Particle Flow Tools: Box#3:Часть 2

Во второй части урока мы рассмотрим новые субоператоры и типы данных.

(Первая часть урока тут)

1. Switch - представляет собой вспомагательный субоператор, позволяющий пользователю выбирать, какая ветка субоператоров будет включена. В прошлом уроке мы создавали оператор, который удаляет партиклы внутри или снаружи обьекта. Вместо того, чтобы создавать два оператора для каждого случая, сделаем по другому (рис.1а)

Добавляем Switch субоператор в нем выбираем Type - Boolean.Затем жмем Add Input, в нем вводим имя по которому будем выбирать из списка. Т.к. как у нас два варианта добавляем два значения : Delete Inside и Delete Outside.На один вход подается значение прямо из Geometry (Inside Objects) субоператора , на второй значение обратное.(Для этого добавим Function субоператор и установим значение Function в Not B1).

Теперь можно вынести это значение через Expose Parameters и у нас появится выпадающее меню (рис. 1б) в котором можно выбрать нужный нам тип удаления (Как вариант можно использовать Check Box (если входа два то вExpose Parameters станет доступна опция Show As Check Box )) .

2.Тестовая сцена.

2.1.Создаем Plane в центре координат с размерами 250x250.

2.2.Жмем клавишу 6. Создаем два Standard Flow далее PF1 и PF2.

В PF1:

2.3.Birth оператор : Emit Start: 0 ; Emit Stop:0. Amount :1500. - все партиклы появятся в 0 кадре.

2.4.Position Icon удаляем вместо него добавляем Position Object:в Emitter objects нажимаем Add и добавляем наш Plane.Ставим галочку Separation -->Distance = 3(чтобы партиклы не наслаивались друг на друга).

2.5.Speed и Rotation удаляем.

2.6.В Shape операторе ставим Size=3, 3D:Cube. В Display операторе выбираем Type:Geometry.

2.7.Жмем на заголовок с надписью PF Source 001 и в Quantity Multiplayer-->Viewport %--> ставим вместо 50% - 100% , ( Это надо всегда проверять , чтобы во вьюпорте у нас отображались все партиклы.)

В PF2:

2.8. Перемещаем иконку к краю Plane и поворачиваем, чтобы испускание частиц было над плоскостью.

2.9. Birth оператор : Emit Start: 0 ; Emit Stop:100. Amount :1.

2.10. Rotation удаляем. Speed уменьшаем до 100.

Повторяем пункты 2.6-2.7.

Сцена должна выглядеть примерно так (рис.2)

3. Перейдем к Box#3

Input Proxy субоператор позволяет нам получать данные с другой Pflow системы.В нашем случае мы свяжем PF1 и PF2.

Для этого добавляем Data Operator в PF1 под Shape оператор и переименовываем его в "Proxy". Ставим галочку Auto Update. И нажимаем Edit Data Flow.(рис.3.1.а)

В окне субоператоров добавляем субоператор Input Proxy (3.1б).Его св-ва очень сходны с Input Standard субоператором.

На входе субоператор просит тип данных "O" т.е. обьект. Добавляем Select Object жмем "None " и выбираем PF Source 002. Cоединяем с Input Proxy. Такой вариант можно использовать для получения данных от любой PFlowсистемы в сцене.(рис.4.1.а)

 

4. Particles субоператор позволяет взаимодействовать партиклам между собой. При этом каждый партикл ищет соседа в так называемой Surround Sphere (сфера окружения) .

4.1.Добавим Particles субоператор.Ставим галочку "Use O1 As Proxy Particles" появится вход "O" к нему подсоединим наш Input Proxy.

В Aggregated Particles выбираем тип "Closest Particles Index". Теперь наши партиклы PF1 будут получать данные об индексах партиклов PF2 попадающих в их сферу окружения. Размеры сферы окружения контролируются параметром Outer (рис.4.1б).

4.2. Теперь добавляем Input Standard субоператор , устанавливаем в Scale Z Component (Масштаб по Z координате).

Добавляем Scalar субоператор устанавливаем Value =0,2. Добавляем Function субоператор и выбираем Type -->Real.Соединяем с Input Standard и Scalar. Добавляем Output Standard, устанавливаем в Scale Z Component и содиняем с Function.

Теперь если прокрутить слайдер анимации партиклы будут увеличиваться на 0,2 по оси Z.(рис.4.2а)

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

Т.к. у нас только один партикл его индекс будет "0". Мы отфильтруем партиклы исходя из индекса.

Для этого добавляем Condition субоператор, выбираем Input Type --> Integer. В значение A: ставим -1. И соединяем выход с фильтром Function субопертора.

5. Shape Control.

