• Как создать (написать) свой собственный видео эффект

    Как создать (написать) свой собственный видео эффект для lightworks
    Gary Hango, является экспертом по обработке видео эффектов, и с энтузиазмом использует Lightworks. В этой, второй части, будет рассмотрен язык программирования, который используется в Lightworks для создания видео эффектов. Далее, будет показано, как вы сами можете написать (создать) свой собственный VFX эффект для применения его в Lightworks.

    Внимание! Эта статья содержит огромное количество жаргонных слов, которые могут привести к снижению понимания.

    В предыдущей статье Основные понятия VFX эффектов я рассказал основы компьютерного программного обеспечения VFX программ, манипуляции чисел через матрицу. Используя различные интенсивности света и тени (красного, зелёного, синего и альфа канала) в каждом цифровом видеокадре, создаются видео эффекты. Вооружённые этими знаниями, мы будем смотреть на то, как применять их в создании новых пользовательских эффектов для Lightworks.

    Параллельная обработка эффектов в реальном времени

    Если вам интересна эта тема, то вероятно вы уже открывали некоторые файлы «.fx», которые идут с Lightworks. И видели, что представляет из себя исходный код, написанный на языке программирования "Си". Lightworks VFX использует один из наиболее серьёзных компонентов в DirectX, предоставляющий программирование шейдеров, язык высокого уровня HLSL (High Level Shading Language), разработанный Microsoft. Этот язык используется для записи пиксельных шейдеров DirectX, которые Lightworks компилирует в видео эффекты, которые затем становятся доступными из панели эффектов в Lightworks. Уникальным аспектом пиксельных шейдеров является скорость, с которой они обрабатывают видео. Чем быстрее (современнее) ваше графическое оборудование, тем быстрее эта обработка проходит.

    Lightworks .fx файл

    Прежде чем мы углубимся в сам код, давайте сначала посмотрим на базовую структуру файла Lightworks «.fx». Первый раздел файла определяет имя эффекта, и в какой категории на панели эффектов Lightworks он будет размещён. В следующем разделе определяются различные элементы графического интерфейса пользователя, которые позволяют вам отрегулировать параметры эффекта.

    Следующий раздел касается фактических входов видео на нашем эффекте. Здесь вы определяете количество видео-треков для работы эффекта. В четвёртом разделе эффекта, вы можете создать код, который будет фактически управлять пикселями вашего видео. Функции, которые вы здесь создаёте изменят значения пикселей вашего входного видео согласно математических алгоритмов и параметров управления GUI, которые вы определили и вывели новые значения пикселей.

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

    Давайте теперь взглянем на один из файлов «.fx», который поставляется с Lightworks. В папке установки Lightworks в Win7 это C:\Program Files (x86)\Lightworks\Shaders папка «Шейдеры» вы найдёте файл с именем «negative.fx». Откройте его в текстовом редакторе, например Блокнот.

    Как упоминалось ранее, вы увидите, что представляет из себя исходный код эффекта. Первое, что вы заметите это присутствие многих двойных косых, "//". Они используются для добавления комментариев. Когда Lightworks компилирует код, он игнорирует всё что на линии после двойных косых чёрточек. Используйте комментарии в вашем коде, чтобы описать, что происходит на каждом этапе эффекта. Это поможет вам, когда вы создаёте сложный код.

    Рассмотрим код готового эффекта

    Первая часть кода "Описание эффекта"

    //--------------------------------------------------------------//

    int _LwksEffectInfo
    <
    string EffectGroup = "GenericPixelShader";
    string Description = "Negative";
    string Category = "Colour Effects";
    > = 0;

    //--------------------------------------------------------------//

    В этом примере эффект называется "Negative" (Негатив) и будет размещён на панели эффектов в разделе «Colour Effects». Любой новый эффект, который вы создаёте должен иметь эту декларацию в верхней части файла с уникальным именем, описанием и категорией, в которую вы хотите поместить этот эффект. Если категория уже существует, то эффект будет располагаться внутри существующей, а если нет, тогда будет создана новая категория. Таким образом, вы можете организовать собственные эффекты в своей категории на панели эффектов. Просто установите «Category» на что-то вроде «My Effects».

    Вторая часть кода "Раздел параметров"

    //--------------------------------------------------------------//
    // Params
    //--------------------------------------------------------------//
    float Level
    <
    string Description = "Level";
    string Group = "Threshold";
    float MinVal = 0.0;
    float MaxVal = 1.0;
    > = 0.0;

    float Softness
    <
    string Description = "Softness";
    string Group = "Threshold";
    float MinVal = 0.0;
    float MaxVal = 1.0;
    > = 0.25;

    float _MaxSoftness = 0.2;

    //--------------------------------------------------------------//

    Это где вы определяете элементы управления для вашего эффекта.

    Параметры в этом примере являются элементами управления плавающего ползунка с минимальной точкой значения 0,0 и максимальное 1.0. Каждый раз, когда вы здесь определяете “float”, Lightworks будет создавать слайдер для вашего эффекта. «float2», «float3» и «float4» будет создавать различные виды контроля.

    Существует множество элементов управления, которые можно использовать, которые вы можете узнать, посмотрев параметры раздела различных «.fx» файлов в папке Shaders «Шейдеры» (для win7 C:\Program Files (x86)\Lightworks) или в файлах "Пользовательские эффекты" папка Effect Templates (для win7 C:\Users\Public\Documents\Lightworks), а так-же вы можете скачать "Пользовательские эффекты" на официальном форуме поддержки Lightworks, User Effects files

    Изучая код других .fx файлов, вы откроете для себя их структуру. Описание (Description) значений имён ползунков. Значение Группа «Group», показана здесь как «Threshold», это необязательное определение, как дополнение, ставит ползунки в подгруппы имён на панели эффектов. Это даёт возможность провести различие между различными группами контроля. Вы заметите, после того, как символ ">", который закрывает каждый параметр декларации, является "= 0.0;" или "= 0.25;". Это значение по умолчанию будет иметь каждый ползунок, когда вы добавляете эффект к видеоклипу.

    Ещё в этом разделе параметров вы найдёте пример Декларации "float _MaxSoftness = 0.2;". Здесь вы устанавливаете постоянные значения для использования в различных функциях, которые вы можете создать для вашего эффекта. Это позволит вам экспериментировать с различными значениями в то время как вы проверяете действие без того, что-бы изменять значение в нескольких местах в ваших функциях. Просто измените значение в этом одном месте. Важно, чтобы добавить символ подчёркивания перед постоянными значениями вы объявляете об этом. Когда Lightworks видит подчёркивания на переменной тогда она не будет добавлять его в качестве контроля на панель эффектов. Lightworks также предоставляет некоторые внутренние переменные, которые предоставляют информацию о настройках проекта для использования в вашем эффекте. Вот некоторые из наиболее полезных:

    • float _OutputWidth; // Проект резолюции ширина
    • float _OutputHeight; // Проект резолюции высота
    • float _OutputAspectRatio; // Соотношение сторон проекта
    • float _Progress; // Переменная со значением, которое изменяется от 0,0 до 1.0 от начала эффекта к его концу.

    Переменная «_Progress» может использоваться для изменения некоторых аспектов вашего эффекта в течение срока действия на временной шкале (Timeline), как исчезает и растворяется. Использовать эти внутренние переменные просто, добавьте объявления, как показано выше в разделе параметры вашего кода и используйте их в ваших функциях, как любая другая переменная.

    Принимаем видео на временной шкале (timeline)

    Третья часть кода "Где мы должны определить способ вывести видео на временной шкале для использования в действие".

    //--------------------------------------------------------------//
    texture Input;
    sampler InputSampler = sampler_state { Texture = ; };
    //--------------------------------------------------------------//

    В Pixel Shaders, каждый кадр становится текстурой нарисованной на плоскости 1,0 х 1,0. Неважно, какое разрешение исходного видео, в Pixel Shaders, оно всегда будет представлено этой плоскостью 1,0 х 1,0. Каждая точка на этой плоскости содержит четыре значения с плавающей точкой, которые соответствуют красному, зелёному, синиму и альфа-каналу из кадра. Первая строка в примере объявляется текстурой под названием "Input". Это создаёт пространство в памяти видеокарты для плоских 1,0 х 1,0 и потому, что это первый (и в этом случае только) текстуры декларации, она соединяет его с верхней дорожкой видео в Lighworks править шкале. В следующей строке на самом деле пишем видео в текстуру 1,0 х 1,0. Если вашему эффекту необходимо работать с 2-я и более видео треками, тогда вам нужно просто объявить дополнительные текстуры и пробоотборники.

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

    //--------------------------------------------------------------//
    // Code
    //--------------------------------------------------------------//
    float4 ps_main( float2 xy1 : TEXCOORD1 ) : COLOR
    {
    float4 ret;

    float soft = Softness * _MaxSoftness;
    float softStart = Level - soft;

    // Get source pixel..
    float4 srcPixel = tex2D( InputSampler, xy1 );

    float lum = ( srcPixel.r + srcPixel.g + srcPixel.b ) / 3.0;

    if ( lum >= Level )
    {
    // Calculate the inverse
    ret = 1.0 - srcPixel;
    }
    else if ( lum > softStart )
    {
    ret = lerp( srcPixel, 1.0 - srcPixel, ( lum - softStart ) / soft );
    }
    else
    {
    ret = srcPixel;
    }

    ret = lerp( srcPixel, ret, srcPixel.a );
    ret.a = srcPixel.a;

    return ret;
    }

    //--------------------------------------------------------------//

    Здесь у нас есть функция под названием "ps_main". Эта функция манипулирования пикселями, она всегда объявляется как "float4", потому что она будут работать с четырьмя значения плавающей точкой красного, зелёного, синего и альфа-каналов для каждого пикселя. "Float2 xy1: TEXCOORD1" внутри скобок определяет "xy1", координаты из текстур. Когда функция Pixel Shader выполняется, он должен знать, какой пиксель работает. Для каждого пикселя на текстуре самолёта, который содержит наш источник видео, координаты загружаются в двух значениях (x, y) чисел с плавающей запятой "xy1". Где каждый пиксель Горизонтальной координации хранится в "xy1.x" а каждый пиксель Вертикальной координации хранится в "xy1.y" и передаётся нашей Pixel Shader функции. Параметр ": COLOR" сообщает компилятору функций о выводе значений пикселей цветов.

    float4 ret; - Это резервирует место в памяти для четырёх операций с плавающей запятой и называет его "ret". Используется для хранения новых значений пикселей цветов.

    • float soft = Softness * _MaxSoftness;
    • float softStart = Level - soft;

    Это создаёт число с плавающей точкой под названием "soft", что совпадает со значением, установленным на определённых выше ползунка под названием "Softness", умноженная на постоянное значение "_MaxSoftness" или 0,2. Затем определяется число с плавающей точкой "softStart", чтобы быть равным значению ползунка под названием "Level" минус значение числа с названием "soft".

    В следующих строках

    • float4 srcPixel = tex2D( InputSampler, xy1 );

    Извлекает RGBA значения пикселя в "xy1" координаты из текстуры и сэмплера, которые были определены выше (источник видеосигнала), поместив их в четыре значения с плавающей точкой "srcPixel".

    • float lum = ( srcPixel.r + srcPixel.g + srcPixel.b ) / 3.0;

    Здесь мы определяем одну переменную float "lum", чтобы быть средним значением каждого пикселя красного, зелёного и синего. Это упрощённый способ получить значение яркости каждого пикселя.

    if ( lum >= Level )
    {
    // Calculate the inverse
    ret = 1.0 - srcPixel;
    }
    else if ( lum > softStart )
    {
    ret = lerp( srcPixel, 1.0 - srcPixel, ( lum - softStart ) / soft );
    }
    else
    {
    ret = srcPixel;
    }

    Следующая функция else. Если переменная "lum" (яркость из пикселей) больше или равна значению слайдера под названием "Level", тогда переменной четыре float "ret" даётся значение 1,0 минус четыре float переменной "srcPixel", который содержит значения пикселей источника видео. Здесь следует отметить, что значения переменной четыре float можно получить с различными способами, вот пример, srcPixel.r, srcPixel.g, srcPixel.b and srcPixel.a, которые соответствуют красный, зелёный, синий и альфа-канал. Поэтому, когда вы пишете "ret = 1.0 – srcPixel;" что подразумевается время является "ret.r = 1.0 – srcPixel.r, ret.g = 1.0 – srcPixel.g, ret.b = 1.0 – srcPixel.b and ret.a = 1.0 – srcPixel.a". Переменные обычно обозначают "float3" - "name.xyz" и "float2" - "name.xy".

    Перейти к коду. Эта часть функции инвертирует или отрицает, видео. Если исходный пиксель имеет значение 1,0, то 1,0 - 1,0 = 0,0, и если исходный пиксель имеет значение 0,0, то 1,0 - 0,0 = 1,0. Это делается для каждого цветового канала каждого пикселя, если значение яркости больше или равна значению "Level" слайдера. Если "lum" меньше, чем "Level", то проверяется, есть ли "lum" больше, чем переменная "softStart". Если это так, то выполняется уравнение;

    • ret = lerp( srcPixel, 1.0 - srcPixel, ( lum - softStart ) / soft );

    Линейная интерполяция

    Функция "lerp" является сокращением от линейной интерполяции. Эта функция трёх переменных. На выходе функция интерполяции между первой переменной, а вторая переменная по отношению третьей переменной. Таким образом, если первая переменная равна 0,25, а вторая переменная равна 0,5 и третьей переменной составляет 0,75, то значение функции будет 0,4375.

    0,4375 составляет три четверти пути между 0,25 и 0,5. Функция "lerp" широко используется в Pixel Shaders для смешивания видео вместе (blend). Вы можете смешать две видео дорожки вместе "lerping" их значения пикселей, используя значение альфа-канала с одного из треков в качестве третьего параметра. Смотрите, как вы можете определить три переменные, используемые в примере.

    Если "lum" меньше, чем "Level" и менее "softStart", то функция снижается до окончательного раздела "else". Здесь "ret" просто сделали равным значению "srcPixel".

    Окончательный код этой функции:

    ret = lerp( srcPixel, ret, srcPixel.a );
    ret.a = srcPixel.a;
    return ret;

    "lerp" функция смешивания исходного видео с перевёрнутым видео, значение альфа-канала источника видео. Затем это изменяет альфа-канал в нашем изменение, видео равным альфа-каналу источника видео, затем возвращение "return" с, или вывод значений RGBA в "ret".

    Техника: как собрать эффект

    Заключительная часть кода называется Техника "technique". Это где компилятору рассказывается, как собрать эффект.

    technique Negative
    {
    pass Single_Pass
    {
    PixelShader = compile PROFILE ps_main();
    }
    }

    technique должно быть присвоено имя. Это может быть что угодно, но в данном случае это то же имя, что и эффект. Внутри находится раздел под названием "pass", это команда для компиляции "ps_main". Слово "PROFILE" является прототипом, Lightworks внутренних эффектов использования. Для ваших собственных эффектов, которые вы должны будете ввести фактическое значение. Значение для использования будет одно из любых ps_2_0, ps_2_b, или ps_3_0. ps_2_0 является основным DirectX 9 Shader. ps_2_b позволяет более сложных функций. Эти два являются наиболее совместимыми для большинства видеокарт. ps_3_0 обеспечивает ещё более сложные функции, но не совместим с некоторыми видеокартами.

    После того как вы создали свой эффект, вы должны будете использовать Lightworks для его компиляции. Положите ваш .FX файл в папку и создайте шаблон. Если этого не сделать эффект не будет работать.

    Для XP расположение:
    C:\Documents and Settings\All Users\Documents\Lightworks\Effect Templates
    Для Vista и Win7, местоположение:
    C:\Users\Public\Documents\Lightworks\Effect Templates

    Запустите Lightworks и войдите в проект. Откройте панель эффектов с помощью назначенных клавиш или нажмите кнопку "Effects" на временной шкале редактирования. Нажмите на иконку винтики и выберите Создать шаблон из файла FX "Create template from FX file". Выберите. FX файл и нажмите кнопку "Ok". Если нет ошибок в файле, ваш эффект будет составлен и помещён в категорию, определяется в начале файла.

    Ну вот пожалуй и всё. Теперь Вы знакомы с основами создания собственного VFX для Lightworks. Посмотрите код .FX файлов, которые входят в состав программы Lightworks и пользовательских эффектов которые можно загрузить с форума Lightworks для справки, вместе с вашим воображением, вы скоро будете писать собственные VFX для ваших проектов и обмена ими с другими пользователями Lightworks.


    Источник: redsharknews.com/technology/item/221-how-to-write-video-effects-for-lightworks

13.01.2013