Rose debug info
---------------

Блог о моушн-дизайне

Подборка экспрешнов для After Effects

Собрал список выражений для Аfter Effects, которые упрощают мою работу. Совсем простых в стиле loopOut() или wiggle (.4,6) здесь нет, но и ничего слишком сложного тоже.

Своих экспрешнов здесь всего несколько. Большинство я взял из интернета и немного адаптировал под себя. Так что там где уместно, я указал ссылки на авторов.

Динамическая рамка для текста

Плашка, которая автоматически подстраивается под длину текста.

Создайте прямоугольный Shape Layer и сверху отдельным слоем добавьте текст.
Примените экспрешн к параметру Size у шейпа:

margin_width = 60;
margin_height = 40;

text_width = thisComp.layer(index-1).sourceRectAtTime().width;
text_height = thisComp.layer(index-1).sourceRectAtTime().height;

box_width = text_width + margin_width*2;
box_height = text_height + margin_height*2;

[box_width, box_height]

© Kalleheikki Kannisto

Если текст в несколько строк, то добавьте ещё этот экспрешн к Position у шейпа:

x = value[0];
y = content("Rectangle 1").content("Rectangle Path 1").size[1]/2;
[x,y]

Анимируемый wiggle

Простой способ анимировать wiggle с помощью двух слайдеров: первый отвечает за частоту, второй за амплитуду. Лучше анимировать только амплитуду.

Добавьте эффект Slider Control на слой с экспрешном и продублируйте его.
Примените экспрешн к нужному параметру:

w_freq = effect("Slider Control")("Slider");
w_amplitude = effect("Slider Control 2")("Slider");

wiggle(w_freq,w_amplitude)

Цикличный wiggle

Благодаря этому экспрешну, wiggle начинается и заканчивается в одной и той же точке.

Если вдруг цикл не работает, то это скорей всего из-за того, что луп не успевает прийти в изначальное состояние за отведённое время. Просто увеличьте loopTime или freq.

freq = 1;
amp = 65;

startTime = 0; // На какой секунде начинается луп
loopTime = 3; // Сколько секунд идёт

t = (time+startTime) % loopTime;
wiggle1 = wiggle(freq, amp, 1, 0.5, t);
wiggle2 = wiggle(freq, amp, 1, 0.5, t - loopTime);

linear(t, 0, loopTime, wiggle1, wiggle2)

© Dan Ebberts

Прикрепить шейп к одной стороне

Фиксирует одну сторону шейпа на месте, когда вы меняете Size.

Примените к Position у шейпа:

stickTo = "left"; // top, bottom, right or left
chosenShape = content("Rectangle 1").content("Rectangle Path 1");

if (stickTo == "top"){
     x = chosenShape.position[0];
     y = chosenShape.position[1]+chosenShape.size[1]/2;
}

else if (stickTo == "bottom"){
     x = chosenShape.position[0];
     y = chosenShape.position[1]-chosenShape.size[1]/2;
}

else if (stickTo == "right"){
     x = chosenShape.position[0]-chosenShape.size[0]/2
     y = chosenShape.position[1]
}

else if (stickTo == "left"){
     x = chosenShape.position[0]+chosenShape.size[0]/2;
     y = chosenShape.position[1]
}

[x,y]

Риг для катящегося круга и квадрата

Катящийся круг

Примените к Rotation и анимируйте Position:

transform.position[0]-(content("Ellipse 1").content("Ellipse Path 1").size[0]/2)-transform.position[0]/2

Катящийся квадрат

Работает как с шейпами, так и со слоями и композициями.

Примените экспрешн к Position. Добавьте Slider Control на этот же слой. Анимируйте Rotation. Если квадрат катится неправильно, измените значение у Slider Control.

targetLayer = thisLayer;
squareSize = targetLayer.sourceRectAtTime().width;
squareDiag = (Math.sqrt(2)*squareSize)/2/3.5;

try{
	squareOffset = effect("Slider Control")("Slider");
}

catch(err) {
    squareOffset = 0;
}


rot=transform.rotation;
scl=transform.scale[0]/100;
w=(squareSize/2)*scl;
r=(degreesToRadians(rot))*2;
t=transform.position;

[t[0]+w*rot/45,t[1]-(Math.abs((squareDiag+squareOffset)*Math.sin(r)))*scl];