Создадим что-то наподобие травинки с пивот внизу и двумя Bend модификаторами. В первом Angle:=0 ,Direction =0.Во втором Angle:=0 ,Direction =90. Пока она у нас стоит не согнувшаяся.(рис.5.1) .Назовем обьект "trava".

В PF1 удаляем Shape оператор. В субоператорах удаляем как на (рис. 5.1) ветку которая отвечала за масштаб по оси Z.

Добавляем Shape Control субоператор.Он работает как Shape Instance оператор т.е. заменяет партиклы на геометрию, но имеет одно интересное свойство. С его помощью можно получить доступ к параметрам модификаторов обьекта.

В свойствах жмем "None" и выбираем нашу травинку.Вращение травинок на данный момент хаотично, приведем их к вертикальному положению (рис. 5.2а)

Для этого создаем Input Standard и Output Standard в обоих выбираем Rotation Euler Angles (Углы вращения Эйлера).

Добавляем Function и Vector субоператоры. Vector является константой на выходе у него вектор.В Vector выбираем Euler Angles и подбираем значения для вертикального положения травы.У меня X=0, Y=-90, Z = 0.

Так как это начальное положение травы и нужно вычислять только один раз добавим Input Standard субоператор и установим в положение New in Event. (рис.5.2б) .Соединим его с фильтром Input Standard.

Сгрупируем субоператоры и назовем группу Initial Rotation.

Возвращаемся к Shape Control субоператору и нажимаем кнопку Add. Появится окно выбора параметра.Нас интересуют углы Bend модификаторов. Выбираем параметр Angle первого Bend модификатора, затем опять нажимаемAdd и выбираем Angle второго Bend модификатора.(рис.5.3а)

У нас появилось два входа Real в субоператор.(рис.5.3б)

 

Теперь сделаем генератор случайного поворота.

Для этого добавим два Random субоператора. Distribution выставим как Uniform(Он генерирует случайные числа между минимумом и максимумом.) И соединим с двумя Real входами Shape Control. Каждый из них соединим с дополнительным Input Standard (New in Event) иначе каждый кадр будут вычисляться новые значения. Поле выглядит теперь так.(рис.5.4)

Теперь возвращаемся к нашей оставшейся после кубиков Proxy ветке. Чтобы получить эффект влияния прокси партикла на траву сделаем простенькую цепочку наподобие Initial Rotation. Только вместо Vector субоператора добавляем Random.Сгруппируем их и назовем Proxy(рис.5.5)

Теперь трава шевелится возле красного партикла.

Видео #1-2

6.Разберем похожий вариант, но только будем контролировать Morpher модификатор.

Для этого делаем модель подсолнуха.Назовите ее "SunFlower ".Копируем ее и увеличиваем в размерах. Затем вторую модель делаем как морф цель к первой рис.6.

В Shape Control мы выделяем наш подсолнух и задаем ему случайное вращение. рис. 6.1.

Далее мы создаем Test Operator (называем "Test If Proxy Near")и в нем делаем Proxy ветку как и раньше. Теперь если в сферу окружения подсолнуха попадется красный партикл , подсолнух переходит в новый эвент. рис. 6.2.

В новом эвенте создаем Data Operator("Grow SunFlowers"). Добавляем Shape Control. В нем выбираем наш подсолнух и в Add - добавляем параметр контроля цели.

Добавляем Input Standard.В нем выбираем Time In Event (собственно для этого мы и переводили подсолнухи в новый эвент, чтобы обнулить этот параметр).

Добавляем Convert субоператор, чтобы перевести Time в Real и соединяем в входом Real. Все подсолнухи начинают расти как только попадают в новый эвент.

Видео #3

Примечание. По данной схеме можно контролировать уровень детализации (LoD). Камеру использовать как центр и в зависимости от расстояния партиклы будут менять количество сегментов или контролировать кол-воIteration в TurboSmooth, вариантов применений много.

 

7. Теперь разберем некоторые типы данных. Я думаю каждый заметил во многих операторах возле чисел стоит буква "E".Если ее нажать то у нас на входе появляется тип данных Equal (равный). C этим типом данных работает только один субоператор - Parameter.

Его удобно использовать например ,если нам нужно вынести через Expose Parameters Seed т.е. уникальность.или какие-то одинаковые данные (рис. 7.1.)

Тип данных Complex состоит из трех величин { Vector + Integer + Time }.

Создадим простую сцену.PF эмиттер размещаем над Plane.Испускает 100 партиклов с 0 до 100 кадров(.рис. 7.2.)

 

