3. Практическая часть
После изучения различных методов работы с рекурсией можно переходить к практическим задачам.
В основе каждого проекта лежит использование ноды Solver, которая позволяет быстро создавать анимацию и объединять несколько подходов в одном процессе. Так, активно дополнительно применяются VEX и циклы For-Each.
Всё это позволяет комбинировать процедурные и симуляционные методы, создавая сложные формы и органические анимации.
3.1. Рост кристаллов
Первая практическая задача — создание системы процедурного роста кристаллов на выбранной поверхности.

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

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

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

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

Нода «Mountain» Смещение точек относительно их нормалей на основе фрактального шума.
Для изменения амплитуды смещения точек необходимо менять параметр Amplitude, для изменения размера шума воздействия — Element Size, для вариаций смещения — Offset.
Так, через подбор значений находится наиболее подходящая форма камня.
Изменения параметров ноды «Mountain».

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

Нода «Mask by Feature» Генерация маски на основе геометрических свойств (высота, кривизна, угол и т. д.).
Для удобства включается отображение маски. В параметре Direction выбирается направление вектора, который создает маску на поверхности. Красная зона — 1, синяя — 0.
Включение отображение маски и изменение направления вектора воздействия в ноде «Mask by Feature».

После создаётся нода «Attribute Wrangle», работающая на уровне Detail. Для отслеживания возраста процесса определяется integer атрибут age:
i@age = 0;
Этот атрибут должен быть создан заранее, чтобы Solver мог его обновлять.

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

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

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

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

Нода «PolyBevel» Создание закруглений вдоль эджей и углов.
Создание фаски через параметр Distance в ноде «PolyBevel».

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

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

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

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

Внутри создаётся нода «Attribute Wrangle», на уровне Detail. и помещается после Prev_Frame.
i@age += 1; — каждая новая итерация увеличивает общую переменную возраста на 1.
i@scatter = i@age * 2; — создание новой integer переменной scatter, которая отвечает за количество точек, на которые будут копироваться кристаллы: каждую новую итерацию их количество увеличивается в 2 раза.

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

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

В параметре 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 (окрашены в красный цвет).

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

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

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

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

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

Между частью Input_2-Copy_to_Points добавляется нода «Transform», для того чтобы настроить размер кристаллов: каждую новую итерацию геометрия уменьшается в два раза. В параметре Uniform Scale используется формула:
1 / (detail (»…/attribwrangle1», «age», 0) + 1) — detail (»…/attribwrangle1», «age», 0) — чтение значения detail-атрибута age из ноды attribwrangle1.
Так размер зависит от возраста: чем больше age, тем меньше размер кристаллов.

После копирования создаётся новая нода «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.

После этого создаётся третья нода «Attribute Wrangle», работающая на уровне Detail.
Во второй вход подключается 1-й Wrangle, чтобы обновить глобальный атрибут age на всей геометрии перед следующей итерацией. Для этого используется VEX-выражение:
i@age = detail (1, «age», 0);
Итоговая нодовая структура внутри Solver.
Симуляция в «Solver».
Появление кристаллов выглядит резким и неестественным: геометрия возникает в кадре без процесса роста. Потому необходимо отдельно анимировать постепенное увеличение каждого кристалла. Именно для этого заранее был создан атрибут cycle_num, который позволяет управлять масштабированием каждой отдельной геометрии.
Анимация роста

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

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

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

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

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

Так как каждая итерация роста имеет собственное значение атрибута cycle_num, появляется возможность поочередно масштабировать каждую итерацию, что создаёт эффект последовательного роста.
Для этого создаётся цикл For-Each Named Primitive, поскольку позволяет автоматически разбивать геометрию по значению атрибута.
В ноде «Block Begin» нажимается кнопка Create Meta Import Node. Она добавляет вспомогательную ноду с данными цикла. В данном случае, позже понадобится номер итерации из атрибута iteration.
Создание вспомогательной ноды цикла через ноду «Block Begin».

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

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

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