На основе экспрешна от Mikey Borup

Ступенчатые повороты

Альтернатива time*n. Только вместо плавного вращения создаются ступенчатые движения. Отлично подходит для анимации стрелок часов, шестерёнок и других похожих механизмов.

Примените к Rotation:

angle = 15; // Угол поворота в секунду
rotateDuration = 10; // Длительность поворота в кадрах

rotateDurationFr = rotateDuration/(1/thisComp.frameDuration);

wholeSecond = Math.floor(time);
startAngle = wholeSecond * angle;
ease(time, wholeSecond, wholeSecond + rotateDurationFr, startAngle, startAngle + angle)

© Xinlai Ni

Продвинутые ступенчатые повороты

Практически то же самое, что и выше. Но с чуть большим количеством настроек.

Примените к Rotation:

angle = 15; // Угол поворота
rotateDuration = 6; // Длительность поворота в кадрах
timeStop = 5; // Длительность остановки между поворотами
offset = 0; // Сдвиг начального положения в кадрах

fr = timeToFrames(time)+offset;

cycle = timeStop+rotateDuration;
n = Math.floor(fr/cycle);
cur_phase = fr-n*cycle;

if((cur_phase)>timeStop){
angle*n+(cur_phase-timeStop)*angle/rotateDuration;
}
else{
angle*n;
}

© aexpressions.ru

Постоянный масштаб при скейле

Когда вы привязываете один объект к другому и масштабируете родительский, оба слоя увеличиваются. Этот экспрешн не позволяет дочернему слою менять масштаб и только перемещает его по позиции.

Примените к Scale у слоя, который должен сохранять постоянный масштаб:

s = [];
ps = parent.transform.scale.value;
for (i = 0; i < ps.length; i++){
s[i] = value[i]*100/ps[i];
}
s

© JR Canest

Переключатель по чекбоксу

Меняет одно значение параметра на другое по нажатию на чекбокс.

Добавьте эффект Checkbox Control на слой с экспрешном. Примените экспрешн к любому параметру:

if (effect("Checkbox Control")(1) == 0) 0 else 100

Луп для шейпов

Обычный loopOut() не работает с шейпами, но зато работает этот экспрешн.

Примените к Path у шейпа:

try{
pingPong = false; // Поставьте true, если нужен pingPong

timeStart = thisProperty.key(1).time;
duration = thisProperty.key(thisProperty.numKeys).time-timeStart;
quant=Math.floor((time-timeStart)/duration);

if(quant<0) quant = 0

if(quant%2 == 1 && pingPong == true){
t = 2*timeStart+ (quant+1)*duration - time;
}

else{
t = time-quant*duration;
}
}
catch(err){
t = time;
}
thisProperty.valueAtTime(t)

© aexpressions.ru

Range Mapper

Преобразует значения из одного диапазона в другой.

Добавьте Slider Control на слой. Примените экспрешн к нужному параметру:

input = effect("Slider Control")("Slider");

inputLow = 0;
inputHigh = 100;
outputLow = 466;
outputHigh = 618;

linear(input,inputLow,inputHigh,outputLow,outputHigh)

© Dan Ebberts

Обводка независимая от скейла

Сохраняет постоянную обводку у шейпов при изменении масштаба.

Примените к Stroke Width:

value / length(toComp([0,0]), toComp([0.7071,0.7071])) || 0.001;

© Adam Plouff

Счётчики

Подборка из 6 экспрешнов для создания различных счётчиков. По сути, все эти счётчики представляют собой текст, привязанный к Slider Control, который можно анимировать при помощи ключей.

1. Обычный счётчик

Счётчик с фиксированным количеством десятичных знаков.

Добавьте эффект Slider Control к текстовому слою. Примените экспрешн к Source Text. Количество знаков после запятой обозначается параметром toFixed(2).

parseFloat(effect("Slider Control")("Slider")).toFixed(2)

2. Счётчик с запятыми вместо точек

Заменяет точку для десятичных знаков на запятую. Если нужен похожий сетап с большим количеством настроек, то он вот здесь.

Добавьте Slider Control на текстовый слой и примените экспрешн к Source Text.

c = parseFloat(effect("Slider Control")("Slider")).toFixed(2);
c.toString().replace(".", ",")