Добавим Data Test оператор (ставим галочку Auto Update нажимаем Expose Parameters). В окне субоператоров добавляем Select Object и выбираем наш Plane.Затем добавляем Geometry субоператор в нем выбираем Collision Point.(рис.7.3). Теперь у нас на выходе Complex тип данных. Vector - вектор точки столкновения , Integer - сложный индекс состоящий из индекса обьекта и индекса полигона, Time - время столкновения.

С помощью Convert субоператора мы можем получить доступ к любому из простых типов данных составляющих тип Complex.

Добавим Convert установим Complex --> Time. Чтобы отправить партиклы при столкновении в новый эвент сравним время столкновения с текущим временем (Absolute Time) и если они равны условие выполняется.

Во втором эвенте добавим оператор Speed --> Random Horizontal и Shape с 3D -->Sphere.

Как только партикл достигнет Plane он поменяет форму на сферу и будет разлетаться в разные стороны.(Рис 7.5.)

Обязательно посмотрите через Show Data как выглядят Complex данные.

С основной теорией все! 

Создаем три Point локатора размещаем примерно как на рисунке.

 

Далее создадим PFlow только для Mag1 , для Mag2 будет точно такая же система только с другим эммитером.Анимацию я закладывал в 250 кадров.

Создаем Standard Flow --> Birth Operator Emit Start =0, Emit End =250,Amount =250(для теста).Position , SpeedRotation удаляем.Display -->Geometry. (рис.8.1а)

8.1.Начальное положение.

Добавляем Data Operator под Birth Operator.Заходим в субоператоры , добавляем Select Object --> в нем выбираем Mag1.

Добавляем Object субоператор --> Object PIvot.Он нам выдает вектор положения пивота локатора Mag1.

Добавляем Output Standard -->Position Vector. И добавим Input Standard --> New In Event (положение нам нужно только один раз)Группируем или склеиваем и называем Initial Position.(рис.8.1б)

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

8.2. Движение к центру.

В этом же операторе добавляем опять Select Object - выбираем наш центральный локатор.Добавляем Object и в нем выбираем Object Local Coordinates. Это дает нам вектор от центра Center локатора к центру локатора Mag1. Этот вектор направлен в противоположную сторону от той которая нам нужна. Поэтому добавляем Function субоператор и устанавливаем его в Normalize (процесс нормализации - приведение вектора к Unit -единичному).Нормализация нам нужна, чтобы уменьшить величину вектора который мы передадим в вектор скорости партиклов.

Дополнительно в Post Factor установим равным "-0,05". Минус повернет вектор в обратную сторону , 0,05 уменьшит вектор т.к. даже после нормализации партиклы двигаются очень быстро.Теперь выводим вектор в скорость.

Добавляем Output Standard -->Speed Vector.(рис.8.2.)

Примечание. Если у вас партиклы возле Center локатора начинают выписывать какието сумасшедшие спирали сделайте ему reset Xform.

8.3.Теперь нужно сделать движение партиклов по функции Noise.

Добавляем еще один Function оператор. Добавляем Random субоператор в нем выбираем тип Vector , Distribution --> Noise V(рис 8.3)

Добавляем Convert субоператор.В нем ставим Real to Vector. Появятся три входа.

Добавляем Input Standard -->Particle Age. Выходными данными будет время. Конвертируем Time --> Real и сшиваем.(рис.8.3а )

Добавляем Scalar и называем его X offset. Соединяем как по рисунку.8.3б .(Партиклов можно добавить, чтобы линия была непрерывная.)

Крутим таймслайдер кривая получилась но она плохо двигается .

На рисунке 8.3в я приведу схему которая у меня получилась. Вы можете попробовать любые варианты. Я анимировал X,Y,Z offset вручную с Loop и Noise Float Controller. Пробуйте любые варианты и проверяйте как анимация выглядит во вьюпорте.

Сейчас оператор выглядит так.Переименуем Data Operator в "Noise Curve".

8.4. Партиклы при достижении центра Center локатора начинают крутится как мошки возле лампы.Лучше всего будет их удалить когда они рядом с локатором.

Добавляем Data test.

В субоператорах добавляем Select Object --> выбираем центральный локатор.Добавляем Object устанавливаем его в Object Pivot.

Добавляем Input Standard --> Position Vector. Добавляем Function ,выбираем Substraction X-Y.

Разница векторов положения центрального локатора и партиклов нам дает вектор между ними.Если мы найдем длину этого вектора мы получим расстояние между ними.(рис. 8.4а)

Добавляем еще один Function в нем снимаем галочку Use Second Operand, выбираем Length(V1). Теперь у нас есть расстояние.

Добавляем Condition в нем выбираем Is Less Then Value A . Число на ваше усмотрение я остановился на 5.

Далее добавляем Amount Change.В нем выбираем Type:Delete. Кнопку ставим в True To Delete. (рис. 8.4б)

