» Морфинг объектов GPU
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

Морфинг объектов GPU

English | French | Italian | Japanese

Простой способ расчета в видеокарте (gpu)

Подготовка объектов

Как и заявлено в заголовке, это упражнение посвящено расчетам выполняемым в шейдере (эффекте). Если вы совсем ничего не знаете о шейдерах, загляните сначала в упражнение Пиксельные шейдеры для новичков.
Мы будем работать с геометрией объекта (т.е. с вертексами)и напишем простой вертексный (вершинный) шейдер. Какой бы шейдер вы не начинали писать для vvvv, всегда хорошо начинать с шейдераTemplate (EX9.Effect). Из-за отсутсвия в vvvv сколько-нибудь интересных встроенных объектов, мы снова воспользуемся двумя типовыми цилиндрами. И опять сделаем их морфинг. Подготовьте патч, как показано на скриншоте:

Помните, что сочетание нодов AspectRatio/Camera это не обязательное условие, а просто хороший и удобный прием. Шейдер Template очень простой - по сути он не делает ничего - поэтому мы видим просто белый цилиндр.

Объединяем 2 объекта в один

Как мы и обещали, вся "тяжелая" часть фокуса будет выполнена шейдером в видеокарте, поэтому этот метод гораздо производительнее предыдущего. Как нам подключить 2 (или более) объектов к одному шейдеру? Это важный момент сейчас. Проблема в том, что формально невозможно подключить к шейдеру более одного объекта. Придется обойти это ограничение, объединив данные двух (или более) объектов в один - мы собираем новый объект, объединяя данные исходных объектов.

На скриншоте показано как объединить вертексные данные двух объектов в один. Обратите внимание на нод VertexBuffer (EX9.Geometry Join). Вам нужно выделить его, и через Инспектор открыть некоторые дополнительные пины: хотя вертексный буфер (VertexBuffer) может содержать только один компонент позиции ("position") и один компонент сглаживания ("normal"), он может содержать несколько (до 8) компонентов координат текстуры ("texture coordinate"). Их-то мы и используем для решения нашей задачи. В Инспекторе мы добавляем 2 дополнительных пина в VertexBuffer (EX9.Geometry Join), установив значение "3D TexCoords" для первых двух пинов "Enable Texture Coordinate ..". Теперь мы добавляем сюда соответсвующие компоненты (position and normal) нашего второго объекта.

Сейчас не важно, что мы добавили position и normal в компоненты буфера текстур "3D TexCoords". Мы учтем это, когда будем писать шейдер, чтобы он корректно расшифровал данные из вертексного буфера. Это относится к семантике языка шейдеров и подробнее об этом мы поговорим ниже...

Пину "Apply" в нодах VertexBuffer (EX9.Geometry Join) и Mesh (EX9.Geometry Join) нужен сигнал =1 только когда объект изменился (например, если в нашем примере вы измените радиус цилиндров). Поскольку эти ноды не применяют новые значения постоянно, производительность не падает!

Вертексный (вершинный) шейдер

Оставшаяся часть фокуса делается внутри шейдера. Откройте Template (EX9.Effect) кликом правой кнопкой на ноде, в открывшемся окне выберите TFixedFunction в левой панели. Поскольку в нашем шейдере не нужна техника обработки fixedfunction, просто удалим этот фрагмент (т.е. выделяем и удаляем все строки ниже: technique TFixedFunction...) и сохраняем изменения (CTRL+SHIFT+S) под новым именем (например, MyFirstMorph.fx).

Теперь добавим к шейдеру пин "MorphFactor" (Фактор деформации) и два пина цвета. Мы создаем их вписывая следующие строки:

float MorphFactor;
float4 Color1: COLOR;
float4 Color2: COLOR;

прямо за существующими четырьмя строками в самом начале (в верху) шейдера:

//transforms
float4x4 tW: WORLD;        //the models world matrix
float4x4 tV: VIEW;         //view matrix as set via Renderer (EX9)
float4x4 tP: PROJECTION;
float4x4 tWVP: WORLDVIEWPROJECTION;
 
float MorphFactor;
float4 Color1: COLOR;
float4 Color2: COLOR;

Обратите внимание, что в ноде шейдера в патче сразу появились 3 новых пина.
Теперь найдем фрагмент:

vs2ps VS(
   float4 PosO  : POSITION,
   float4 TexCd : TEXCOORD0)
{
...

здесь описана текущая функция обработки вертексов.

Следующая строка:

Out.Pos = mul(PosO, tWVP);

весьма интересна для нас. Здесь говорится, что входящие значения позиции (position) первого цилиндра (PosO) обрабатываются матрицей (tWVP) - worldviewprojection - и выводятся как результат обработки шейдером (Out.Pos). Именно здесь мы объединим данные позиции первого цилиндра с данными позиции второго цилиндра.

Почему мы уверены, что параметр PosO относится к данным именно первого цилиндра? Потому что этот параметр относится к семантике POSITION, а именно туда мы задали данные в VertexBuffer. Поэтому, если мы хотим получить значения для второго объекта, которые мы задали как "TexCoord0", мы должны задать параметр с доступом к семантике TEXCOORD0, который уже прописан здесь:

float4 TexCd : TEXCOORD0;

Поскольку в нашем примере не используются координаты текстур, мы можем просто переименовать этот параметр в "PosO2". Таким образом и эти данные теперь относятся к семантике POSITION.

float4 PosO2: TEXCOORD0;

Теперь у нас есть данные двух объектов и мы можем делать морфинг. Чуть более сложный (но прозрачный) способ - заменить строку:

Out.Pos = mul(PosO, tWVP);

на:

Out.Pos = mul(MorphFactor * PosO + (1-MorphFactor) * PosO2, tWVP);

или использовать встроенную функцию hlsl - "lerp" - как сделано здесь:

Out.Pos = mul(lerp(PosO, PosO2, MorphFactor), tWVP);

Должна высветитьшя ошибка параметра "TexCd", который мы только что заменили на "PosO2". Просто удалите:

Out.TexCd = mul(TexCd, tTex);

Теперь шейдер должен работать (выходной пин compile =1) и когда вы меняете значение пина "MorphFactor" в патче, вы должны видеть искомый результат.

Пока у нас нет блендинга цвета. Но это просто. Найдите фрагмент в части pixelshader:

float4 PS(vs2ps In): COLOR
{
   float4 col = tex2D(Samp, In.TexCd);
   return col;
}

и замените его на:

float4 PS(vs2ps In): COLOR
{
   return lerp(Color1, Color2, MorphFactor);
}

Вот и все.

Бонус

Возможно, вы хотите деформировать не только плоско освещенные объекты. Возьмите шейдер GouraudDirectional (EX9.Effect), сохраните его под другим именем и внесите те же изменения, что мы сделали только что в Template (EX9.Effect). Помните, что сейчас мы обрабатывали только данные POSITION, а вам придется добавить обработку данных NORMAL! Принцип там тот же.

anonymous user login

Shoutbox

~12d ago

joreg: Postponed: Next vvvv beginner course starting April 29: https://thenodeinstitute.org/courses/vvvv-beginner-class-summer-2024/

~1mth ago

~1mth ago

joreg: The Winter Season of vvvv workshops is now over but all recordings are still available for purchase: https://thenodeinstitute.org/ws23-vvvv-intermediates/

~2mth ago

schlonzo: Love the new drag and drop functionality for links in latest previews!

~2mth ago

joreg: Workshop on 29 02: Create Sequencers and Precise Clock Based Tools. Signup here: https://thenodeinstitute.org/courses/ws23-vvvv-08-create-sequencers-and-precise-clock-based-tools-in-vvvv-gamma/