Главная » Шпаргалки » Expressions в DaVinci Resolve: полный список с примерами

Войти
Шпаргалка 19 авг 10:58

Expressions в DaVinci Resolve: полный список с примерами

Expressions на Fusion-странице DaVinci Resolve открывают то, что не выразить одними ключевыми кадрами. Здесь собраны формулы, которые реально пригождаются в работе, — проверенные на практике, а не придуманные для примера. Список не претендует на полноту: это рабочий документ, к которому я сам постоянно возвращаюсь и дополняю.

Проверять expression удобнее всего на узле Text+: вставь его в поле Styled Text — и сразу увидишь результат в читаемом виде, дальше останется только подстроить формулу под задачу.

Ещё момент: сначала пропиши expression, и только потом переименовывай узел. Сделаешь наоборот — ссылка внутри формулы не обновится сама.

Два дефиса -- в конце строки отсекают всё, что после них: например, GetPrefs("Comp.FrameFormat.Rate") -- Returns TL FPS. Удобный способ оставить себе комментарий прямо внутри expression.

Как читать эту шпаргалку

Если ты раньше не касался expressions вообще — вот минимум, без которого дальше половина формул будет выглядеть как заклинание.

Expression — формула вместо ручного значения. У любого параметра (Angle, Width, Center — не важно) справа есть маленький значок или пункт в правом клике «Expression» — нажимаешь, и вместо ползунка появляется текстовое поле. Начиная с этого момента значение параметра на каждом кадре не задаётся руками, а вычисляется по формуле заново.

time — «номер текущего кадра», и это буквально счётчик: на кадре 0 он равен 0, на кадре 24 — равен 24, на кадре 100 — 100. Он растёт сам собой, пока играет таймлайн, без единого keyframe. Вся анимация без keyframes в этой шпаргалке построена на одном и том же трюке: если параметр зависит от time, он меняется каждый кадр автоматически.

Например, expression time в параметре Angle узла Transform означает «угол поворота равен номеру кадра». На кадре 0 угол 0°, на кадре 90 — угол 90°, на кадре 360 — объект вернулся туда же, откуда начал (360° — это полный круг). Число всё время растёт — значит, объект крутится без остановки. В Fusion рост угла в плюс вращает объект против часовой стрелки, поэтому -time (тот же приём, только со знаком минус) крутит его по часовой.

comp.RenderEnd — общая длина композиции в кадрах. Если поделить time на comp.RenderEnd, получится дробь, которая растёт от 0 в начале до 1 в самом конце, — прогресс всей композиции. Это самый частый строительный блок ниже: почти любая анимация «от 0 до 100%» или «уложиться ровно в длину ролика» начинается именно с этого отношения.

Ссылка на другой узел пишется как ИмяУзла.Параметр, например Rectangle1.Width — так можно забрать значение одного параметра и подставить в формулу другого, вообще не трогая keyframes.

И последнее: часть формул ниже начинается с двоеточия : — это значит, что внутри не одна короткая формула, а кусок настоящего кода на Lua (переменные, условия, функции). Точка с запятой разделяет команды внутри такого блока — как в обычном программировании.

Базовые

time

Номер текущего кадра — растёт на 1 каждый кадр сам, без твоего участия. Подставь в Angle — получишь бесконечное вращение против часовой стрелки: угол каждый кадр увеличивается на 1°.

time-1 (time-n)

То же самое значение, что было n кадров назад: time-1 — прошлый кадр, time-10 — на 10 кадров раньше текущего. Пригождается, когда нужно сравнить состояние сейчас с состоянием чуть раньше — например, посчитать, на сколько что-то сдвинулось за кадр.

-time

Тот же time, только со знаком минус — угол уменьшается с каждым кадром, поэтому вращение идёт по часовой стрелке, в обратную сторону от обычного time.

ceil()

Округляет дробное число вверх, до ближайшего целого: и 2.1, и 2.9 одинаково станут 3. Пригождается, когда важно получить целое число, а формула внутри выдаёт дробь.

math.ceil()

То же самое действие, только в записи для Lua-блоков: если строка начинается с :, пиши math.ceil(), а не просто ceil().

floor()

Округляет вниз, до ближайшего целого: и 2.1, и 2.9 станут 2.

math.floor()