3. Счётчик с дополнительными знаками

Добавляет любые дополнительные символы в начале или конце счётчика.

Добавьте Slider Control на текстовый слой и примените экспрешн к Source Text.

"+"+parseFloat(effect("Slider Control")("Slider")).toFixed(2)+"%"

4. Счётчик с нулями в начале

Превращает числа из 1 в 001.

Добавьте Slider Control на текстовый слой и примените экспрешн к Source Text.

zerosAmount = 3;

var slider = effect("Slider Control")("Slider");

function padStart(string, targetLength, character) {
	string = (string instanceof String) ? string : string.toString();
	targetLength = targetLength >> 0;
	character = character || ' ';

	while (string.length < targetLength) {
		string = character + string;
	}

return string;
};

if (slider >= 0) {
zeroAmount = zerosAmount + 1;
paddedString = padStart(parseFloat(slider.value).toFixed(0), zerosAmount, '0');
}

else {
paddedString = '-0'+padStart(parseFloat(slider.value).toFixed(0)*-1, zerosAmount, '0');
}

paddedString;

На основе экспрешна от Tomas Sinkunas

5. Счётчик с разрядами

Группирует цифры по разрядам, превращая 30000 в 30 000.

Добавьте Slider Control на текстовый слой и примените экспрешн к Source Text.

num = parseFloat(effect("Slider Control")("Slider")).toFixed(0);
str = isNaN(num) ? "" : (num * 1 + "");
str.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ');

© Tomas Bumbulevičius

6. Счётчик для больших чисел

Счётчик, привязанный к Slider Control, не идёт дальше 1 000 000. Поэтому если нужны большие числа, приходится использовать эффект Angle Control.

Добавьте Angle Control на текстовый слой и примените экспрешн к Source Text.

number = Math.round(effect("Angle Control")("Angle")/360);

n="" + number;
s="";
for(i=0, l=n.length; i<l;  i++){
    if(s && s!="-" && (l-i)%3 ==0)
                s+=" "; 
        s += n[i];
}
s;

© Chunk Motion

Мини-экспрешны

И, под конец, 4 полезных мини-выражения, которые часто пригождаются.

1. Привязка к слою выше или ниже

Это не полноценный экспрешн, а только его часть. Вместо того, чтобы привязывать один слой к другому напрямую, иногда удобнее динамически привязывать к слою, который стоит выше или ниже слоя с экспрешном.

В примере, я привязываю позицию у слоя с шейпом к любому слою, который стоит выше на таймлайне. Если нужна привязка к слою ниже, то используйте index+1.

thisComp.layer(index-1)

2. Постоянно ускоряющиеся повороты

Добавьте это к Rotation, чтобы создать вращение, которое становится быстрее с каждой секундой:

time*time*time*time

3. Ключи для time*n

Добавляет постоянное движение, но оставляет возможность ставить ключи.

value+time*11

© Ben Marriott

4. Привязка градиента к слою

Чтобы Gradient Ramp не слетал при перемещении слоя, добавьте на Start и End:

toComp(value)

© aeexpressions.ru

Это все выражения, которыми я пользуюсь на постоянной основе. Всего получилось 23.
📁 Проект со всеми экспрешнами, который вы можете скачать бесплатно.

Рендер в After Effects

Расскажу самые базовые вещи о рендере в Adobe After Effects. Будет как небольшая подсказка для новичков.

Рендерить можно двумя способами. Через Render Queue внутри After Effects и через стороннюю программу Adobe Media Encoder.

Для слабых компьютеров или тяжёлых проектов советую Render Queue. А для всего остального — Media Encoder.

Две заметки перед началом
1) Если АЕ 2017 года или ниже — скачайте кодеки Quicktime. На macOS не нужно.
2) Если рендерите через Media Encoder проверьте, чтобы он был того же года, что и After Effects.


К настройкам рендера

Рендерим видео с оптимальным соотношением веса и качества через Media Encoder

Сейчас самый распространённый стандарт сжатия видео — H.264. Мало весит, не убивает качество и везде поддерживается.

— Открываем композицию, которую хотим отрендерить.
— Заходим в Composition → Add to Adobe Media Encoder Queue. Немного ждём, открывается Media Encoder.
— Нажимаем на стрелочку в Format и выбираем H.264.

