3. Практическая часть
Исходный размер 2480x3500
Данный проект является учебной работой студента Школы дизайна или исследовательской работой преподавателя Школы дизайна. Данный проект не является коммерческим и служит образовательным целям

3. Практическая часть

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

В основе каждого проекта лежит использование ноды Solver, которая позволяет быстро создавать анимацию и объединять несколько подходов в одном процессе. Так, активно дополнительно применяются VEX и циклы For-Each.

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

3.1. Рост кристаллов

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

big
Исходный размер 1920x810

Референс роста кристаллов и композиционного решения.

Анализ природных процессов кристаллообразования показывает, что рост начинается из случайных точек и развивается постепенно, формируя сложную структуру. Именно этот принцип лежит в основе данного проекта.

big
Исходный размер 2480x1296

Схема проекта с системой роста кристаллов.

Геометрия поверхности роста

post

Первый шаг — создание геометрии, на которой происходит рост кристаллов.

Для этой цели создаётся сфера через ноду «Sphere» (тип Primitive Type — Polygon). В параметрах увеличивается частота разбиения Frequency = 20. для большей детализации.

post

Затем добавляется нода «Mountain» для создания формы, похожей на камень.

post

Нода «Mountain» Смещение точек относительно их нормалей на основе фрактального шума.

Для изменения амплитуды смещения точек необходимо менять параметр Amplitude, для изменения размера шума воздействия — Element Size, для вариаций смещения — Offset.

Так, через подбор значений находится наиболее подходящая форма камня.

Исходный размер 1920x810

Изменения параметров ноды «Mountain».

post

Для того чтобы определить область роста кристаллов, добавляется нода «Mask By Feature».

post

Нода «Mask by Feature» Генерация маски на основе геометрических свойств (высота, кривизна, угол и т. д.).

Для удобства включается отображение маски. В параметре Direction выбирается направление вектора, который создает маску на поверхности. Красная зона — 1, синяя — 0.

Исходный размер 1920x810

Включение отображение маски и изменение направления вектора воздействия в ноде «Mask by Feature».

post

После создаётся нода «Attribute Wrangle», работающая на уровне Detail. Для отслеживания возраста процесса определяется integer атрибут age:

i@age = 0;

Этот атрибут должен быть создан заранее, чтобы Solver мог его обновлять.

post

Затем добавляется еще одна нода «Attribute Wrangle», работающая на уровне Primitives. Чтобы впоследствии можно было отделить геометрию камня от геометрии кристаллов, необходимо создать string атрибут name:

s@name = «stone» = 0;

Исходный размер 1920x810

Создание бокса для организации нод.

post

На выход добавляется «Null» с именем OUT_SOURCE. Это нужно для удобного рефакторинга.

Геометрия кристалла

post

Второй шаг — создание геометрии кристалла.

Для этого создаётся нода «Box», которая задаёт базовую форму.

post

Через ноду «PolyBevel» добавляются фаски у куба для создания более реалистичной формы.

post

Нода «PolyBevel» Создание закруглений вдоль эджей и углов.

Исходный размер 1920x810

Создание фаски через параметр Distance в ноде «PolyBevel».

post

Затем нода «Normal» настраивает сглаживание и визуально задаёт острые грани у геометрии.

post

Нода «Normal» Вычисление нормали поверхности (для корректного отображения сглаживания).

Исходный размер 1920x810

Настройка сглаживания через изменение параметра Cusp Angle в ноде «Normal».

post

В конце этого этапа ставится нода «Null» с именем OUT_GEO.

Симуляция

post

Следующий шаг — симуляция роста через Solver.

Для этого создаётся нода «Solver». В первый вход подаётся OUT_SOURCE (геометрия камня), во второй — OUT_GEO (геометрия кристалла). После чего необходимо зайти внутрь ноды.

post

Внутри создаётся нода «Attribute Wrangle», на уровне Detail. и помещается после Prev_Frame.