floor() в Lua-варианте — для формул, начинающихся с :.

abs

Убирает знак минус: -5 и 5 после abs одинаково дают 5. Полезно, когда важна только величина, а не направление — например, расстояние всегда положительное.

time/600

Делит номер кадра на 600 — получается медленно растущее число. Чем больше делитель, тем медленнее меняется результат: удобный способ «притормозить» анимацию, не трогая keyframes.

time*600

Обратный приём: умножает номер кадра, значение растёт быстрее. Чем больше множитель, тем быстрее анимация.

sin(time)

Синус от номера кадра — плавно и без остановок колеблется между -1 и 1, туда-обратно. Хорошая основа для покачивания, мигания или «дыхания» объекта.

ceil(sin(time))

То же колебание, но округлённое вверх — вместо плавного перехода получается резкий скачок между 0 и 1 каждые два кадра. Годится как переключатель вкл/выкл.

floor(sin(time))

То же самое, но округление вниз — скачок между -1 и 0.

comp.RenderEnd

Сколько всего кадров в композиции. Используется как «знаменатель» почти во всех формулах на прогресс ниже.

comp.RenderEnd/2

Номер кадра ровно посередине композиции — например, чтобы что-то произошло точно «на середине ролика».

(1-(time/comp.RenderEnd)*2)

Прогресс от 0 до 1, который укладывается только в первую половину композиции — во второй половине формула уже не «работает на анимацию». Удобно, если действие должно успеть закончиться независимо от общей длины ролика.

(comp.RenderEnd-comp.RenderStart)

Тоже общее число кадров в композиции, только через разницу конца и начала — на случай, если начало не с нулевого кадра.

time/comp.RenderEnd

Главная формула прогресса во всей этой шпаргалке: 0 в начале композиции, 1 в конце. Практически любая формула «подстроиться под длину таймлайна» начинается именно с этого отношения.

1-(time/comp.RenderEnd)

Тот же прогресс, только задом наперёд: 1 в начале, 0 в конце.

(time*360)/fps

Ровно один оборот в секунду в параметре Angle: 360° делится на fps (число кадров в секунду) и умножается на time — за одну секунду угол успевает пройти полный круг. Вместо fps подставь своё число.

(time*360)/(fps*2)

То же самое, но оборот растягивается на 2 секунды — вдвое медленнее.

360/copies

На узле Duplicate делит полный круг (360°) на количество копий — так копии расставляются по кругу равномерно, без ручного подбора угла для каждой.

ceil(time/fps)

Секундомер, считающий вверх: 1, 2, 3… — растёт на единицу раз в секунду, а не каждый кадр.

ceil((time)/comp:GetPrefs("Comp.FrameFormat.Rate"))

Тот же секундомер, но fps подставляется автоматически из настроек композиции — не нужно вписывать число руками и следить, чтобы оно совпадало с реальным.

ceil((comp.RenderEnd-time)/fps)

Обратный секундомер: считает не вверх, а вниз, до конца композиции.

ceil((comp.RenderEnd-time)/comp:GetPrefs("Comp.FrameFormat.Rate"))

Тот же обратный отсчёт, но с автоматическим fps.

max(floor(30-(time/fps)),0)

Отсчёт целыми секундами от 30 до 0, который останавливается на нуле и не уходит в минус — за это как раз отвечает max(...,0).

ceil(time/comp.RenderEnd*100)

Процент прохождения композиции: 0 в начале, 100 в конце.

ceil(time/comp.RenderEnd*100) .. "%"

То же самое, но со знаком % на конце строки. В Lua строки склеиваются двумя точками .., и текст всегда берётся в кавычки.

ceil((1-time/comp.RenderEnd)*100)

Процент, который остался до конца композиции, — обратный отсчёт в процентах.

ceil((1-time/comp.RenderEnd)*100) .. "%"

То же самое, с приклеенным %.

math.floor(PolylineStroke1.WriteOnEnd*100).."%"

Забирает значение прогресса у эффекта Wipe On (обводка, которая постепенно «дорисовывается») и превращает в проценты с подписью — удобно вывести рядом текстом.

math.floor(Circle1.Radius*100)

Счётчик, растущий вместе с радиусом узла Circle: если радиус анимирован ключами, число будет расти синхронно с ним.

math.floor(Rectangle1.Width*50).."%"