Media Encoder Format H.264

— В Preset выбираем Match Source High Bitrate.

Preset Match Source High Bitrate

— Output File выбираем куда сохранить. Нажимаем Enter или на зелёный треугольничек справа. Рендер пошёл.

В итоге, минутное видео больше не будет весит несколько гигабайт, а останется где-то в пределах сотни мегабайт.

Рендерим видео с оптимальным соотношением веса и качества через Render Queue

— Открываем композицию, которую хотим отрендерить.
— Заходим в Composition → Add to Render Queue.
— Нажимаем на синий текст рядом с Output Module.

After Effects Render Queue Output Module

— В Format выбираем Quicktime.

After Effects Render Queue Format

— Нажимаем Format Options.
— В Video Codec выбираем H.264.

After Effects Render Queue H.264
Если АЕ 2018 или старше, то H.264 в списке не будет. Выбирайте Animation.
Файл получится тяжеловатый, но легче, чем совсем без сжатия. Поэтому для последних версий АЕ лучше использовать Media Encoder, где есть H.264.

— Кликаем ОК в двух окошках.
— Справа от Output To нажимаем на синий текст и выбираем куда сохранить.

After Effects Render Queue Output

— Нажимаем Enter или кнопку «Render» справа.
Готово! Рендер начался.

Рендерим видео на альфа-канале через Media Encoder

А сейчас рассмотрим как отрендерить анимацию с прозрачным фоном. Это уже чуть-чуть посложнее.

— Открываем нужную композицию.
— Composition → Add To Adobe Media Encoder Queue
— В Format выбираем Quicktime

Media Encoder Format Quicktime

— В Preset ничего не выбираем, просто нажимаем на синий текст

Media Encoder Preset

— Теперь выбираем Video Codec в зависимости от версии AE:
AE 2017 и ниже — PNG.

Media Encoder QuickTime PNG

АЕ 2018 — Animation.

Media Encoder QuickTime Animation

AE 2019 или любая версия на macOS — ProRes 4444.

ProRes 4444 Media Encoder

— Нажимаем кнопку Match Source.
— Проматываем чуть-чуть вниз, в Depth выбираем параметр у которого написано +alpha или 32 bit.

Media Encoder Alpha Depth

— Нажимаем ОК, в Output выбираем место куда сохранится файл и запускаем рендер.

Всё, теперь ролик отрендерится с прозрачностью, будет потяжелее. Зато на фон можно подставить всё, что угодно.

Рендерим видео на альфа-канале через Render Queue

— Открываем нужную композицию.
— Composition → Add To Adobe Media Encoder Queue
— Кликаем на синий текст рядом с Output Module.

— В Format выбираем Quicktime.

After Effects Render Queue Format Quicktime

— Нажимаем «Format Options».

— Теперь выбираем Video Codec в зависимости от версии AE:
AE 2017 и ниже — PNG.

After Effects Render Queue Alpha PNG

АЕ 2018 — Animation.

After Effects Render Queue Alpha Animation

AE 2019 или любая версия на macOS — ProRes 4444.

After Effects Render Queue Alpha ProRes

— Нажимаем ОК.
— В Channels выбираем RGB+Alpha.

After Effects Render Queue RGB Alpha

— Нажимаем ОК.
— В Output To выбираем куда сохранить файл.

After Effects Render Queue Output

— Нажимаем Enter или кнопку «Render».
Есть!

Создаём шаблоны для рендера в Media Encoder

Как в Media Encoder, так и в Render Queue можно создавать шаблоны на все случаи жизни: для H.264, альфа-канала, MP3, PNG-секвенций. Один раз настраиваете рендер, сохраняете в темплейт и в нужный момент переключаетесь между ними.

— Чтобы сохранить шаблон достаточно настроить рендер под себя и нажать на эту кнопку

Save Preset Adobe Media Encoder

— После этого, созданный темплейт будет доступен в выборе пресетов

Custom Template Adobe Media Encoder

Создаём шаблоны для рендера в Render Queue

— Настраиваем рендер, нажимаем справа от Output Module на стрелочку и выбираем Make Template

Make template After Effects Render Queue

— Задаём имя шаблону — готово, можно рендерить

Custom Template Render Queue