Внутри второго цикла создаётся нода «Transform».
Во вкладке Pivot Transform в поле Pivot Translate вводятся выражения $CEX, $CEY, $CEZ соответственно, чтобы опорная точка находилась в центре каждого кристалла.
Затем на параметр Uniform Scale устанавливаются ключи анимации: на 0 кадре значение 0, на 30 кадре — значение 1. Второй ключ можно ставить как раньше, так и позже — это изменяет скорость роста.
Создание ключей анимации на параметре Uniform Scale в ноде «Transform».

После второго цикла создаётся нода «TimeShift». В параметре Frame вводится выражение:
$F − detail (»…/foreach_begin2_metadata1/», «iteration», 0) * 3 — $F — текущий кадр таймлайна. — detail (…, «iteration», 0) — обращение к созданной meta ноде, чтение номера итерации. — *3 — задержка во времени.
Это позволяет сдвигать начало анимации каждой итерации кристаллов, основываясь на её номере.
Наконец, результат трансформации (выход второго цикла) соединяется с первым выходом ноды «Split» через ноду «Merge», что объединяет анимированные кристаллы с исходной статичной геометрией камня.
Итоговая нодовая структура части с анимацией.
Итоговый флипбук.
3.2. Рост корневой системы
Задача этого раздела — разработать систему роста корневой структуры, которая постепенно углубляется вниз и разветвляется в разные стороны.
Референс роста корней и композиционного решения.
Изучение биологических материалов показывает, что корни развиваются неравномерно: основной стержень движется вниз, постоянно изгибаясь и периодически разделяясь на несколько ответвлений. Кроме того, старые участки постепенно утолщаются. Обращение к такой системе позволяет достичь наиболее естественного результата.
Схема проекта с системой роста корней.
Начальная точка

Первый шаг — создание начальной точки.
Для этого добавляется нода «Add», и создается точка в нулевых координатах.
Далее создаётся нода «Attribute Wrangle», работающая на уровне Points. Внутри задаются основные атрибута, определяющие условия роста.

i@active = 1; — создание integer параметра active для обозначения активной точки, которая подвергается трансформации.
v@dir = {0, -1, 0}; — создание vector параметра dir для назначения базового направления, в данном случае рост идет вниз по оси Y.
f@width = 0.1; — создание float параметра width для обозначения начальной толщины, которая по мере цикла увеличивается.
Поле турбулентности
Второй шаг — создание поля турбулентности, которое будет искажать траекторию роста.
Для этого используется Volume с заданными параметрами турбулентности, который задает векторное поле смещения.
Volume (вольюм) — это поле данных, состоящее из трёхмерных пикселей — вокселей.
Сравнение полигональной модели и воксельного объёма при разных разрешениях (0.1 и 0.05).
В Houdini существует два типа Volume: — Standard Volume — плотная равномерная сетка, состоящая из всех вокселей, включая пустые области. — VDB — разреженная сетка, состоящая только из вокселей с данными, пустые области не записываются.
С точки зрения работы в нодовой сети принципиальной разницы между ними нет, оба типа используются примерно одинаково. В данном проекте выбран VDB, так как этот формат значительно экономит память и ускоряет вычисления.
Сравнение форматов хранения данных Standard Volume и VDB.

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

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

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

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

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

Чтобы визуально понять характер турбулентности, рядом создаётся нода «Grid» с высоким числом полигонов (Orientation — XY, Size — 100×100, Rows и Columns — 150).
После этого добавляется нода «Volume Trail», где первый вход — Grid, а второй — Volume Velocity.
Теперь при включении отображения этой ноды, можно менять в ранее созданной ноде «Volume Velocty» параметры шума и наблюдать, как они влияют на направление и интенсивность потока.

Нода «Volume Trail» Отображение velocity внутри Volume через точки.
Визуальное изменение параметров в ноде «Volume Velocity».

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

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

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

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

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

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

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

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 из второго входа.

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}, чтобы корни не росли наверх.

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 — назначение начальной толщины.

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.
Сравнение геометрии при разных значениях атрибута step.
Итоговая симуляция после операций в Solver.

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

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

В параметре Wire Radius задаётся толщина кривой. Здесь используется атрибут width, который формирует градиент толщины: более широкое основание и постепенно сужающиеся концы. Для этого применяется выражение:
fit (@width, 0, 10, 1, 10) / 500 — fit (value, omin, omax, nmin, nmax) — перерасчет диапазона значений. В данном случае это избавляет от нулевого значения, где отсутствует толщина. — деление на 500 уменьшает итоговый масштаб (можно изменять для уточнения итоговой толщины).
Покрас
Последний шаг — добавление цвета.
Для этого используется отдельный уровень обработки геометрии — VOP.
VOP (VEX Operators) — это нодовая альтернатива написанию VEX-кода вручную, позволяет выполнять те же операции над атрибутами, но в визуальной среде, собирая логику из блоков-нод.

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

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

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

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

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

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

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

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

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

VOP нода «Ramp Parameter» Создание градиента, по которому можно визуально преобразовывать входные значения в цвет или другие параметры.
Изменение цветов выполняется уже на верхнем уровне: после выхода из VOP нужно открыть параметры Attribute VOP и настроить градиент вручную.
Процесс покраса через VOP ноду «Ramp Parameter» (выводится на ноду «Attribute VOP»).
Итоговый флипбук.
3.3. Рост грибов
Задача последнего практического раздела — воспроизвести процесс роста древесного гриба, формирующегося слоями вдоль поверхности.
Референс роста кристаллов и композиционного решения.
Исследование природных образцов показывает, что такие грибы развиваются радиально: из центральной точки появляется первый тонкий слой, после чего структура постепенно расширяется, образуя характерные волнистые «полки». Рост происходит неравномерно, одни участки формируются быстрее, другие задерживаются или искривляются под влиянием среды. Опора на эти закономерности позволяет сформировать реалистичную форму гриба.
Схема проекта с системой роста грибов.
Начальная геометрия

Самый первый шаг — создание начальной геометрии.
Для этого добавляется нода «Sphere» (тип Polygon) с параметрами Radius — 0.5, 0.15, 0.5; Uniform Scale — 2; Frequency — 16. (можно менять для поиска подходящей формы).
Затем добавляется нода «Mountain», где настраивается шум через основные параметры Amplitude, Element Size и Offset для получения неровной формы, подходящей для неравномерного роста в дальнейшем.
Результат выводится через ноду «Null», названную OUT_GEO.
Начальная геометрия.
Volume-поле

Второй шаг — конвертирование геометрии в Volume.
Для это создается нода «VDB From Polygons».

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

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

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

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

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

Третий шаг — формирование векторного поля для искажения объема.
Основой служит готовая ветка OUT_VEL из пункта 3.2, но с несколькими изменениями.
- Размеры куба в ноде «Box» уменьшаются до 6×6×6;
- После ноды Volume добавляется «Volume Wrangle» с кодом, в котором задается направление velocity так, чтобы оно расходилось от центральной точки наружу, что имитирует естественный рост структуры:
v@vel = normalize (@P — {0, 0, 0});
Направление velocity: движение идет из центра к краям.
- Изменяются параметры ноды «Volume Velocity», чтобы задать характер турбулентности.
Изменение параметров турбулентности в ноде «Volume Velocity».
Симуляция

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

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

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

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

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

Первая нода настраивается под curvature (кривизна, то есть то, насколько сильно изгибается поверхность).
В параметрах устанавливается Operator — Curvature, Output Name — Custom name, Custom name — curvature.

Вторая нода настраивается под gradient (градиент поля, то есть направление роста плотности)
В параметрах устанавливается Operator — Gradient, Output Name — Custom name, Custom name — grad.

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

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

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

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

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

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

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

Следующее, что необходимо сделать — обратиться к атрибуту grad.
Создается нода «Bind» с параметрами Name — grad, Type — 3 floats (vector).
Значение нормализуется через ноду «Normalize».
И также подаётся в ноду «Multiply».

Последний атрибут, необходимый к обращению, — это curvature.
Аналогично создаётся «Bind » с параметрами Name — grad, Type — 3 floats (vector).
Через связку нод «Fit Range—Ramp Parameter» кривизна преобразуется в управляемый диапазон.
Таких связок необходимо сделать две: одна поступает в Multiply с атрибутом vel, другая — в Multiply с атрибутом grad.
Параметры srcmin и srcmax в обеих нодах «Fit Range», а также 3-и входы в обеих «Multiply» выносятся наружу через Promote Parameter, чтобы изолированно иметь доступ к настройкам на верхнем уровне. Для этого необходимо зажать колесиком на параметре.
Вынесение параметра из VOP через Promote Parameter.
После этого этим параметрам даются названия: нужно нажать на появившуюся закладку и в Label дать соответствующее название (можно отталкиваться от приложенной схемы).
Аналогично необходимо задать названия для градиентов в параметре Name в каждой ноде «Ramp Parameter».
Переименование вынесенного параметра.
Схема названий параметров, выведенных наружу.
Финальные значения из «Multiply» объединяются с помощью ноды «Add».

VOP нода «Add» Сложение входных значений.
Таким образом, сетап позволяет управлять направлением «выдавливания» поверхности:
— grad определяет базовое направление, в котором поверхность может расширяться; — curvature задаёт, какие зоны будут реагировать сильнее или слабее; — vel добавляет хаотичную турбулентную составляющую.
Каждое влияние можно гибко настраивать, усиливать или ослаблять каждый компонент.
В итоге итоговый вектор grad определяет, какие области VDB будут выдавливаться при симуляции.
Этот атрибут необходимо экспортировать через ноду «Bind Export» в атрибут grad (Name — grad, Type — 3 floats).

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

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

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

В параметрах ноды в Group указывается @name=surface, а в Velocity — @name=grad (так как оно является деформирующим полем).
Теперь можно запустить Solver и увидеть, как происходит рост.
При изменении параметров ноды «Volume VOP», которые были вынесены наружу, можно получить совсем разные результаты.
Сравнение результатов изменения значений параметров в ноде «Volume VOP».
В данном случае следующие настройки позволяют достичь естественный результат:
Параметры в ноде «Volume VOP» для симуляции наиболее естественного результата.
Покрас

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

Далее также от Solver необходимо добавить ноду «VDB Analysis» и в параметре Operator выбрать Curvature.
Для небольшого смягчения значений можно добавить ноду «VDB Smooth» и установить параметр Iteration в районе 2-4.
В конце всё подключается к ноде «Attribute VOP»: «Convert VDB» — к 1-му входу, а «VDB Smooth» — ко 2-му.

Внутри 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».
Итоговый флипбук.
Houdini [Электронный ресурс] // SideFX. — URL: https://www.sidefx.com/docs/houdini/index.html (дата обращения: 21.11.2025).
Фантастические Грибы (Fantastic Fungi, реж. Луи Шварцберг, 2019)
https://as2.ftcdn.net/jpg/04/51/74/53/1000_F_451745338_4G0coWeyknv233CK06jq4KD5i35kP3Hl.jpg (дата посещения 29.11.2025)
https://toadstool.ru/wp-content/uploads/2021/12/laesul3-768x609.jpg (дата посещения 29.11.2025)
https://www.youtube.com/shorts/T7ZZHO6gsAg (дата посещения 29.11.2025)
https://www.youtube.com/shorts/s5OIwtf12YM (дата посещения 29.11.2025)