Прокрутите таймслайдер теперь когда расстояние между партиклом и Center локатором меньше 5, он удаляется.

8.5. Используем это же расстояние для деления партиклов.

Добавляем Function, выбираем тип данных Real,.отключаем второй операнд, выбираем Inverse 1\X. Соединяем с Length. Это значение мы будем использовать для деления. Т.к. изначальная длина вектора довольно большая величиная путем инверсии мы ее уменьшим.Инверсия также поможет сделать так, что партиклы которые ближе к Center локатору будут иметь большее значение.

Добавляем Function выбираем тип данных Real, выбираем Multiplication. Добавляем Scalar и соединяем с ним(после инверсии значения будут небольшие и этот множитель будет контролировать величину деления).рис. 8.5а

Теперь вернемся в основное PFlow и сделаем второй эвент.Сначала добавим Gravity во вьюпорте. И добавим его в Force оператор.

Переименуем Data Test в "Spawn by Distance"(рис. 8.5б)

 

Еще важный момент. Если в сцене есть Amount Change и он служит для деления партиклов, лучше всего в PFlow включать в верхнем меню Options-->Track Update-->Particle Count

Возвращаемся к субоператорам. Добавляем Amount Change. Ставим Integer as Additive.В режиме Spawn он требует на входе Integer. Для это конвертируем Real в Integer.

Добавим Convert и соединяем с Amount Change.рис.8.5в

Если поменять наш Scalar гдето до 200 то при прокручивании слайдера анимации начнет жутко тормозить вьюпорт.

Если посмотреть в основное PFlow увидим, что во первых мы перешли лимит в 100 000 партиклов устанавливаемый по умолчанию, во вторых из-за того, что результаты деления партиклов тоже начинают делиться их общее число в сцене моментально увеличивается.Поэтому их сразу нужно отправлять в следующий эвент.(рис.8.5г)

Нажимаем на название PF Source 001 и в Particle Amount : Upper Limit добавим пару нулей к 100 000.

Теперь в окне субоператоров добавляем Output New. Тип данных выбираем Boolean. Этот поток данных нам нужен, чтобы те партиклы которые возникли в результате деления перешли в новый эвент.Назовем его " Spawn Product"

В Spawn Amount ставим галочку напротив Is Current Spawn нажимаем на None и выбираем Spawn Product.(рис. 8.5г.)

Далее создаем Input Custom и в нем выбираем наш Spawn Product. Добавляем Output Test и соединяем.(рис. 8.5д.)

У Spawn Product должен быть выше порядок выполнения Execution Order, иначе Amount Change не будет знать куда писать информацию.

Далее мы используем Spawn Product для вывода партиклов из эвента.

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

Это два общих принципа которые заложены в эффект.

Далее можно раскидывать партиклы по эвентам и дополнительно использовать информацию о расстоянии - например для возраста.

(рис. 8.5з.)

Далее я коротко опишу некоторые моменты. рис. 9

 

9.1.Сюда приходят все партиклы после деления. Split Amount переводит 50% из них в новый эвент. Оставшуюся часть Send Out отсылает в другой.

9.2. В этом эвенте партиклы по всей длине луча получают случайную скорость и падают вниз под действием Gravity силы. (В итоге на финальном рендере я его не использовал, но как вариант оставил.)

9.3 Это партиклы как на рис.8.5е разлетаются во все стороны и удаляются в зависимости от дистанции от Center локатора.

9.4. Это Data Test аналогичный Spawn by Distance только деление происходит на расстоянии 5-10 единиц от Center локатора.(С помощью Condition субоператора сравниваем значение расстояния и соединяем как фильтр соSpawn Amount).

9.5. Этот и следующий эвенты собраны только со стандартных операторов.Партиклы под действием Wind (нужно добавить его в сцену ) сдуваются назад к эмиттеру.Это придает дополнительный эффект сопротивления

9.6. Сюда приходит 5% партиклов из предыдущего эвента. Они падают вниз, возле центра столкновения под действием Gravity.

Для всех слоев я использовал ShapeCube3D. Размеры от 0,25 до 1.При рендере основной кривой(первый эвент) я увеличивал испускание до 5000 и ставил Integration Step - 8Ticks(чтобы кривая была более четкая). При рендере всех последующих эвентов я уменьшил кол-во до 750.

Композ в Нюке, на каждый слой добавлял Glow.

Результат

На этом с Box#3 все!Спасибо за внимание.

773 0 850 15
6
2011-07-23
Спасибо большое за урок, очень интересно:)
2011-07-25
[smile=05]
2011-07-31
Thanks! [smile=04]
2011-08-01
amazing!!!)))
2011-08-02
Здорово!
2011-08-16
Хороший урок
RENDER.RU