Text+ и Text1 в DaVinci Resolve: скрытые возможности

Text+ (в списке узлов он же Text1) — самый недооценённый узел в Fusion-странице DaVinci Resolve. Обычно его используют для набора заголовка и выбора шрифта, а дальше даже не открывают остальные вкладки. Здесь — то, что обычно проходит мимо: чтение текста из файла, бегущая строка и титры, подсчёт символов формулами, свои шрифты и ручная расстановка букв.
Коротко о термине, если ты впервые открываешь expression: это формула, которую вписываешь в поле параметра вместо ручного значения — правый клик по полю → Expression. С этого момента значение в поле каждый кадр вычисляется по формуле. Ниже formulas в основном живут в поле StyledText узла Text+ — том самом большом текстовом поле, куда обычно просто печатают текст.
Текст из файла
Text+ умеет не только принимать напечатанный текст, но и подтягивать его из обычного текстового файла — удобно, когда текст присылает заказчик или он часто меняется: правишь файл на диске, а не лезешь каждый раз в проект.
Пока это работает только с файлами из папки документов DaVinci Resolve — на Windows это
C:\Documents\Blackmagic Design\DaVinci Resolve\Fusion
Туда нужно положить свой текстовый файл — например, text.txt, отформатированный заранее в любом текстовом редакторе.
Дальше — правый клик внутри поля StyledText → Expression, и в поле expression:
Text(assert(io.open(comp:MapPath("comp:/text.txt"), "r")):read("*all"):gsub("\\n", '\n'):gsub("\\t", " "))Подтягивает содержимое файла целиком, с переносами строк и табуляцией как в оригинале. Удобно, если нужно вставить присланный текст «как есть»: отрендерил один раз, поменял файл на диске, отрендерил снова с другим текстом — без правок в самом проекте.
Ничто не мешает завести несколько таких Text+ с разными файлами — просто меняй имя файла в формуле у каждого.
Построчный вывод по таймингу
Похожий трюк, но для списка: одна строка текстового файла показывается за раз, и через заданный интервал сменяется на следующую — как титры со сменой реплик. Тут formulas живут не в StyledText, а на странице настроек композиции, в двух отдельных полях: Start Render Script (выполняется один раз, в начале рендера) и Frame Render Script (выполняется на каждом кадре).
Сначала Start Render Script — читает файл целиком в таблицу построчно:
f = [[C:\list.txt]] -- путь к файлу
interval = 2 -- через сколько кадров меняется строка
t = {}
for l in io.lines(f) do
table.insert(t, l)
end
num_lines = table.getn(t)
А затем Frame Render Script — на каждом кадре берёт из этой таблицы нужную по времени строку и кладёт её в StyledText:
index = math.floor(time / interval)
if index > num_lines then
index = num_lines
end
StyledText = t[index]
Подставь свой путь к файлу в f и нужный интервал смены строк в interval — остальное произойдёт само.
Считаем и препарируем текст формулами
Дальше — набор формул, которые читают содержимое StyledText одного узла и что-то с ним делают: считают, режут, переставляют. Чтобы формула могла сослаться на текст ИЗ ДРУГОГО узла, у него должно быть имя — например, Text1 — и тогда в формуле другого Text+ пишешь Text1.StyledText.Value, и туда прилетает именно то, что напечатано в Text1.
string.len(Text1.StyledText.Value)Сколько всего символов в тексте Text1 — включая пробелы и знаки препинания.
:_, 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Сколько гласных букв (латиница).
:_, 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Сколько символов годится для шестнадцатеричной записи — цифры и буквы A–F.
:_, myletters = string.gsub(Text1.StyledText.Value, "%A", ""); return mylettersВсё, что НЕ буквы. Общее правило для всех формул выше: заглавная буква класса после % (было %a, стало %A) всегда переключает результат на противоположный, так же как ^ перед классом в квадратных скобках.
Дальше — не подсчёт, а обработка текста: результат тоже формула, но выводит не число, а переделанный текст.
string.rep(Text1.StyledText.Value, 3)Повторяет текст Text1 три раза подряд.
string.reverse(Text1.StyledText.Value)Переворачивает текст задом наперёд.
string.lower(Text1.StyledText.Value)Весь текст в нижний регистр.
string.upper(Text1.StyledText.Value)Весь текст в ВЕРХНИЙ регистр.
string.sub(Text1.StyledText.Value, 1, 2)Первые 2 буквы текста. Отсчёт слева, поэтому 1, 3 — это 1-я, 2-я и 3-я буквы. Отрицательные числа считают с конца.
string.byte(Text1.StyledText.Value, 1)ASCII-код первой буквы текста числом. Отсчёт тоже слева, отрицательные числа — с конца.
string.char(Text1.StyledText.Value, 1)Обратное действие: символ по его ASCII-коду.
И склейка текста из нескольких источников:
Text1.StyledText.Value .. " " .. "Eggs"Текст Text1, пробел и слово «Eggs» следом. Два дефиса .. склеивают строки в Lua — между ними и добавляют пробел, если он нужен: просто напиши .. " " ...
Text1.StyledText.Value .. Text2.StyledText.ValueТекст из двух Text+ подряд, без пробела между ними.
Ещё один источник текста — поле Comments на странице настроек любого узла: обычная текстовая заметка, но её тоже можно склеить формулой, и в неё точно так же можно вставить модификатор — например, таймкод (правый клик в поле Comments → Timecode).
Text1.StyledText.Value .. Comments.ValueТекст Text1 и содержимое поля Comments того же узла — например, вписанный туда таймкод — подряд, без пробела.
Text1.StyledText.Value .. " " .. Comments.ValueТо же самое, но с пробелом между ними.
Бегущая строка и титры
Прокручивающиеся титры в конце ролика и бегущая строка внизу экрана — тоже штатная функция Text+, просто спрятана не на первой вкладке.
- На вкладке Layout поменяй Type с Point на Frame — и там же выставь Width и Height в 1.
- Перейди на вкладку Text и найди под настройками привязки (anchor) комбобокс Scroll. Roll — это прокрутка титров, Crawl — бегущая строка.
- Выбери Roll — появится ещё один параметр, Scroll Position. Правый клик по нему → Expression.
1-(time/comp.RenderEnd)В Scroll Position запускает прокрутку титров снизу вверх на протяжении всей композиции. Не забудь напечатать сам текст в StyledText.
Для бегущей строки внизу экрана то же самое, только Scroll ставится на Crawl — а нужную скорость и положение подбираешь через Width, Height и Position на вкладке Layout.
Не только текст
Text+ умеет выводить не только напечатанное, но и почти что угодно другое — значения других узлов, дату, случайные числа.
Transform1.AngleОбщий принцип: ИмяУзла.Параметр выводит значение любого параметра любого узла композиции — не обязательно текстового. Angle здесь просто пример, работает с любым свойством.
Center.X .. " " .. Center.YКоординаты самого узла Text+ — X и Y через пробел.
string.format("%.4f" ,Center.X)То же значение, но округлённое до 4 знаков после запятой — сырые координаты обычно слишком длинные для читаемого вывода.
string.format("%.2f" ,Center.X) .. "x" .. " ".. string.format("%.2f" ,Center.Y) .. "y"Координаты X и Y вместе, округлённые до 2 знаков, с подписями «x» и «y» — готовая строка для вывода на экран.
math.random()Случайное число от 0 до 1 — новое на каждом кадре. При воспроизведении будет мельтешить: если нужно значение, привязанное к конкретному кадру, а не дёргающееся на каждом, для этого в статье про expressions есть randomseed.
math.random(0, 100)То же самое, но случайное целое число от 0 до 100.
os.date("%a")Сокращённое название текущего дня недели. Со вставленным кэшем кадров могут быть нюансы — движок иногда придерживает старое значение, но в самом рендере дата всегда актуальная.
Код после % в os.date() меняет, что именно выводится:
| Код | Что выводит |
|---|---|
%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) |
%% | символ % как есть |
Свои шрифты под рукой
Если список шрифтов в Text+ огромный, а пользуешься на деле десятком — можно собрать отдельную папку с избранными и подключить её отдельным пунктом в выпадающем списке шрифтов.
- В папке документов DaVinci Resolve создай папку
Fontsи скопируй туда нужные шрифты. Путь на Windows:C:\Documents\Blackmagic Design\DaVinci Resolve. - На странице Fusion открой Fusion → Fusion Settings → Path Map.
- В списке выбери Fonts — внизу панели появятся детали пути. Нажми на папку и укажи ту, что создал.
- Сохрани и перезапусти Resolve — шрифты подгружаются только при старте программы.
После перезапуска в выпадающем списке шрифтов Text+ появится отдельная группа с твоими избранными.
Ручной кернинг
Текст не обязан лежать ровной строкой — расстояние между конкретными буквами можно двигать руками, а не только общим трекингом.
На странице Fusion, когда в кадре есть текст и выбран сам узел Text+, в левом верхнем углу вьюера есть набор мелких значков. Наведи на них и найди «allow manual kerning» — включи его, затем увеличь масштаб на тексте в кадре: у каждой буквы появится маленький красный квадрат. Перетаскивая его, двигаешь именно эту букву, не трогая остальные.
На постоянку это не нужно почти никогда, но для леттеринга в заголовке или подгонки логотипа под текст — единственный способ подвинуть одну букву, не разваливая всю строку.
Обсуждение
0На этой странице
Шпаргалки
Ёмкие разборы инструментов DaVinci Resolve — сохраняй, возвращайся, когда нужно быстро вспомнить деталь.
Все шпаргалки