i@age += 1; — каждая новая итерация увеличивает общую переменную возраста на 1.

i@scatter = i@age * 2; — создание новой integer переменной scatter, которая отвечает за количество точек, на которые будут копироваться кристаллы: каждую новую итерацию их количество увеличивается в 2 раза.

post

Следом добавляется нода «Scatter » для генерации точек.

post

Нода «Scatter» Создание случайно расположенных на геометрии точек.

post

В параметре Force Total Count указывается количество создаваемых точек. Здесь необходимо считывать значение detail-атрибута scatter из текущей геометрии:

detail (0, «scatter», 0) — detail (geometry, attribute_name, 0) — чтение detail-атрибута attribute_name на указанной геометрии. — вместо конкретной ссылки на геометрию можно указать 0 — так считается геометрия с основного первого входа (input 0).

В поле Density Attribute выбирается маска mask (создана в Mask By Feature). Таким образом, точки будут появляться только на заданной стороне: на области, имеющей значения маски ближе к 1 (окрашены в красный цвет).

post

Чтобы кристаллы имели разный наклон, создаётся нода «Attribute Randomize».

post

Нода «Attribute Randomize» Генерация случайных значений у атрибута (-ов).

post

В Attribute Name указывается N, и во вкладке Distribution выбирается опция Inside Sphere. Это создаёт случайные направления в трёх осях.

post

Добавляется нода «Copy to Points» для переноса геометрии на точки.

В 1-й вход подключается геометрия кристалла (2-й вход Solver), во 2-й — сгенерированные на поверхности точки.

post

Нода «Copy to Points» Копирование геометрии из первого входа на точки из второго.

post

Между частью Input_2-Copy_to_Points добавляется нода «Transform», для того чтобы настроить размер кристаллов: каждую новую итерацию геометрия уменьшается в два раза. В параметре Uniform Scale используется формула:

1 / (detail (»…/attribwrangle1», «age», 0) + 1) — detail (»…/attribwrangle1», «age», 0) — чтение значения detail-атрибута age из ноды attribwrangle1.

Так размер зависит от возраста: чем больше age, тем меньше размер кристаллов.

post

После копирования создаётся новая нода «Attribute Wrangle», работающая на уровне Primitives.

Во второй вход подключается 1-й Wrangle, чтобы считать корректное значение возраста для присвоения номера итерации каждому кристаллу. Следующее VEX-выражение позволяет это сделать:

i@cycle_num = detail (1, «age», 0); — detail (1, «age», 0) — чтение detail-атрибут age с геометрии из второго входа (input1).

Чтобы новые кристаллы сохранялись вместе с предыдущими, добавляется нода «Merge», в которую подключен 2-й Wrangle и Prev_Frame.

post

После этого создаётся третья нода «Attribute Wrangle», работающая на уровне Detail.

Во второй вход подключается 1-й Wrangle, чтобы обновить глобальный атрибут age на всей геометрии перед следующей итерацией. Для этого используется VEX-выражение:

i@age = detail (1, «age», 0);

Исходный размер 1920x835

Итоговая нодовая структура внутри Solver.

Исходный размер 1920x810

Симуляция в «Solver».

Появление кристаллов выглядит резким и неестественным: геометрия возникает в кадре без процесса роста. Потому необходимо отдельно анимировать постепенное увеличение каждого кристалла. Именно для этого заранее был создан атрибут cycle_num, который позволяет управлять масштабированием каждой отдельной геометрии.

Анимация роста

post

После завершения работы внутри Solver необходимо вернуться на уровень SOP. Затем создаётся нода «Time Shift» для фиксации состояния.

post

Нода «Time Shift» Фиксация или смещение кадра в анимации.

В настройках ноды необходимо удалить текущее значение параметра Frame и задать новое — 40. Это число можно изменять для увеличения/уменьшения количества итераций.

Исходный размер 1920x810

Удаление и изменение параметра Frame в ноде «Time Shift».

post

Далее добавляется нода «Split».

post

Нода «Split» Разделение примитивов или точек на две геометрии по заданному условию.

post

В параметре Group вводится выражение @name=stone. Теперь первый выход ноды содержит геометрию камня, второй — геометрию кристаллов.

post

Так как каждая итерация роста имеет собственное значение атрибута cycle_num, появляется возможность поочередно масштабировать каждую итерацию, что создаёт эффект последовательного роста.

Для этого создаётся цикл For-Each Named Primitive, поскольку позволяет автоматически разбивать геометрию по значению атрибута.

В ноде «Block Begin» нажимается кнопка Create Meta Import Node. Она добавляет вспомогательную ноду с данными цикла. В данном случае, позже понадобится номер итерации из атрибута iteration.

Исходный размер 1920x810

Создание вспомогательной ноды цикла через ноду «Block Begin».

post

В ноде «Block End» в поле Piece Attribute прописывается cycle_num, чтобы цикл последовательно проходил по каждой итерации кристаллов.

post

Поскольку каждая итерация состоит из множества отдельных кристаллов, их трансформация должна выполняться изолированно.

Для этого внутри цикла создаётся второй цикл For-Each Connected Pieces, позволяющий работать с каждым кристаллом отдельно.

Автоматически перед 2-м циклом добавляется нода «Connectivity», которая разделяет множество кристаллов на отдельные сегменты.

post

Нода «Connectivity» Создание атрибута, который определяет принадлежность точек или примитивов к отдельным изолированным частям геометрии.

Исходный размер 1920x775

Разделенная на отдельные части одна итерация кристаллов (у каждой части свой цвет) через ноду «Connectivity».

post

Внутри второго цикла создаётся нода «Transform».

Во вкладке Pivot Transform в поле Pivot Translate вводятся выражения $CEX, $CEY, $CEZ соответственно, чтобы опорная точка находилась в центре каждого кристалла.

Затем на параметр Uniform Scale устанавливаются ключи анимации: на 0 кадре значение 0, на 30 кадре — значение 1. Второй ключ можно ставить как раньше, так и позже — это изменяет скорость роста.

Исходный размер 1920x850

Создание ключей анимации на параметре Uniform Scale в ноде «Transform».

post

После второго цикла создаётся нода «TimeShift». В параметре Frame вводится выражение:

$F − detail (»…/foreach_begin2_metadata1/», «iteration», 0) * 3 — $F — текущий кадр таймлайна. — detail (…, «iteration», 0) — обращение к созданной meta ноде, чтение номера итерации. — *3 — задержка во времени.

Это позволяет сдвигать начало анимации каждой итерации кристаллов, основываясь на её номере.

Наконец, результат трансформации (выход второго цикла) соединяется с первым выходом ноды «Split» через ноду «Merge», что объединяет анимированные кристаллы с исходной статичной геометрией камня.

Исходный размер 1920x835

Итоговая нодовая структура части с анимацией.

Исходный размер 1920x810

Итоговый флипбук.

Loading...

3.2. Рост корневой системы

Задача этого раздела — разработать систему роста корневой структуры, которая постепенно углубляется вниз и разветвляется в разные стороны.

Исходный размер 1920x810

Референс роста корней и композиционного решения.

Изучение биологических материалов показывает, что корни развиваются неравномерно: основной стержень движется вниз, постоянно изгибаясь и периодически разделяясь на несколько ответвлений. Кроме того, старые участки постепенно утолщаются. Обращение к такой системе позволяет достичь наиболее естественного результата.

Исходный размер 2480x1550

Схема проекта с системой роста корней.

Начальная точка

post

Первый шаг — создание начальной точки.

Для этого добавляется нода «Add», и создается точка в нулевых координатах.

Далее создаётся нода «Attribute Wrangle», работающая на уровне Points. Внутри задаются основные атрибута, определяющие условия роста.

post

i@active = 1; — создание integer параметра active для обозначения активной точки, которая подвергается трансформации.

v@dir = {0, -1, 0}; — создание vector параметра dir для назначения базового направления, в данном случае рост идет вниз по оси Y.

f@width = 0.1; — создание float параметра width для обозначения начальной толщины, которая по мере цикла увеличивается.

Поле турбулентности

Второй шаг — создание поля турбулентности, которое будет искажать траекторию роста.

Для этого используется Volume с заданными параметрами турбулентности, который задает векторное поле смещения.

Volume (вольюм) — это поле данных, состоящее из трёхмерных пикселей — вокселей.

Исходный размер 2480x914

Сравнение полигональной модели и воксельного объёма при разных разрешениях (0.1 и 0.05).

В Houdini существует два типа Volume: — Standard Volume — плотная равномерная сетка, состоящая из всех вокселей, включая пустые области. — VDB — разреженная сетка, состоящая только из вокселей с данными, пустые области не записываются.

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

Исходный размер 1920x960

Сравнение форматов хранения данных Standard Volume и VDB.

post

Теперь можно продолжить создание сцены. Добавляется нода «Box» размером 100×100×100. Это область, в которой корни будут получать влияние турбулентности.

Далее добавляется нода «Volume», чтобы создать воксельное поле.

post

Нода «Volume» Создание Volume с заданными характеристиками.

post

В параметрах указывается, что поле векторное, так как смещение задается в трёх осях Collated Rank — Vector. Имя поля устанавливается vel (velocity — поле скорости).

post

Для генерации турбулентности создаётся нода «Volume Velocity», которая добавляет к Volume вихревой шум (curl noise) и формирует векторное движение.

post

Нода «Volume Velocity» Добавление поля скорости (velocity) внутри Volume.

post

Чтобы визуально понять характер турбулентности, рядом создаётся нода «Grid» с высоким числом полигонов (Orientation — XY, Size — 100×100, Rows и Columns — 150).

После этого добавляется нода «Volume Trail», где первый вход — Grid, а второй — Volume Velocity.

Теперь при включении отображения этой ноды, можно менять в ранее созданной ноде «Volume Velocty» параметры шума и наблюдать, как они влияют на направление и интенсивность потока.

post

Нода «Volume Trail» Отображение velocity внутри Volume через точки.

Исходный размер 1920x810

Визуальное изменение параметров в ноде «Volume Velocity».

post

Далее создаётся нода «Convert VDB», чтобы преобразовать обычный Volume в формат VDB.

post

Нода «Convert VDB» Конвертация полей Volume в разные типы (в том числе VDB).

post

В параметрах указывается Convert to — VDB. Это необходимо для дальнейшей оптимизации.

post

После конвертации поле vel разделяется на три скалярных VDB (vel.x, vel.y, vel.z). Чтобы объединить их в одно векторное поле, используется нода «VDB Vector from Scalar».

post

Нода «VDB Vector from Scalar» Объединение нескольких скалярных (одно значение на воксель) VDB-полей в одно векторное (три значения на воксель).

Исходный размер 933x601

Объединение 3-х скалярных VDB полей (vel.x, vel.y, vel.z) в одно векторное vel с помощью ноды «VDB Vector from Scalar».

Симуляция

post

Следующий шаг — симуляция роста.

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

post

Внутри используется одна нода «Attribute Wrangle», работающая на уровне Points.

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

post

float base_step = chf («step»); float step = base_step * fit01(rand (@ptnum + @Frame), 0.2, 1.5); — chf («step») — установление значения параметра step. — rand (@ptnum + @Frame) — случайное число, зависящее от номера точки и времени (таким образом обеспечивается каждый раз новое число). — fit01(value, a, b) — преобразование диапазона 0–1 в диапазон a–b. — step случайно варьируется от 20% до 150% базового значения, что делает рост более естественным.

if (i@active == 1) {} — условие: если атрибут точки active равен 1, то она участвует в росте

vector dir = normalize (v@dir); vector vel = volumesamplev (1, «vel», @P); — v@dir — записанное ранее направление роста. — normalize () — нормализация вектора (приведение длины к 1 без изменения направления). — volumesamplev (input, field, position) — обращение к векторному значению из Volume. В данном случае считывается vel из второго входа.

post

vector n = set (    noise (@P25 + 0),    noise (@P25 + 1),    noise (@P*25 + 2)); — noise (pos) — создание шума Перлина (Perlin noise). — умножение позиции на 25 усиливает детализацию, а сложение дополнительных чисел исключает повторения шума. — таким образом создается 3D-вектор шума для добавления микроколебаний.

dir = normalize (lerp (dir, vel, 0.1)* n*25); dir = normalize (lerp ({0, -1,0}, dir, 0.95)); — lerp (a, b,t) — линейная интерполяция (промежуточное значение) между векторами. — первое смешивание: 90% исходного направления и 10% турбулентности, затем умножается на шум для добавления хаотичности роста. — второе смешивание: 95% текущего направления и 5% направление вниз {0, -1,0}, чтобы корни не росли наверх.

post

vector newP = @P + dir * step; int newpt = addpoint (0, newP); — создание атрибута позиции новой точки на расстоянии step по направлению dir. — addpoint (0, pos) — добавление точки в геометрию на входе 0.

int prim = addprim (0, «polyline»); addvertex (0, prim, @ptnum); addvertex (0, prim, newpt); — создание примитива типа polyline. — добавление к примитиву двух вершин: текущая и новая точка. Так формируется новый сегмент корня.

setpointattrib (0, «dir», newpt, dir, «set»); setpointattrib (0, «active», newpt, 1, «set»); i@active = 0; f@width = 0.1; — добавление атрибутов новой точке: dir — своё направление роста, active = 1 — в следующем цикле рост идет уже от нее. — добавление атрибутов текущей точке: active = 0 — больше не участвует в росте, width = 0.1 — назначение начальной толщины.

post

if (rand (@Frame + @ptnum + 25) < 0.02) {} — добавление возможности ветвление (создания дополнительного корня) — установление условия: вероятность ветвления — 2% (rand (…) для стабильной случайности).

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

f@width = min (f@width + fit01(rand (@ptnum + @Frame*0.1), 0.05, 0.25), 10.0); — width для всех точек увеличивается каждый кадр на случайное значение от 0.05 до 0.25. — min (…, 10) — ограничение толщины сверху до 10.

С помощью нажатия Creates spare parameters появляется атрибут step.

Исходный размер 2480x1080

Сравнение геометрии при разных значениях атрибута step.

Исходный размер 1920x810

Итоговая симуляция после операций в Solver.

post

Операции внутри Solver закончены. Так как результат — это полилиния без объёма, то необходимо придать толщину. Для этого добавляется нода «PolyWire».

post

Нода «PolyWire» Создание полигональной трубы вдоль линий.

post

В параметре Wire Radius задаётся толщина кривой. Здесь используется атрибут width, который формирует градиент толщины: более широкое основание и постепенно сужающиеся концы. Для этого применяется выражение:

fit (@width, 0, 10, 1, 10) / 500 — fit (value, omin, omax, nmin, nmax) — перерасчет диапазона значений. В данном случае это избавляет от нулевого значения, где отсутствует толщина. — деление на 500 уменьшает итоговый масштаб (можно изменять для уточнения итоговой толщины).

Покрас

Последний шаг — добавление цвета.

Для этого используется отдельный уровень обработки геометрии — VOP.

VOP (VEX Operators) — это нодовая альтернатива написанию VEX-кода вручную, позволяет выполнять те же операции над атрибутами, но в визуальной среде, собирая логику из блоков-нод.

post

В Tab Menu существует несколько разновидностей VOP-нод, различающихся тем, на каком уровне геометрии они работают, но принцип у всех одинаков.

post

При двойном клике ЛКМ по ноде открывается её внутренняя сеть: — Global Attributes — входящие атрибуты геометрии; — Output — выходные значения, которые вернутся обратно в сеть.

Между ними размещаются VOP-ноды и строится цепочка операций: математические функции, шумы, смешивание значений и любые другие вычисления.

post

В данном проекте используется нода «Attribute VOP», так как она позволяет напрямую работать с атрибутами.

post

Нода «Attribute VOP» Запуск сети VOP для изменения атрибутов геометрии.

Внутри сначала создается нода «Bind», с помощью которой происходит обращение к атрибуту width.

post

VOP нода «Bind» Импорт существующего атрибута геометрии или создание нового.

post

В параметрах в качестве имени указывается width, тип данных остаётся float.

post

Затем добавляется нода «Fit Range», чтобы перенастроить диапазон значений и преобразовать его в удобный интервал для окраски. Выход сразу подключается к атрибуту Cd, чтобы значения отображались как цвет.

post

VOP нода «Fit Range» Преобразование входного значения из одного диапазона в другой, масштабируя его по заданным пределам.

Исходный размер 1920x965

Сравнение различных значений минимального и максимального значения входящего атрибута в ноде «Fit Range».

post

После этого добавляется нода «Ramp Parameter», позволяющая преобразовать градиент в цветовой переход.

post

VOP нода «Ramp Parameter» Создание градиента, по которому можно визуально преобразовывать входные значения в цвет или другие параметры.

Изменение цветов выполняется уже на верхнем уровне: после выхода из VOP нужно открыть параметры Attribute VOP и настроить градиент вручную.

Исходный размер 1920x810

Процесс покраса через VOP ноду «Ramp Parameter» (выводится на ноду «Attribute VOP»).

Исходный размер 1920x810

Итоговый флипбук.

Loading...

3.3. Рост грибов

Задача последнего практического раздела — воспроизвести процесс роста древесного гриба, формирующегося слоями вдоль поверхности.

Исходный размер 1920x810

Референс роста кристаллов и композиционного решения.

Исследование природных образцов показывает, что такие грибы развиваются радиально: из центральной точки появляется первый тонкий слой, после чего структура постепенно расширяется, образуя характерные волнистые «полки». Рост происходит неравномерно, одни участки формируются быстрее, другие задерживаются или искривляются под влиянием среды. Опора на эти закономерности позволяет сформировать реалистичную форму гриба.

Исходный размер 2480x2002

Схема проекта с системой роста грибов.

Начальная геометрия

post

Самый первый шаг — создание начальной геометрии.

Для этого добавляется нода «Sphere» (тип Polygon) с параметрами Radius — 0.5, 0.15, 0.5; Uniform Scale — 2; Frequency — 16. (можно менять для поиска подходящей формы).

Затем добавляется нода «Mountain», где настраивается шум через основные параметры Amplitude, Element Size и Offset для получения неровной формы, подходящей для неравномерного роста в дальнейшем.

Результат выводится через ноду «Null», названную OUT_GEO.

Исходный размер 1920x711

Начальная геометрия.

Volume-поле

post

Второй шаг — конвертирование геометрии в Volume.

Для это создается нода «VDB From Polygons».

post

Нода «VDB from Polygons» Преобразование полигональной геометрии в VDB.

post

Параметр Voxel Size определяет детализацию объекта: чем ниже значение, тем выше плотность вокселей. В данном случае установлено значение 0.03.

Исходный размер 1920x636

Сравнение уровня детализации при изменении параметра Voxel Size.

post

Далее добавляется нода «VDB Smooth», мягко сглаживающая границы объёма.

post

Нода «VDB Smooth» Сглаживание значений VDB.

Исходный размер 1920x534

Сравнение VDB без сглаживания и с ним через ноду «VDB Smooth».

post

В конце результат вычисленного Volume-поля выводится на ноду «Null» с именем OUT_SOURCE.

Поле турбулентности

post

Третий шаг — формирование векторного поля для искажения объема.

Основой служит готовая ветка OUT_VEL из пункта 3.2, но с несколькими изменениями.

  1. Размеры куба в ноде «Box» уменьшаются до 6×6×6;
  2. После ноды Volume добавляется «Volume Wrangle» с кодом, в котором задается направление velocity так, чтобы оно расходилось от центральной точки наружу, что имитирует естественный рост структуры:

v@vel = normalize (@P — {0, 0, 0});

Исходный размер 1354x616

Направление velocity: движение идет из центра к краям.

  1. Изменяются параметры ноды «Volume Velocity», чтобы задать характер турбулентности.
Исходный размер 1920x810

Изменение параметров турбулентности в ноде «Volume Velocity».

Симуляция

post

Следующий шаг — симуляция.

Создаётся нода «Solver». В первый вход подключается OUT_SOURCE, во второй — OUT_VEL.

post

Внутри Solver между нодами Prev_Frame и Output вставляется нода «VDB Renormalize SDF», стабилизирующая расстояние в объёме.

post

Нода «VDB Renormalize SDF» Стабилизация значений расстояний внутри поля для корректировки.

post

Добавляются две ноды «VDB Analysis», создающие дополнительные поля: curvature и gradient.

post

Нода «VDB Analysis» Вычисление свойств VDB (например, кривизну или градиент) с последующим созданием новых полей.

Исходный размер 1920x534

Визуальное представление полей curvature (float) и gradient (vector).

post

Первая нода настраивается под curvature (кривизна, то есть то, насколько сильно изгибается поверхность).

В параметрах устанавливается Operator — Curvature, Output Name — Custom name, Custom name — curvature.

post

Вторая нода настраивается под gradient (градиент поля, то есть направление роста плотности)

В параметрах устанавливается Operator — Gradient, Output Name — Custom name, Custom name — grad.

post

Созданные поля объединяются через ноду «Merge».

Затем подключаются в ноду «Volume VOP». Второй вход соединён с полем турбулентности (Input_2).

post

Нода «Volume VOP» Запуск сети VOP для изменения полей Volume.

post

Внутри ноды, в первую очередь, необходимо обратиться к velocity из поля турбулентности.

Для этого используется нода «Volume Sample Vector», где к filaname подключается OpInput 2, а к samplepos — P.

post

VOP нода «Volume Sample Vector» Обращение к векторным значениям из указанного Volume-поля.

post

В параметрах Signature указывается Primitive Name, а в аналогичном Primitive Name — vel.

post

Далее значение нормализуется через ноду «Normalize».

Затем всё подаётся в ноду «Multiply» для дальнейшего смешивания.

post

VOP нода «Multiply» Умножение входных значений.

post

Следующее, что необходимо сделать — обратиться к атрибуту grad.

Создается нода «Bind» с параметрами Name — grad, Type — 3 floats (vector).

Значение нормализуется через ноду «Normalize».

И также подаётся в ноду «Multiply».

post

Последний атрибут, необходимый к обращению, — это curvature.

Аналогично создаётся «Bind » с параметрами Name — grad, Type — 3 floats (vector).

Через связку нод «Fit Range—Ramp Parameter» кривизна преобразуется в управляемый диапазон.

Таких связок необходимо сделать две: одна поступает в Multiply с атрибутом vel, другая — в Multiply с атрибутом grad.

Параметры srcmin и srcmax в обеих нодах «Fit Range», а также 3-и входы в обеих «Multiply» выносятся наружу через Promote Parameter, чтобы изолированно иметь доступ к настройкам на верхнем уровне. Для этого необходимо зажать колесиком на параметре.

Исходный размер 1920x810

Вынесение параметра из VOP через Promote Parameter.

После этого этим параметрам даются названия: нужно нажать на появившуюся закладку и в Label дать соответствующее название (можно отталкиваться от приложенной схемы).

Аналогично необходимо задать названия для градиентов в параметре Name в каждой ноде «Ramp Parameter».

Исходный размер 1920x810

Переименование вынесенного параметра.

Исходный размер 1097x695

Схема названий параметров, выведенных наружу.

Финальные значения из «Multiply» объединяются с помощью ноды «Add».

post

VOP нода «Add» Сложение входных значений.

Таким образом, сетап позволяет управлять направлением «выдавливания» поверхности:

— grad определяет базовое направление, в котором поверхность может расширяться; — curvature задаёт, какие зоны будут реагировать сильнее или слабее; — vel добавляет хаотичную турбулентную составляющую.

Каждое влияние можно гибко настраивать, усиливать или ослаблять каждый компонент.

В итоге итоговый вектор grad определяет, какие области VDB будут выдавливаться при симуляции.

Этот атрибут необходимо экспортировать через ноду «Bind Export» в атрибут grad (Name — grad, Type — 3 floats).

post

VOP нода «Bind Export» Экспорт атрибута из уровня VOP.

Исходный размер 1209x695

Итоговая нодовая структура внутри ноды «Volume VOP».

post

После выхода из уровня VOP добавляется нода «VDB Advect», выполняющая деформацию объёма. Первый вход — результат ноды «VDB Renormalize SDF», второй — «Volume VOP».

post

Нода «VDB Advect» Перемещение значений VDB относительно поля velocity.

post

В параметрах ноды в Group указывается @name=surface, а в Velocity — @name=grad (так как оно является деформирующим полем).

Теперь можно запустить Solver и увидеть, как происходит рост.

При изменении параметров ноды «Volume VOP», которые были вынесены наружу, можно получить совсем разные результаты.

Исходный размер 3000x810

Сравнение результатов изменения значений параметров в ноде «Volume VOP».

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

Исходный размер 1920x810

Параметры в ноде «Volume VOP» для симуляции наиболее естественного результата.

Покрас

post

Последний шаг — покрас. Он происходит на основе VDB-поля curvature.

Первоначально необходимо превратить VDB-поле в геометрию. Для этого создается нода «Convert VDB», в параметрах устанавливается Convert To — Polygons.

Исходный размер 1920x695

Преобразование VDB-поля в полигоны с помощью ноды «Convert VDB».

post

Далее также от Solver необходимо добавить ноду «VDB Analysis» и в параметре Operator выбрать Curvature.

Для небольшого смягчения значений можно добавить ноду «VDB Smooth» и установить параметр Iteration в районе 2-4.

В конце всё подключается к ноде «Attribute VOP»: «Convert VDB» — к 1-му входу, а «VDB Smooth» — ко 2-му.

post

Внутри VOP импортируется VDB-поле через ноду «Volume Sample Vector». P подключается к samplepos, OpInput2 — filename.

Далее добавляется связка «Fit Range-Ramp Parameter» и все подключается к атрибуту Cd. Можно изменить параметры Source Min и Source Max в ноде «Fit Range» (например, {-10, -10, -10) и {5, 5, 5} соответственно), а также добавить градиент цвета в «Ramp Parameter».

Исходный размер 1920x810

Итоговый флипбук.

Loading...
Библиография
1.

Houdini [Электронный ресурс] // SideFX. — URL: https://www.sidefx.com/docs/houdini/index.html (дата обращения: 21.11.2025).

Источники изображений
1.

Фантастические Грибы (Fantastic Fungi, реж. Луи Шварцберг, 2019)

2.3.4.

https://www.youtube.com/shorts/T7ZZHO6gsAg (дата посещения 29.11.2025)

5.

https://www.youtube.com/shorts/s5OIwtf12YM (дата посещения 29.11.2025)

3. Практическая часть
Проект создан 01.12.2025
Глава:
1
2
3
4
5
Мы используем файлы cookies для улучшения работы сайта и большего удобства его использования. Более подробную информац...
Показать больше