Проценты, завязанные на ширину маски Rectangle — например, подпись «заполнено на N%» рядом с прогресс-баром на основе маски.

Случайность и условия

:randomseed(floor(time/6)) ; return random()

Случайное число от 0 до 1, которое меняется не каждый кадр, а раз в 6 кадров: floor(time/6) держит одно и то же «семя» случайности 6 кадров подряд, поэтому значение дёргается ступеньками, а не мельтешит.

iif(time >= 0 and time <=30, (random(0,20)), 20)

С 0 по 30 кадр — случайное число от 0 до 20, дёргающееся каждый кадр, а после 30 кадра значение застывает на 20. iif(условие, если_да, если_нет) — это и есть «если-то-иначе» в одну строку, самая частая конструкция в expressions.

iif(time<10, 5, iif(time >= 0 and time <=30, (random(0,20)), 20))

Тот же трюк, но с задержкой перед стартом: до 10 кадра держит фиксированное значение 5, а с 10 по 30 кадр включается случайность из формулы выше и застывает на 20.

:if time < 10 then return 0; else return 90; end

Развёрнутая запись «если-то-иначе» на Lua, словами if/then/else/end — работает только если строка начинается с двоеточия. Короче то же самое пишется как iif(time<10,0,90).

:freq = 0.1;amplitude = 3.5; decay = 0.1; y = amplitude*math.cos(freq*time*2*math.pi)/math.exp(decay*time); function hello() x = time*0.02;return x; end; return (y + hello());

Затухающее колебание: сначала раскачивается заметно, потом амплитуда сама уменьшается со временем — как маятник, который постепенно останавливается. freq отвечает за частоту колебаний, amplitude — за размах, decay — за скорость затухания. Есть смысл вынести все три в CustomTool ползунками, чтобы настраивать на глаз, а не переписывать формулу.

Прогресс и загрузка

"Progress: " .. ceil(time/comp.RenderEnd*100) .. "%"

Готовая подпись «Progress: 42%», которая растёт сама вместе с проигрыванием — просто подставь в Styled Text узла Text+.

ceil((1-time/comp.RenderEnd)*100) .. "%"

Тот же процент, только тающий: со 100% к 0%.

"Progress: " .. ceil((1-time/comp.RenderEnd)*100) .. "%"

То же самое, но с подписью «Progress:» впереди тающего процента.

"Loading " .. ceil(time/24) .. "/" .. ceil(comp.RenderEnd/fps)

Имитация загрузки в духе «Loading 3/12», где числа считаются в секундах. Замени 24 в первой части на свой fps, если он отличается.

Работа с текстом

((Text1.Output.DataWindow[4]-Text1.Output.DataWindow[2])/Text1.Output.Height)

DataWindow — это область, которую текст реально занимает в кадре, а не размер текстового блока. Формула вычисляет её высоту в пикселях — пригождается, если нужно, например, подстроить фон точно под размер надписи.

((Text1.Output.DataWindow[3]-Text1.Output.DataWindow[1])/Text1.Output.Width)

То же самое, но ширина занятой текстом области. Индексы DataWindow идут по границам: [1] — левый край, [2] — верхний, [3] — правый, [4] — нижний.

Text1.StyledText.Value или Text1.StyledText[0]

Достаёт сам текст, набранный в узле Text+, как строку — чтобы использовать его в других формулах: посчитать длину, склеить с другим текстом и так далее.

Text1.StyledText.Value .. Text2.StyledText.Value

Склеивает текст из двух узлов Text+ в один. .. — оператор склейки строк в Lua.

string.len(Text1.StyledText.Value)

Считает, сколько всего символов в тексте — включая пробелы и знаки препинания.

:_, mylines = string.gsub(Text1.StyledText.Value, "\n", ""); return mylines

Считает количество строк — ищет символы переноса строки и считает, сколько раз функция их нашла и заменила.

:_, myspaces = string.gsub(Text1.StyledText.Value, "%s", ""); return myspaces

Считает количество пробелов в тексте — буквально, а не что-то ещё, несмотря на похожее название переменной в оригинале этого рецепта.

:_, myletters = string.gsub(Text1.StyledText.Value, "%a", ""); return myletters

Считает буквы, без пробелов и цифр.

