Удар молнии с VFX Graph

от автора

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

Перед началом:

  • Использована версия Unity 2022.3, должно работать на всех версиях выше 2020.2

  • Перед началом поставьте галочку в Preferences > Visual Effect > Experemental Operators/Blocks

  • Данные кривых будут указаны как «значение» = «точка х» или «промежуток от х до у». Вы можете использовать свои кривые, я даю их в основном для справки. Это не удобно для чтения, но способа лучше не нашлось.

  • Если значения кривой не указаны в каком-то промежутке, значит они свободно интерполируют между указанными точками.

Создаём следующий скелет:

Эффект будет состоять из Strip‘ов, так что добавляем все необходимые блоки в System. Создаём две первые переменные, они нам понадобятся в дальнейшем.

Добавляем Set custom attribute в Initialize, в инспекторе даём ему имя Progress. Устанавливаем атрибут при помощи оператора Get Attribute: spawnIndexInStrip (обычный spawnIndex даёт неверные значения) делённого на переменную PartAmount. Теперь в этом атрибуте хранятся числа в диапазоне от 0 до 1 в зависимости от положения на линии.

Добавляем Get Custom Attribute, в инспекторе указываем имя атрибута Progress, добавляем оператор Sample Bezier, добавляем Set Position.

Чтобы было удобнее размещать молнию на сцене, создаём четыре переменных для задания позиции кривой Безье, переводим позиции из local в world. Добавляем на GameObject с Visual Effect VFX Property Binder, соответствующим образом устанавливаем значения всех переменных как позиции других GameObject. Теперь мы можем контролировать форму и позицию кривой Безье прямо в редакторе меняя позиции указанных GameObject‘ов, избегая хардкодинга.

Промежуточный результат со значением Set Size = 0.05.

Промежуточный результат со значением Set Size = 0.05.

Теперь добавим оператор шума и необходимые для его контроля переменные. Быстро перечислю переменные и их значения: NoiseFrequency (2), NoiseOctaves (3), NoiseRoughness (0.5), NoisePower (0.1), MoveDelta

С добавлением шума.

С добавлением шума.

Однако, молния каждый раз одинаковая, поскольку шум детерминистический. К тому же, молния не двигается. В реальной жизни удар молнии состоит из двух этапов: 1) сначала молния движется сверху вниз и ветвится, 2) как только одна из ветвей достигает земли по ней проходит мощный той, происходит основная вспышка. Чтобы не перегружать эффект симуляцией ветвления и оставить туториал простым (к тому же, все кроме первой достигшей поверхности ветви должны быть тусклее основной), будем просто менять координаты шума в первую половину эффекта. После вспышки молния будет замирать и исчезать.

Добавляем новый кастомный атрибут MoveSpeed и устанавливаем его равным Total Time(Game). В Update также устанавливаем значение MoveSpeed = Delta Time(VFX) * Noise Speed * Sample Curve + MoveSpeed. Для T кривой используем Age Over Lifetime. Sample Curve равна 1 = от 0 до 0.5, 0 = от 0.6 до 1. Добавляем результат MoveSpeed к координатам шума. Кривая будет регулировать количество движения.

Добавляем HDR цвет (Мой равен R 3.08 G 7.12 B 22.6) (Чтобы HDR работал, добавьте в Post Procces Bloom). Умножаем цвет на кривую с T AgeOverLife равную 0.1 в промежутке от 0 до 0.5, 1 = от 0.6 до 0.8, и 0.4 = на координате 1.

Устанавливаем альфу тоже как кривую с таким же T, значения 0 = 0 до 0.1, 0.1 = 0.2, 0 = 0.3 до 0.5, 1 = 0.5 до 0.85, 0 = 1. Я также умножаю альфу на кривую использованную с NoisePower, чтобы скрыть острые края начала и конца молнии.

Получается уже довольно неплохо!

Получается уже довольно неплохо!

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

Для вспышки создаём простой (копеечный) Initialize Particle с Output Particle Quad. Настраиваем его по своему вкусу, здесь главное чтобы момент вспышки совпал с началом второй части молнии. Для удобства использования ассета я также нахожу центр между Pos1 и Pos2, и устанавливаю его в качестве координаты вспышки, а расстояние между этими точками использую для Scale по вертикали. Момент вспышки регулирую с помощью Curve 0 = 0 до 0.5, 1 = 0.6, 0 = 0.75 до 1.

Теперь, тёмная часть. Это будет декаль на поверхности, в которую ударяет молния. Всё просто, создаём партикль, поворачиваем его на -90 градусов по х, чтобы он проецировался на поверхность снизу. Для цвета использую Color2 (R 4.28 G 1.09 B 0) (понадобиться дальше) делённый на 4, а для альфы кривую 0 = 0 до 0.5, 0.6 = 0.6, 0 = 1.

Я дополнительно добавлю стилизованное перекрестье в нижней точке молнии + небольшие отлетающие частицы, чтобы передать импакт.

Единственный примечательный момент графа перекрестья состоит в том, что чтобы корректно повернуть Quad к камере, для угла z используется Camera.transform.angles.z + spawnIndex * 90 + 45. То есть, первая линия перекрестья появится под углом 45 градусов к камере (spawnIndex считает с нуля), а вторая линия под углом 135.

Для разлетающихся частиц располагаем их на сфере в Initialize, а в Update добавляем Conforn To Sphere Attraction Force относительно сферы с большим радиусом (или же отрицательный Attraction Force для сферы (или точки) меньшего диаметра).

Итого

Итого

Итого мы имеем ассет, который имеет:

  • Удобные якоря GameObject для расположения на сцене.

  • Форму мелких неровностей, которая условно случайная.

  • Баланс контраста.

  • Ощущение импакта.


ссылка на оригинал статьи https://habr.com/ru/articles/771226/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *