AlexHappy
Распределение листьев с помощью Particle Flow
AlexHappy 7007

  Всем привет! Сегодня хочу представить на ваш суд один из способов создания листвы (или массива других объектов) без пересечений с помощью встроенного в Макс генератора частиц – Particle Flow.

Итак… поехали!

1. Подготовка

Для начала я создал несколько вариаций листочков, ориентировав их по оси X и выставив Pivot в точку присоединения листа к ветке:

Так же у меня есть веточки (зелёные) дерева, на которых мы будем выращивать листву. Ещё я создал вспомогательную сферу, с помощью которой, на первом этапе, мы будем наблюдать поведение листьев в зависимости от направления нормали поверхности, на которой он вырос. А пока веточки можно скрыть.

2. Распределение листьев

Открываем Particle View (цифра 6 на клавиатуре) и перетягиваем Standard Flow в поле.

Заходим в настройки PF Source 001, ставим отображение частиц во вьюпорте и на рендере на 100%, Integration Step на половину кадра (Half Frame) или на 1/4, 1/8 – это увеличит качество просчёта пересечений, хотя в нашем случае это не так критично, т.к. не будет больших скоростей.

- Кликаем на Birth и делаем, чтобы все частицы рождались в 0 кадре (Emit Stop на 0). За количество частиц (листиков) будет отвечать параметр Amount.

- Мы хотим, чтобы частицы генерировались из нашего объекта, поэтому перетягиваем на место оператора Position Icon - оператор Position Object, где добавляем наш сферический объект. Так же ставим галочку на Separation со значением, близким к размеру листочков, чтобы они распределялись более равномерно – я поставил 5 см.

- Чтобы вектор скорости частиц был направлен по нормали к поверхности, заменяем оператор Speed на Speed by Surface, где выбираем наш объект. Значение скорости я пока поставил на 1 см.

- В настройках оператора Rotation выбираем Speed Space, чтобы наши листочки ориентировались по вектору скорости.

- Заменяем оператор Shape на Shape Instance, чтобы выбрать свою геометрию частиц. Предварительно надо сгруппировать все листики, а в настройках нажать галочку Group Members. Тут же, кстати, можно настроить размер листочков (Scale %) и его вариацию (Variation %).

- Чтобы во вьюпорте видеть не точки, на свою геометрию, в Display выбираем Type: Geometry.

Если сейчас проиграть анимацию, мы увидим, как листья, равномерно распределённые по поверхности сферы удаляются от неё с небольшой скоростью.

3. Располагаем листочки более горизонтально.

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

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

Добавляем под Speed By Surface, Data Operator, в его настройках ставим галочку Auto Update, чтобы видеть все изменения во вьюпорте и заходим в его редактор (Edit Data Flow).

- перетаскиваем Input Standard, выбираем там Speed: Z Component;

- добавляем число Scalar, скажем, 0,1 + можно добавить Variation;

- перетаскиваем Functions, выбираем Real единицы и функцию умножения;

- добавляем Output Standard и выбираем там Speed: Z Component;

Объединяем всё, как на схеме ниже:

Теперь наши листики стали более ориентированы по солнцу, т.к. вертикальная составляющая вектора скорости умножается на 0,1.

Схожим образом можно добавить ещё одну функцию, которая будет прибавлять к вертикальному вектору определённое число. Таким образом мы сможем регулировать вертикальный поворот всех листочков:

Обратите внимание, что мне пришлось уменьшить влияние этого коэффициента в функции.

Для удобства доступа к этим параметрам их можно вывести в настройки данного оператора через Expose Parameters…:

Я вывел коэффициент умножения и прибавления к Z компоненте вектора скорости, ну и переименовал сам оператор в ZComponent

4. Листочки тянутся к свету.

Следующим шагом я хочу сделать так, чтобы листики от центра дерева тянулись ближе к его краю, т.е. как бы тянулись к свету. В этом нам поможет более хитрый Data Operator.

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

Добавляем новый Data Operator над нашим ZComponent, ставим галочку Auto Update и заходим в его редактор.

Итак… исходными данными будут служить: вектор к нашему вспомогательному объекту, к каждому листочку и текущий вектор скорости.

Чтобы узнать вектор от центра дерева к листочку нужно из вектора положения листочка вычесть вектор до центра дерева.

- вытаскиваем Select Object и выбираем наш Dummy объект;

- вытаскиваем оператор Object и выбираем в нём Object Pivot (мы «построили» вектор к вспомогательному объекту);

- добавляем оператор Input Standard, Position: Vector (это вектора к каждому листочку);

- перетягиваем функцию вычитания векторов Function, Vector, Subtraction X-Y;

Теперь надо сложить наш вектор скорости объектов и вектор от центра дерева до каждого листочка:

- добавляем оператор Input Standard, Speed: Vector;

- добавляем функцию сложения векторов Function, Vector, Addition X+Y;

- вытаскиваем Output Standard, Speed: Vector (выводим все полученные значения в новый вектор скорости, т.е. направление листочков).

Общая схема представлена ниже. Обратите внимание, что с помощью коэффициентов Pre-Factor нужно добится оптимального влияния на направление листиков каждого из векторов (у меня это 0,001 и 1000,0):

Теперь, если перемещать вспомогательный объект, можно видеть, как листики как бы отворачиваются от него при этом влияние нормали поверхности сохраняется.

5. Переносим нашу модель на реальные веточки.

Для этого в операторах Position Object и Speed by Surface выбираем наши ветки, а сферу оттуда можно Remove. В Birth я увеличил число листиков (Amount) до 1000 штук:

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

6. Убираем пересечение между листиками.

Теперь, используя операторы с приставкой mP.., которые позволяют проводить расчёт столкновений частиц, попробуем избавиться от пересечений.

- под Shape Instance перетаскиваем mP Shape с параметрами Collide As: Convex Hill, Display As: Wireframe (создалась сетка,которая будет участвовать в расчёте столкновений);

- под него перетаскиваем mP World (чтобы расчёт заработал) и жмём кнопочку Create New Driver;

Если проиграть анимацию Вы увидете, как листочки, которые пересекались, разлетаются в разные стороны. Чтобы они не разлетались мы добавим вязкости среде:

- переносим оператор mP Drag, с галочками и высокими значениями Linear и Angular в Damping Factor (я поставил по 1000).

Теперь уже на первых кадрах пересекающиеся листики отодвигаются друг от друга и останавливаются.

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

7. Убираем пересечение листиков с ветками.

Следующим шагом я хочу попробовать убрать пересечения листьев и с ветками, на которых они растут. Для этого я создал копии веток и применил к ним модификатор Push со значением -0,2.

Затем назначим модификатор PFlow Collision Shape и нажмём кнопочку Activate.

В Particle View добавляем оператор mP Collision и указываем там наши объекты веток.

Теперь расчитывается пересечения и с нашими веточками, но, как показала практика.. далеко не везде :/ Если лист изначально был «проколот» веткой, то он остаётся на месте:

Теперь возникает вопрос.. Как много листиков таким методом можно одновременно просчитать? Видимо зависит от компьютера, но, к моему удивлению, всё достаточно шустро работает:

У меня на 1 000 листьев нет заметных тормозов.

5 000 листочков рассчиталось с небольшими тормозами.

На превью над 10 000 листиками без пересечений комп думал 30 секунд:

8. Сохраняем полученный результат в геометрию.

Ищем Mesher в Compound Objects, создаём объект в нулевых координатах и там выбираем нашу систему частиц:

Полученный объект конвертируем в Editable Poly и.. на этом всё!

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

Благодарю за внимание! Конструктивная критика и идеи только приветствуются!

Небольшое видео процесса создания листвы:

Комментарии (29)

+1
FunMaker
FunMaker
Спасибо!
+1
Герыч
Герыч
Великолепно!
+3
blackivan2008
blackivan2008
Сохраню в закладки, думаю пригодится. Спасибо.
+1
sander_alek
sander_alek
Очень полезная информация, спасибо!
+4
grdesigner
grdesigner
Отлично, схоронил.
+1
iolanta989
iolanta989
Спасибо, актуально
0
График
График
Здорово! Подскажите, сами ветки с помощью чего сделаны? Или вручную Edit Poly ?
+1
AlexHappy
AlexHappy
Ветки уже готовые взял, сделаны они были в Speed Tree.
0
График
График
Понял, благодарю
+4
Tmin
Tmin
Реалити!!! Не то что у многих ! )))
Один недочет.... Желательно на кончике каждой веточки тоже иметь листочек.
+2
AlexHappy
AlexHappy
Спасибо! Ну.. вообще можно заморочиться и сделать, отделив Cap веток и сгенерировав по ним листочки по нормали к поверхности. Оставим это для домашнего задания :)
+1
Tmin
Tmin
А пересечения? Для чистоты надо включать все в единый алгоритм.
+3
AlexHappy
AlexHappy
Всё это можно сделать, добавив ещё один источник частиц, а столкновения листиков объединить в другом событии.
Но это не точно..
0
gorbunkov
gorbunkov
Комментарий удален
+1
egor98
egor98
Новый урок...Класс.
+1
Jacot
Jacot
Рвения автора не могут не радовать !
+1
Arrow92
Arrow92
Спасибо) как раз искал такую тему)
+2
MpaKo6ec
MpaKo6ec
Воу-воу-воу, палехче!
Тут щас от векторов качаны-то полопаются:)
+1
AlexHappy
AlexHappy
Можете остановиться на втором шаге :)
+1
MpaKo6ec
MpaKo6ec
Я не себя имел ввиду)
+1
Prog
Prog
Я еще не начал читать, а у меня уже качан чувствую напрягся ))) Но ничего, я смогу!
+1
Motocat
Motocat
ого )) круто
+3
MastaMan
MastaMan
Отличное оформление и хорошая подача, все четко и по полочкам, текст читать приятно, плюс бонус видео в конце...
Вот как надо писать уроки. Спасибо.
+14
AlexHappy
AlexHappy
Первое правило морали гласит: "Делай другим уроки так, как хочешь, чтобы они делали тебе"
+8
kirillotron
kirillotron
Хочу заметить, что у PFlow есть ограничение на 5 млн. вертексов, так что если кто-то захочет таким способом сгенерировать листву на большом дереве целиком, для какого-то прям очень крупного кадра с нереальной детализацией, или вообще может что либо заскатерить через систему частиц, то в итоге мешер не сможет вам превратить в геометрию все партиклы. Сам сталкивался с подобной проблемой в свое время, поэтому заранее подумайте над тем, на какие куски порезать объект на котором будет происходить генерация.
+1
voronkoff
voronkoff
Круто, буду пробовать! Спасибо!
+1
JiminiCricket
JiminiCricket
всякая честь.... Good job... excellent...
У меня нет слов.... I have no words for this tutorial
Спасибо! Thanks
+1
ivanna
ivanna
Какой хороший урок,но для старых версий макса,похоже,не подходит. Что-то у меня в 12 максе и кнопочек таких нет(
0
AlexHappy
AlexHappy
Делал в 2014.