:_, mylower = string.gsub(Text1.StyledText.Value, "%l", ""); return mylower

Считает символы в нижнем регистре — сюда же попадают и цифры.

:_, myupper = string.gsub(Text1.StyledText.Value, "%u", ""); return myupper

Считает символы в ВЕРХНЕМ регистре.

:_, alphanumeric = string.gsub(Text1.StyledText.Value, "%w", ""); return alphanumeric

Считает буквы и цифры вместе, без пробелов и знаков препинания.

:_, myvow = string.gsub(Text1.StyledText.Value, "[AEIOUaeiou]", ""); return myvow

Считает гласные буквы (латиница — AEIOU).

:_, novow = string.gsub(Text1.StyledText.Value, "[^AEIOUaeiou]", ""); return novow

Считает всё, кроме гласных: согласные, пробелы, цифры и знаки — «наоборот» от предыдущей формулы.

:_, mydigits = string.gsub(Text1.StyledText.Value, "%d", ""); return mydigits

Считает цифры.

:_, punctuation = string.gsub(Text1.StyledText.Value, "%p", ""); return punctuation

Считает знаки препинания: точки, запятые и похожее.

:_, controlchar = string.gsub(Text1.StyledText.Value, "%c", ""); return controlchar

Считает управляющие символы — они не отображаются на экране (перенос строки, табуляция), но формально тоже часть текста.

:_, myhex = string.gsub(Text1.StyledText.Value, "%x", ""); return myhex

Считает символы, которые годятся в шестнадцатеричной записи — цифры 0-9 и буквы A-F. На глаз их легко перепутать с пробелами, отсюда и оговорка в оригинальном рецепте.

:_, myletters = string.gsub(Text1.StyledText.Value, "%A", ""); return myletters

Считает всё, что НЕ буквы, — цифры, пробелы и знаки препинания вместе.

[^AEIOUaeiou]

Общее правило для всех формул выше: если сделать заглавной букву класса после % (например, %a → %A), результат переключается на противоположный — «буквы» превращаются в «не буквы». То же самое делает знак ^ перед классом символов в квадратных скобках: «всё, кроме перечисленного».

Эффект «печатной машинки» — Write On

min(time/(comp.RenderEnd/2),1)-(Text1.Delay)

Резко останавливает перемешивание букв (scramble, когда буквы «трясутся» и постепенно складываются в слово) ровно на середине композиции — вторая половина уже показывает читаемый текст без изменений. Delay — ползунок 0–0.25, добавляющий паузу перед стартом эффекта. Чтобы буквы, наоборот, распадались из слова в кашу, повесь на композицию TimeSpeed со скоростью -1 — время пойдёт в обратную сторону.

1-(time/comp.RenderEnd)

Та же логика перемешивания, но в обратном направлении: от каши к читаемому слову.

time/(comp.RenderEnd/fps)

Классический эффект «печатной машинки»: один символ текста проявляется за каждый кадр.

time/(comp.RenderEnd/fps)*2

То же самое, только скорость печати вдвое выше — два символа за кадр.

time/(comp.RenderEnd/comp:GetPrefs("Comp.FrameFormat.Rate"))/2

Половинная скорость печати, с автоматическим fps — не нужно заранее знать частоту кадров. На «неровных» значениях вроде 23.976 буквы иногда проявляются между кадрами, поэтому стоит проверить результат глазами.

time/(comp.RenderEnd/comp:GetPrefs("Comp.FrameFormat.Rate"))/(Text1.WriteOn)

Та же печать, но скорость крутит ползунок WriteOn (целое число, шаг 2) — можно менять темп прямо в инспекторе, не трогая формулу.

Маски

floor(-1*((Rectangle1.Height))/2) или floor(-Rectangle1.Height)/2

Координата нижнего края маски Rectangle — половина высоты со знаком минус.

floor((Rectangle1.Height)/2)

Координата верхнего края той же маски. По аналогии Width вместо Height должен давать боковые границы — автор рецепта сам ещё не проверял.

Point(Rectangle1.Center.Y-(Rectangle1.Width/2)+(Rectangle1.Width/2))

Ставит точку ровно на внутренний левый край маски — удобно, чтобы «пришить» другой объект точно к границе.

Point(Rectangle1.Center.Y-(Rectangle1.Width/2)-(Rectangle1.Width/2))