— Чтобы сделать шаблон рендером по умолчанию просто выбираем его в Movie Default

Movie Default After Effects Template

Рендерим один кадр из видео

Сохранить текущий кадр можно двумя способами. Одной кнопкой в плагине FX Console.

FX Console Interface

Или штатными средствами After Effects. Единственное, по умолчанию картинка сохраняется в PSD, но это быстро исправить.

— Создаём любую композицию
— Нажимаем Composition → Add To Render Queue
— Справа от Output Module нажимаем на маленькую стрелочку и выбираем Make Template

Make template After Effects Render Queue

— В появившемся меню нажимаем Edit

Edit Template Render Queue

— Format ставим PNG Sequence
— Channels — RGB + Alpha
— Нажимаем ОК

Format PNG Sequence Render Queue

— Переименовываем шаблон

Settings Name Render Template

— Ставим его во Frame Default. Нажимаем ОК

Frame Default Render Queue

— Возвращаемся обратно в нашу композицию
— Выбираем Composition → Save Frame As → File и сохраняем кадр куда нужно. Если будет прозрачность, сохранит с прозрачностью.

Same Frame As After Effects

Теперь в любом проекте можно нажать Save Frame As или Ctrl+Alt+S и кадр сохранится. Настраивать темплейт снова больше не нужно.

Думаю на этом всё.
Надеюсь, что эта заметка поможет кому-нибудь с рендером. Если что-то непонятно — пишите в комментарии, разберёмся.

Разберёмся с кадрами в секунду

В этой заметке расскажу откуда появились 24 кадра в секунду, почему в США их 29,97. Зачем играм так много FPS и почему 25 кадр не работает.

Вступление

Любая анимация существует благодаря инертности зрения. Если изображения сменяются достаточно быстро, то мозг не видит их по отдельности, а создаёт иллюзию непрерывного движения. Скорость смены изображений должна быть выше 10-12 в секунду, иначе мозг воспринимает картинки по-отдельности. Казалось бы, вот и подходящая для человека кадровая частота — 12 FPS и больше. Но не всё так просто.

Немые фильмы

Представьте себе ленту немого фильма, в которой 1 500 отдельных изображений. Если мы покажем фильм со скоростью 12 кадров в секунду, то увидим что-то такое. Гифку сделал по ссылке, чтобы не раздражала мерцанием.

Движение есть, но мерцание в кадре всё портит. Оно появилось из-за того, что мы должны закрыть проектор, чтобы прокрутить ленту дальше и показать новое изображение. По словам Томаса Эдисона, наше зрение не заметит мерцание, если мы будем прокручивать ленту со скоростью 46 кадров в секунду. Но это не лучший вариант, и вот почему.

Сейчас у нас фильм состоит из 1 500 изображений и мы его проигрываем со скоростью 12 кадров в секунду.
Получается 1 500 кадров / 12 кадров в секунду = 125 секунд
Значит, нам достаточно 1 500 кадров, что создать двухминутный фильм.

Со скоростью 46 кадров в секунду наш фильм будет идти всего 32 секунды. То есть, чтобы восстановить хронометраж мы должны создать не 1 500 кадров, а 5 750 = 125 секунд * 46 кадров в секунду. Кинолента будет длиннее в четыре раза, количество кадров больше, а значит отснять, смонтировать и показать фильм выйдет намного дороже.

Легче изменить конструкцию проектора. Поэтому вместо обычного обтюратора поставили трёхлезвийный.

Теперь один кадр показывают три раза и только потом сменяют на новый. Получается частота кадров (хоть и одинаковых) увеличилась. Количество мерцания увеличилось по количеству, но в три раза сократилось по времени. Таким образом инертность зрения стала «съедать» мерцание в кадре.

Мы сменяем кадры со скоростью 16 FPS, но зрителям показываем один и тот же кадр три раза.
И получаем 48 спроецированных кадра в секунду = 16 кадров * 3 повторения. Прямо как и хотел Эдисон, даже лучше.

Мы взяли 16 FPS, а не 12 или 14, так как 16 — минимальное целое число, которое умножается на 3 и в результате даёт число больше 46.