То же самое, но точка ставится на внешней стороне левого края — за пределами маски.

Point(Rectangle1.Center.X, (Rectangle1.Center.Y+(Rectangle1.Height/2)))

Верхняя точка прямоугольной маски — центр плюс половина высоты.

Point(Rectangle1.Center.X, (Rectangle1.Center.Y-(Rectangle1.Height/2)))

Нижняя точка прямоугольной маски.

Point(Rectangle1.Center.X+(Rectangle1.Width/2))

Правая точка прямоугольной маски.

Point(Rectangle1.Center.X-(Rectangle1.Width/2))

Левая точка прямоугольной маски.

math.floor(((Transform1.XSize*100)-100)+100).."%"

Процент «до пустоты»: чем уже становится маска по ширине (Transform1.XSize), тем меньше число — удобно для подписи вроде «осталось N%».

math.floor((100-Transform1.XSize*100)).."%"

Процент «до заполнения» — растёт по мере того, как маска расширяется. Обратный вариант предыдущей формулы.

Точки для масок удобнее не считать вручную, а собрать через null-объект и трансформацию — так же надёжно, но без риска ошибиться в формуле.

Дата и системные функции

Text1.StyledText = os.date('%x')

Подставляет в текст текущую дату компьютера, на котором открыт проект. Что именно выводится, регулируется кодом после % — таблица ниже.

Код Что выводит
%a сокращённый день недели (Wed)
%A полный день недели (Wednesday)
%b сокращённый месяц (Sep)
%B полный месяц (September)
%c дата и время (09/16/98 23:48:10)
%d число месяца, 01–31 (16)
%H час, 24-часовой формат, 00–23 (23)
%I час, 12-часовой формат, 01–12 (11)
%M минуты, 00–59 (48)
%m месяц, 01–12 (09)
%p «am» или «pm»
%S секунды, 00–61 (10)
%w день недели, 0–6, где 0 — воскресенье (3)
%x дата (09/16/98)
%X время (23:48:10)
%Y год полностью (1998)
%y год двумя цифрами (98)
%% символ % как есть

Запуск файлов и веб-страниц из кнопки

Одна строка кода умеет открывать браузер с локальным html-файлом или веб-страницей прямо по нажатию кнопки на узле — например, кнопка на узле открывает документацию проекта или галерею отрендеренных кадров. Windows и Mac запускают внешние программы по-разному (start и open), поэтому под каждую систему — своя строка.

os.execute ("start ../galleries/gallery.html" )

Открывает локальный html-файл в браузере по умолчанию — Windows.

os.execute ("open ../galleries/gallery.html" )

То же самое для Mac.

os.execute('start "" "https://example.com/"')

Открывает веб-страницу — Windows.

os.execute('open "" "https://example.com/"')

Открывает веб-страницу — Mac.

А так эта команда превращается в настоящую кнопку прямо на узле — код добавляется в текстовый редактор скрипта узла (Edit Controls → Script), строкой ниже ViewInfo = OperatorInfo { Pos = { 0, 82.5 } },:

UserControls = ordered() {
    ScriptButton = {
        LINKS_Name = "ScriptButton",
        LINKID_DataType = "Number",
        INPID_InputControl = "ButtonControl",
        INP_Integer = false,
        BTNCS_Execute = [[
        os.execute('open "" "https://example.com"')
        os.execute('start "" "https://example.com"')
        ]],
        ICS_ControlPage = "Controls"
    }
}

Ссылка на значение другого узла

Transform1:Angle

Забирает текущее значение угла у узла Transform1 и подставляет его сюда. Общий вид записи — ИмяУзла:Параметр — так можно сослаться на любое свойство любого другого узла в композиции, не только на Angle.

Значение в конкретный момент времени

Rectangle1:GetValue("Width", 10)

Ширина узла Rectangle1 не сейчас, а именно на 10-м кадре — застывший «снимок» значения на конкретный момент, даже если сам параметр анимирован и меняется.

Rectangle1.Width

А это — просто текущее, «живое» значение ширины на каждом кадре, без привязки к конкретному моменту.

Merge1:GetValue("Center", time-1).X

Координата X точки Center с прошлого кадра — пригождается, чтобы сравнить, куда объект сдвинулся за один кадр, например для расчёта скорости.

self:GetValue(....)

Тот же приём, но для параметра этого же узла — self означает «у самого себя», а не у соседнего узла.

Значение с предыдущего узла в цепочке

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

self:GetSourceTool("[connected input]"):GetValue("[source parameter]", [source time])

Читает значение параметра не у себя, а у узла, который подключён на вход текущего. [connected input] — это имя именно входа (например, EffectMask), а не имя узла. [source time] — на каком кадре смотреть это значение: можно взять фиксированный кадр (0), а можно завязать на time, чтобы значение менялось вместе с проигрыванием.

self:GetSourceTool("EffectMask"):GetValue(("Width*2",time*2))

Пример применения формулы выше: смотрит на вход EffectMask и берёт его ширину на кадре, который вдвое больше текущего, — то есть развитие эффекта опережает саму композицию в 2 раза.

iif(time>=25 and time<=200, ceil(((time-25)/(200-25)*100)) .. "%",iif(time<25,"0%","100%"))

Прогресс, который включается не с самого начала, а с 25-го кадра, доходит до 100% к 200-му, а до и после остаётся неподвижным на границах — 0% и 100%. Замени 25 и 200 на нужные тебе кадры и вынеси их в ползунки, чтобы настраивать без правки формулы.

Настройки композиции — comp:GetPrefs

comp:GetPrefs()

Возвращает сразу весь набор настроек текущей композиции.

comp:GetPrefs("Comp.FrameFormat.Rate")

Частота кадров таймлайна одним числом. Самое частое применение — подставлять её вместо ручного fps в других формулах: не нужно вписывать число руками и рисковать ошибиться, если проект переоткроют с другой частотой.

comp:GetPrefs("Comp.FrameFormat.Width")

Ширина таймлайна в пикселях — например, 1920 для проекта в 1080p.

comp:GetPrefs("Comp.FrameFormat.Height")

Высота таймлайна в пикселях — например, 1080 для проекта в 1080p.

self.Input.OriginalWidth

Ширина не таймлайна, а именно входного видео на этом узле. Если в 1080p-проект вставлен 4K-ролик, формула вернёт честные 3840, а не 1920 таймлайна — разница важна, когда нужно работать с реальным разрешением исходника.

self.Input.OriginalHeight

То же самое, только высота — 2160 для 4K-исходника на 1080p-таймлайне.

KeyframeStretcher

min(Background1.GlobalOut,F1.FPS)

Подстраивает KeyframeStretcher под длину узла по его собственным Global In/Out — если общая длина композиции меняется, узел не «уезжает» и не обрезается, а пересчитывается сам.

Dissolve Switch

iif((comp.RenderEnd-time)<(comp.RenderEnd/2),0,1)

Переключает вход Dissolve с заднего плана (0) на передний (1) ровно в момент, когда пройдена половина композиции, — простой способ «сменить картинку» без анимации самого перехода.

Несколько таких переключателей можно связать в цепочку через iif, чтобы одним параметром (в примере — Animation) управлять сразу несколькими состояниями: например, крутить один ползунок, а переключаться между тремя разными картинками. На комбо-переключателе — iif(Animation>=1,1,0), на Switch 01 — iif(Animation>=1,1,0), на Switch 02 — iif(Switch02.Animation>1,1,0).

TimeStretcher

Мощный узел, вариантов expressions под него можно придумать бесконечно много.

time<Hold_Frame and time or time>Hold_Frame+Hold_Time and time-Hold_Time or Hold_Frame

Формула держит анимацию на паузе: до кадра Hold_Frame время идёт как обычно, затем «застревает» на Hold_Time кадров — анимация как будто останавливается, — а после снова продолжается, просто со сдвигом. Оба значения удобно вынести в Edit Controls ползунками: Hold_Frame — с какого кадра пауза, Hold_Time — насколько кадров она длится.

Готовый узел с этим expression, чтобы разобрать по частям: TimeStretcher Animation Pause Node.

If-Then-Else

iif(Merge1.Blend > 0.5, 1, 0)

Если Blend больше 0.5 — на выходе 1, иначе — 0. Именно так expressions обычно «принимают решения»: привычного if в интерфейсе нет, но есть iif() как его короткая замена.

(Merge1.Blend > 0.5) and 1 or 0

Тот же результат без iif() — через логические and/or: (условие) and значение_если_да or значение_если_нет. Работает так же, просто другой синтаксис записи.

Операторы

Оператор Что делает
x + y x плюс y
x - y x минус y
x < y 1.0, если x меньше y, иначе 0.0
x > y 1.0, если x больше y, иначе 0.0
!x 1.0, если x = 0, иначе 0.0
-x (0.0 - x)
+x (0.0 + x) — по сути не делает ничего
x ^ y x в степени y
x * y x умножить на y
x / y x разделить на y
x % y остаток от деления x на y
x <= y 1.0, если x меньше или равно y, иначе 0.0
x >= y 1.0, если x больше или равно y, иначе 0.0
x = y / x == y 1.0, если x точно равно y, иначе 0.0 (обе записи равнозначны)
x <> y / x != y 1.0, если x не равно y, иначе 0.0 (обе записи равнозначны)
x & y / x && y 1.0, если и x, и y не равны 0.0 (обе записи равнозначны)
x | y / x || y 1.0, если x или y (или оба) не равны 0.0 (обе записи равнозначны)

Формулы для Number Out / Point Out

Доступны прямо во вкладках Number Out и Point Out, как часть expression:

Функция Что возвращает
n1..n9 значение Number Input 1..9
p1x..p9x X координата Positional Control 1..9
p1y..p9y Y координата Positional Control 1..9
time текущий кадр
pi число π
e число e
log(x) логарифм x по основанию 10
ln(x) натуральный логарифм x (по основанию e)
sin(x) синус x (x в градусах)
cos(x) косинус x (x в градусах)
tan(x) тангенс x (x в градусах)
asin(x) арксинус x, в градусах
acos(x) арккосинус x, в градусах
atan(x) арктангенс x, в градусах
atan2(x, y) арктангенс x,y, в градусах
abs(x) абсолютное (положительное) значение x
int(x) целая часть x
frac(x) дробная часть x
sqrt(x) квадратный корень x
rand(x, y) случайное значение между x и y
rands(x, y, s) случайное значение между x и y по seed-у s
min(x, y) меньшее из x и y
max(x, y) большее из x и y
dist(x1, y1, x2, y2) расстояние между точками x1,y1 и x2,y2
dist3d(x1,y1,z1,x2,y2,z2) расстояние между 3D-точками
noise(x) плавный Perlin-шум по x
noise2(x, y) плавный Perlin-шум по x и y
noise3(x, y, z) плавный Perlin-шум по x, y и z
if(c, x, y) x, если c ≠ 0, иначе y

Плавность анимации — easing

Easing — это форма кривой скорости, а не сама скорость. Обычный time/comp.RenderEnd даёт линейное движение — равномерное от начала до конца. Easing-формулы ниже дают ту же дробь от 0 до 1, но не по прямой, а по кривой: In — старт медленный, разгон к концу; Out — старт быстрый, торможение к концу; InOut — медленно-быстро-медленно, S-образная кривая, самая похожая на «живое» движение. Названия семейств — Sine, Quad, Cubic, Quart, Quint, Expo, Circ, Back — это просто нарастающая «крутизна» кривой: чем дальше в списке, тем резче разгон и торможение. Подставляй любую формулу вместо обычного time/comp.RenderEnd там, где движение должно быть не линейным.

Sine

easeInSine1 - cos((time/comp.RenderEnd * pi) / 2)
easeOutSinesin(((time/comp.RenderEnd) * pi) / 2)
easeInOutSine-(cos(pi * (time/comp.RenderEnd)) - 1) / 2

Quad

easeInQuad(time/comp.RenderEnd) * (time/comp.RenderEnd)
easeOutQuad1 - (1 - (time/comp.RenderEnd)) * (1 - (time/comp.RenderEnd))
easeInOutQuadiif((time/comp.RenderEnd) < 0.5, 2 * (time/comp.RenderEnd) * (time/comp.RenderEnd), 1 - pow(-2 * (time/comp.RenderEnd) + 2, 2) / 2)

Cubic

easeInCubic(time/comp.RenderEnd)^3
easeOutCubic1-(1-time/comp.RenderEnd)^3
easeInOutCubiciif((time/comp.RenderEnd < 0.5), (((time/comp.RenderEnd)^3)*4), 1-(((1-time/comp.RenderEnd)^3)*4))

Quart

easeInQuart(time/comp.RenderEnd) ^ 4
easeOutQuart1 - pow(1 - (time/comp.RenderEnd), 4)
easeInOutQuartiif((time/comp.RenderEnd) < 0.5, 8 * (time/comp.RenderEnd) * (time/comp.RenderEnd) * (time/comp.RenderEnd) * (time/comp.RenderEnd), 1 - pow(-2 * (time/comp.RenderEnd) + 2, 4) / 2)

Quint

easeInQuint(time/comp.RenderEnd)^5
easeOutQuint1 - pow(1 - (time/comp.RenderEnd), 5)
easeInOutQuintiif((time/comp.RenderEnd) < 0.5, 16 * (time/comp.RenderEnd) *(time/comp.RenderEnd) * (time/comp.RenderEnd) * (time/comp.RenderEnd) * (time/comp.RenderEnd), 1 - pow(-2 * (time/comp.RenderEnd) + 2, 5) / 2)

Expo

easeInExpopow(2, 10 * (time/comp.RenderEnd) - 10)
easeOutExpo1 - pow(2, -10 * (time/comp.RenderEnd))
easeInOutExpoiif((time/comp.RenderEnd) < 0.5, pow(2, 20 * (time/comp.RenderEnd) - 10) / 2, (2 - pow(2, -20 * (time/comp.RenderEnd) + 10)) / 2)

Circ

easeInCirc1 - sqrt((1 - (time/comp.RenderEnd) ^ 2))
easeOutCircsqrt(1 - pow((time/comp.RenderEnd) - 1, 2))
easeInOutCirciif((time/comp.RenderEnd < 0.5), (1 - sqrt((1 - (2 * (time/comp.RenderEnd)) ^ 2))) / 2, (sqrt(1 - (-2 * (time/comp.RenderEnd) + 2) ^ 2) + 1) / 2)

Back

easeInBack(1.70158 + 1) * (time/comp.RenderEnd) * (time/comp.RenderEnd) * (time/comp.RenderEnd) - 1.70158 * (time/comp.RenderEnd) * (time/comp.RenderEnd)
easeOutBack1 + (1.70158 + 1) * pow((time/comp.RenderEnd) - 1, 3) + 1.70158 * pow((time/comp.RenderEnd) - 1, 2)
easeInOutBackiif((time/comp.RenderEnd) < 0.5, (pow(2 * (time/comp.RenderEnd), 2) * ((2.594909 + 1) * 2 * (time/comp.RenderEnd) - 2.594909)) / 2, (pow(2 * (time/comp.RenderEnd) - 2, 2) * ((2.594909 + 1) * ((time/comp.RenderEnd) * 2 - 2) + 2.594909) + 2) / 2)

Обратный отсчёт — Fake Timer

Text("9:".. max(30-floor(time/comp:GetPrefs("Comp.FrameFormat.Rate")),0))

Через узел Text+ делает таймер обратного отсчёта в формате 9:30, 9:29, 9:28… «9» перед двоеточием — просто часть строки, замени на любое число или слово под свой формат.

max(floor((Text1.N1+1)-(time/comp:GetPrefs("Comp.FrameFormat.Rate"))),0)

Та же идея, но стартовое число задаётся не в самой формуле, а ползунком N1 (или через CustomTool) — удобнее менять таймер без захода в код.

Сохрани эту шпаргалку в закладки — при работе с Fusion-страницей к ней придётся возвращаться регулярно. И не расстраивайся, если expression не заработал с первого раза: большинство формул выше завязаны на конкретные имена узлов — Text1, Rectangle1, Merge1 — проверь, что в твоём проекте они называются именно так, либо поправь имена под свои.

Не понимаешь, как монтировать?Раскладываем монтаж по полочкам — шаг за шагом, на реальных проектах.Посмотреть тарифы

Обсуждение

0
Посетители, находящиеся в группе Гость, не могут оставлять комментарии к данной публикации.
Не понимаешь, как монтировать?Раскладываем монтаж по полочкам — шаг за шагом, на реальных проектах.Посмотреть тарифы

Шпаргалки

Ёмкие разборы инструментов DaVinci Resolve — сохраняй, возвращайся, когда нужно быстро вспомнить деталь.

Все шпаргалки