Вот мы и получили первую кадровую частоту — 16 FPS для немых фильмов. Плюс немых фильмов в том, что мы можем легко увеличить или уменьшить количество кадров в секунду, это повлияет только на скорость воспроизведения. Ручку проектора крутил человек и мог варьировать скорость кадров от 14 до 26 FPS.

Звук

Всё сложнее стало со звуком. Теперь нельзя крутить фильм быстрее или медленнее. Нужно соблюдать постоянную кадровую частоту, чтобы скорость, а значит и тембр голоса не изменялся на протяжении фильма. С 16 FPS была проблема, звук не звучал точно, как задумывалось. Нужно было выбрать новую частоту, чтобы она была больше 16 и в итоге давала 48 проецируемых FPS. В итоге, вместо трёхлезвийного обтюратора стали использовать двулезвийный. И утвердили новый фрейм рейт — 24 FPS.

24 кадра * 2 повторения = 48 проецируемых кадров в секунду. Всё просто и удобно. 24 нацело делится на 2, 3 и 4. То есть мы знаем, что половина секунды — 12 FPS, треть — 8, а четверть — 6.

Тут вроде становится понятно — мы и сейчас используем 24 FPS. Тогда зачем нам 25, 30 и тем более 29,97?

Телевизор

Когда решили транслировать изображение по телевизору возникли новые проблемы. Показывать два раза один и тот же кадр было не вариант, да и технически это было сложновато. Ещё надо передать аналоговый сигнал по радиоволнам. И чем больше кадров, тем больше вес файла — значит канал передачи должен быть шире, а значит и дороже. Поэтому стали передавать кадры по половинкам — полукадрами. Разбиваем изображение на полосы и показываем сначала все нечётные, а потом все чётные. Инертность зрения делает своё дело и мы видим целый кадр.

Кадр из людей в чёрном 3

В телевизоре происходит то же самое, только намного быстрее.

По-умному, это называется чересстрочная развёртка и обозначается буквой «i», от слова «interlaced». Ролик с чересстрочной развёрткой и разрешением 1920 × 1080 будет называтся 1080i. А такой же ролик с прогрессивной развёрткой — 1080p. Это означает «progressive» или то, что кадры передаются целиком.

Чтобы не было лишних шумов и конструкция телевизора была проще, полукадры решили обновлять с частотой электросети. Для Европы это 50 Гц. Получилось 50 полукадров в секунду или 25 целых кадров в секунду. В США частота электросетей 60 Гц, значит полукадров будет 60, а кадров соответственно 30.

И вот вроде как всё хорошо, но тут появляется цвет.

Цвет

Теперь через тот же канал нужно донести больше информации. Мы должны передать чёрно-белое изображение для старых телевизоров, цветное изображение и звук. И сделать это было довольно сложно. Потому что как только мы добавляем в электромагнитный спектр информацию о цвете его частота пересекается со звуком и создаёт помехи. Чтобы чётко разделить цвет и звук решили снизить частоту полукадров на 0,1%.

60 полукадров — 0,1% = 59,94 полукадров в секунду
59,94 полукадров в секунду/2 = 29,97 кадров в секунду

Система вещания с такой странной кадровой частотой называется NTSC и использовалась в США и ещё парочке стран.

В Европе таких сложностей не было, в качестве стандарта сразу взяли PAL, который был создан, чтобы решить проблемы с цветом. Поэтому как было 25 кадров в секунду, так и осталось.

>30 FPS

Зачем же тогда делают фильмы в 60 FPS?
Дело в том, что камера размывает любое резкое движение в сторону направления объекта. Величина размытия зависит от расстояния, которое объект прошёл за 1 кадр. И чем больше количество кадров в секунду, тем меньше размытие.

1 секунда / 25 фпс = 0,04
1 секунда / 60 фпс = 0,016

Это называется моушн-блюр.

Разница между фильмами с 25 FPS и 60 FPS только в плавности движения. Резкие движения в фильме выглядят менее размытыми. За счёт этого картинка кажется более реалистичной. Вот в этом и смысл.

25 кадр

Представьте, что мы берём книгу в которой 24 страницы — 23 белые и 1 красная. Если мы пролистнём книгу за одну секунду, то точно заметим, что одна страница другого цвета. Если страниц в книге 25, то ничего не изменится. Страница не станет невидимой и тем более не будет влиять на подсознание, она просто пролистнётся не за 1/24 секунды, а за 1/25. Вот и вся разница. Даже если страниц будет больше 100 — глаз поймёт, что одна из них отличается. Абсолютно то же самое с видео.

Наше зрение не ограничивается считыванием какого-то определённого количества кадров в секунду. Различия между кадрами будут заметны и на двухстах, и на пятистах кадрах в секунду.

Слоумоушн и таймлапс

Слоумоушн это, когда мы снимаем видео с большей частотой кадров, а смотрим с меньшей — снимаем в 120, смотрим в 25.

Снимем на айфон 6 секунд в 120 FPS. Это значит, что за секунду он создаст 120 изображений. За 6 секунд — 720. А смотреть мы их будем в 25 FPS. Это значит, что 720 изображений / 25 FPS мы будем смотреть почти 29 секунд. За это время мы и рассмотрим все детали.

А если мы возьмём высокоскоростную камеру, снимем 1 секунду с фреймрейтом 5 000 FPS и посмотрим в 25 FPS.

5 000 * 1 / 25 = 200 секунд или 3 минуты 20 секунд

Одну секунду реального времени мы смотрим целых 3 минуты. Можно в деталях рассмотреть выстрел пистолета под водой.

После таких расчётов становится понятно почему Slow Mo Guys не выкладывают свои ролики в 60 FPS. Мы просто увидим меньше деталей.

5 000 * 1 / 60 = 83 секунды или 1 минута 22 секунды

Также, есть противоположность для слоумоушна — timelapse. Снимаем видео с меньшей частотой, а проигрываем с большей. Ставим штатив на балкон и делаем одну фотографию в день на протяжении года. Получается, что у нас получилось видео с частотой кадров — 1 кадр в день. За год у нас получилось 365 кадров. Теперь мы включаем скорость 25 FPS. В итоге, получаем 365 / 25 = 14,6 секунд в которые уместился целый год.

Игры

Почему тогда играм недостаточно 25 FPS? А нужно намного больше: 60 или даже 100 FPS.

Как написано в абзаце про фильмы с 60 FPS — камера всегда снимает с небольшим размытием в движении. Компьютер же создаёт абсолютно чёткие изображения. Из-за этого мозгу сложнее складывать их в непрерывную картинку. И чем больше движения в игре, тем больше чётких кадров нам нужно для корректного восприятия.

Для сапёра нам хватит и 2 FPS. Два раза в секунду компьютер будет обновлять изображение на мониторе и показывать попали мы в бомбу или нет. А для Counter-Strike не хватит и 30. Просто потому, что движения там слишком динамичные.

Конечно, игры научились включать искуственное размытие, но оно похоже только мешает игровому процессу. По крайней мере, я не знаю ни одного человека, который включает моушн-блюр в играх. Да и система лишний раз нагружается.

На восприятие также влияет то, что фильмы мы смотрим с постоянной кадровой частотой. В играх же, в зависимости от происходящего, FPS меняется. Как только FPS резко падает, мозг сразу же замечает это. То же самое было бы и с фильмами, если бы кадров в секунду было то 25, то 60.

FPS для игр важен не только для комфортного восприятия игры. Частота кадров равна частоте обновления физической модели. Это значит, чем больше FPS, тем чаще компьютер проверяет сделали вы выстрел или нет. Иногда эти доли секунды важны.

Похоже, что всё, что хотел рассказать — рассказал. Вот кратко все тезисы этой заметки.

Итоги

1) Первый фрейм рейт — 16 FPS
2) Звук увеличил кадровую частоту и сделал её постоянной — 24 FPS
3) Частота электросети определила новую кадровую частоту для телевизоров — 25 FPS и 30 FPS
4) Цвет превратил 30 FPS в 29,97 FPS из-за того, что не дружил со звуком
5) Фильмы в 60 FPS плавнее
6) Слоумоушн — снимаем с бóльшим FPS, смотрим с меньшим. В таймлапсе наоборот
7) Игры генерируют абсолютно чёткие кадры, поэтому нужно больше FPS, чтобы создать плавное движение
8) В фильмах кадры в секунду постоянные, в играх зависят от ситуации

Источники

The History of Frame Rate for Film
Why is TV 29.97 frames per second?
Почему нам мало 30 fps?
Why aren’t Slow Mo Guys videos 60fps?