Анимация с помощью шейдера в Unity

В последнее время я работал над эффектом возрождения главного героя в моей игре King, Witch and Dragon. Для этого мне понадобилась пара сотен анимированных крыс.

В закладки
Слушать

Создавать на сцене несколько сотен Skinned Mesh со скелетной анимацией ради одного эффекта крайне нецелесообразно, поэтому я решил использовать систему частиц (или «партиклов»). Для этого пришлось прибегнуть к альтернативному способу анимации.

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

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

Анимация, которую я собираюсь детально разобрать, выглядит так:

Подготовка

Для начала я сделал в Blender низкополигональную модель крысы.

Для разделения модели на разные «зоны» (туловище, лапы, хвост) я использовал UV-координаты vertex. Поэтому развёртка у модели немного специфичная.

Основное движение крысы — это волнообразные прыжки. Чтобы все vertex анимировались плавно и синхронно, нам надо расположить всё тело крысы параллельно одной из UV-осей. Для удобства я разместил её вдоль оси U (она же X).

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

Хвост занимает всю левую половину развёртки (координаты U от 0,0 до 0,5). Это будет наша маска для анимации хвоста.

Лапы занимают всю нижнюю половину развёртки (координаты V от 0,0 до 0,4). Это маска для анимации лап. При этом лапы сжаты по горизонтальной оси U, чтобы избежать деформации. Так как я использую cel-shading и заливку цветом без детализированной текстуры, в моём случае это не проблема.

На основе этой развёртки я нарисовал diffuse-текстуру. Теперь можно приступать к работе над шейдером.

FBX-модель крысы с развёрткой и diffuse-текстуру можно скачать отсюда.

Создаём шейдер

Для наглядности я сначала соберу шейдер в нодовом Shader Graph, а потом покажу его текстовую версию.

Создаём Unlit Graph, в качестве Preview выбираем Custom Mesh и выбираем нашу модель крысы.

Применяем текстуру

Создаём параметр Texture 2D, который будет нашей основной текстурой. Создаём ноду Sample Texture 2D, в качестве текстуры задаём наш параметр и подсоединяем ноду к полю Color нашей мастер ноды.

Далее мы будем работать только с vertex модели.

Основное волнообразное движение

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

  • Jump Amplitude — как высоко будет прыгать крыса;
  • Jump Frequency — как часто она будет это делать;
  • Jump Speed — как быстро будет происходить вертикальное смещение.

2 основных ноды, которые позволят нам создать движение, это Time и UV. Для UV мы будем использовать каждую ось по отельности, поэтому мы подсоединим её к ноде Split, которая даст нам доступ к каждому каналу по отдельности.

Умножив ноду Time на параметр Jump Speed мы сможем контролировать с какой скоростью будет смещаться наша синусоидальная функция и, соответственно, с какой скоростью будет меняться вертикальное смещение vertex’ов.

Умножив горизонтальную составляющую UV на параметр Jump Frequency, мы сможем контролировать сжатие и растяжение синусоидальной функции, а значит, как часто будет прыгать наша крыса.

Сложив эти 2 произведения и подсоединив результат к ноде Sin, мы получим желаемую форму синусоидальной волны. По умолчанию функция принимает значения между -1.0 и 1.0, поэтому, если мы помножим нашу функцию на параметр Jump Amplitude, мы получим желаемую траекторию.

Теперь нужно применить результат к положению vertex, но сделать это нужно только для вертикальной составляющей. Поэтому мы возьмём ноду Position, разделим её на компоненты с помощью ноды Split, добавим значение, полученное из синусоидальной функции к вертикальной компоненте, и соберем обратно, с помощью ноды Combine. После этого подсоединяем результат к Vertex Position нашей мастер-ноды.

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

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

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

Сверху - нормальные значения синуса, снизу - абсолютные

Добавляем ноду в наш граф.

Теперь анимация крысы выглядит так.

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

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

Сверху - абсолютное значение синуса, в середине - смещённое по оси Y, снизу - максимальное значение между синусом и нулём

Чтобы реализовать это, добавим ещё один параметр Jump Vertical Offset, который позволит нам регулировать, насколько смещать вниз нашу функцию.

Граф теперь выглядит так.

Крыса теперь остаётся некоторое время на земле перед прыжком.

Дополнительное движение хвоста

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

Для этого мы будем использовать заранее подготовленную UV-развёртку в качестве маски, чтобы отделить движение хвоста от остального тела.

Мы знаем, что хвост занимает левую половину UV-развёртки, поэтому давайте создадим плавный градиент от значения 0,0 до 0,5 по горизонтали. Можно даже сделать до значения 0,6, чтобы сделать переход от тела к хвосту более плавным. В значении 0,0 будет белый цвет, в значении 0,6 и далее — чёрный. Чем светлее пиксель на градиенте, тем сильнее будет эффект. Значит, кончик хвоста будет подвержен дополнительному движению сильнее всего и этот эффект будет постепенно уменьшаться, приближаясь к туловищу.

Мы будет использовать ноду Smooth Step с горизонтальной компонентой UV в качестве in-значения.

Также нам понадобится параметр Tail Extra Swing, который будет определять насколько сильно крыса будет вилять хвостом.

Умножив значение, полученное от Smooth Step функции на этот новый параметр, мы получим распределение дополнительного смещения по длине хвоста. Добавив его к общей Jump Amplitude, мы получим финальное движение тела, с учётом дополнительного взмаха хвостом.

Теперь движение хвоста крысы стало более заметно (значение параметра Tail Extra Swing = 0,3):

Движение лап

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

  • Legs Amplitude — насколько сильно вперёд и назад будут смещаться лапы;
  • Legs Frequency — как часто они это будут делать.

Параметр Legs Speed нам не нужен, потому что движение лап должно быть синхронизировано с прыжками, поэтому мы будем использовать Jump Speed. Единственный нюанс в том, что так как мы используем абсолютное значение синуса, за один цикл совершается два прыжка, поэтому для лап мы будем использовать Jump Speed * 2.

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

Значение Legs Frequency надо подобрать таким образом, чтобы когда передние лапы движутся вперёд, задние лапы двигались бы назад и наоборот. Опытным путём я выбрал значение 10.

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

Для этого мы снова будем использовать ноду Smooth Step, но теперь в качестве in-параметра будем использовать вертикальную ось UV-развёртки. Обозначим градиент между значениями 0,1 и 0,4.

Почему 0,1 а не 0,0? Чтобы не деформировались стопы, которые находятся в нижней части развёртки. Для всех vertex, находящихся ниже уровня 0,1, смещение будет одинаковым.

Давайте теперь добавим полученное значение к Z-координате vertex (продольная ось), временно отключим движение туловища и посмотрим на изолированное движение лап.

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

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

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

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

Подобрав нужное значение фазового смещения (в моём случае -1,0), получаем такую анимацию.

И с нормальной скоростью.

Финальный граф целиком.

Текстовая версия шейдера

Для тех, кто ещё не перешёл на URP/HDRP в Unity или просто предпочитает писать шейдеры в текстовом редакторе, вот текстовая версия того, что мы только что сделали.

Shader "Unlit/Rat" { Properties { _JumpSpeed("Jump Speed", float) = 10 _JumpAmplitude("Jump Amplitude", float) = 0.18 _JumpFrequency("Jump Frequency", float) = 2 _JumpVerticalOffset("Jump Vertical Offset", float) = 0.33 _TailExtraSwing("Tail Extra Swing", float) = 0.15 _LegsAmplitude("Legs Amplitude", float) = 0.10 _LegsFrequency("Legs Frequency", float) = 10 _LegsPhaseOffset("Legs Phase Offset", float) = -1 [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; float4 _MainTex_ST; half _JumpSpeed; half _JumpAmplitude; half _JumpFrequency; half _JumpVerticalOffset; half _TailExtraSwing; half _LegsAmplitude; half _LegsFrequency; half _LegsPhaseOffset; v2f vert (appdata v) { float bodyPos = max((abs(sin(_Time.y * _JumpSpeed + v.uv.x * _JumpFrequency)) - _JumpVerticalOffset), 0); float tailMask = smoothstep(0.6, 0.0, v.uv.x) * _TailExtraSwing + _JumpAmplitude; bodyPos *= tailMask; v.vertex.y += bodyPos; float legsPos = sin(_Time.y * _JumpSpeed * 2 + _LegsPhaseOffset + v.uv.x * _LegsFrequency) * _LegsAmplitude; float legsMask = smoothstep(0.4, 0.1, v.uv.y); legsPos *= legsMask; v.vertex.z += legsPos; v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG } } }

Сложности с системой частиц

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

Этот шейдер рассчитан на работу в Object space (локальном пространстве объекта). Если вы назначите его на GameObject, всё будет работать отлично. Но если назначить его системе частиц, начнутся артефакты.

Насколько я знаю (тут могу ошибаться), раньше партиклы в системе частиц тоже работали в локальном пространстве, но несколько версий назад их перевели в World Space, чтобы они батчились с целью экономии ресурсов. Поэтому прибавление значений к координатам Y и Z будет смещать vertex в мировом пространстве, соответственно все они будут смещаться в одном и том же направлении, независимо от поворота крысы.

Чтобы решить эту проблему я использовал 2 Custom Vertex Stream в системе частиц и передавал туда из скрипта значения up-vector и forward-vector для каждой частицы. Первый учитывался для рассчета направления смещения тела во время анимации прыжка, второй для направления смещения лап.

Заключение

Мы создали 2 версии шейдера, который позволяет анимировать крысу без использования скелета и keyframe-анимации.

Такие анимации подойдут для фоновых и декоративных объектов, которые не являются основным фокусом внимания, но добавляют картинке живости и динамики.

Используя показанные техники можно анимировать различных простых существ, особенно если их должно быть много (косяк рыб, стая птиц, толпа крыс). Надеюсь, было полезно и интересно.

Чтобы поддержать разработку игры, добавляйте King, Witch and Dragon в вишлис на Steam. Если хотите принять участие в обсуждении, вступайте в группу ВК, а также подписывайтесь на меня в Twitter и Instagram.

Спасибо за внимание!

#лонг #unity #графика #опыт #анимация

Гейм-дизайнер днём, инди-разработчик ночью.
{ "author_name": "Андрей Торчинский", "author_type": "self", "tags": ["\u043e\u043f\u044b\u0442","\u043b\u043e\u043d\u0433","\u0433\u0440\u0430\u0444\u0438\u043a\u0430","\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f","unity","pragma","long","include"], "comments": 109, "likes": 682, "favorites": 524, "is_advertisement": false, "subsite_label": "gamedev", "id": 152957, "is_wide": false, "is_ugc": true, "date": "Mon, 15 Jun 2020 09:44:54 +0300", "is_special": false }
0
109 комментариев
Популярные
По порядку
Написать комментарий...
76

Не всё понятно, но очень интересно.

Ответить
33

С шейдерами всегда так 

Ответить
10

Кому интересны более продвинутые техники с вертексной анимацией, для UE4 есть тулзы для конвертации кейфреймов в вертексную анимацию:  

Ответить
15

Если запустить гифку обратно, то чувака съедает толпа крыс.

Ответить
10

Страшная сиерть

Ответить

Комментарий удален

13

На крыс из Plague Tale похоже

Ответить

Коллективный рубин

Damn
24

Где-то заплакал Корво Аттано.

Ответить
14

Где-то

В Корво Бьянко

Ехал Корво через Корво 
Видит Корво в Корво Корво
Корво Корво Корво Курва.

Ответить
–1

Ну, в Dishonored-то попроще анимация крыс

Ответить

Коллективный рубин

Кирилл
0

А с этим никто и не спорит

Ответить
0

Они там в такие вихри не собирались.

Ответить

Постоянный супер_стар

–9

Придирка, конечно, но мыши (крысы) так не бегают. Откройте ссылку ниже. На последнем видео  страницы, на 25 секунде можно увидеть как бежит мышка по виниловой пластинке.

Ответить
41

Ещё как бегают :) поищите видео не домашних грызунов, а диких крыс которые не прогуливаются трусцой, а именно куда-то целенаправленно бегут.

Ответить

Постоянный супер_стар

Андрей
7

Хотя, да. Бегают оказывается.

Ответить
1

Хоть мыши и могут бегать так, все равно можно просто сдвинуть все лапы с левой стороны меша в UV пространстве на .25 по U и получится рассинхрон лап. Тогда мышка начнет мельтешить лапками и как бы бегать.

Ответить
–2

Очень интересно, но игра-то где

Ответить
39

В разработке, где-же ещё 

Ответить
6

Согласен, уже джва года жду.

Ответить
4

Мега-познавательно! Спасибо за годный контент, очень интересно читать про такие приемы. А насколько большой выигрыш по производительности дает такой способ анимирования множества объектов, по сравнению с традиционными способами анимирования? Вы случайно не проводили замеры?

Ответить
11

Огромный выигрыш. Все, что вы сейчас видите в современных играх сделано через шейдеры. Анимация травы, деревьев (их реакция на игрока/ветер), волны океана, объемные облака - это все вертексные шейдеры.

Ответить
0

Ну...логично. В консолях достаточно чахлый проц, проще всё на видеосистему переложить.
Вернее не проще а выгодней.

Ответить
1

Любые массивные вычисления на CPU это всегда проблема. Даже современных 8-12 ядерных CPU не хватит, чтобы рассчитать физические симуляции такого объема в оупенворлд играх. Любое IK, процедурные анимации через bones, физические симуляции, перегруженный Control flow/AI - это все безумная нагрузка на CPU. Поэтому в индустрии все ждут, когда эти вещи будут вычисляться исключительно на GPU.

Ответить
3

Замеры не проводил, но могу точно сказать что с точки зрения производительности такой метод гораздо дешевле чем иметь Skinned Mesh Renderer с keyframe анимацией. И чем больше количество объектов на сцене, тем больше становится разрыв. Проблема в том, что по понятным причинам качество самой анимации ниже, поэтому этот метод используется в основном для «фоновых» объектов.

Ответить
0

а если запечь анимацию в алембик то вроде будет тоже не напряжно и с шейдерами заморачиваться не придется?

Ответить
0

мож лучше геометрию глаз удалить и нарисовать на текстуре? 
как-никак лишние полики

Ответить
16

Можно, но тогда придётся сильно увеличить размер текстуры, чтобы глаза не выглядели пиксельными на текстуре. Сейчас размер текстуры 5х7 пикселей, если  ее увеличить хотя бы до 128х128, количество памяти, которое она будет сжирать перекроет прирост от удаления 8 треугольников. Сейчас основная проблема памяти в играх как раз в текстурах, а не в геометрии. 

Ответить
1

Что-то мне кажется при таком количестве крыс, ни 50 лишних полигонов, ни 100 лишних пикселей в текстуре никакой ощутимой роли не сыграют. Даже на мобилках.

Ответить
0

блин, сначала хотел написать, мол глаз вообще не видно) потом пересмотрел гифку а они есть, да еще и с блумом. Так-то топчик!

Ответить
2

А не пробовал вместо UV маскирования, просто покрасить Vertex Color и использовать его как маску напрямую?
КМК так будет проще.

Ответить
2

Можно и Vertex Color использовать. Если UV-развёртка достаточно сложная, чтобы грамотно расположить все как надо, можно ещё дополнительную текстуру для маски использовать.  В моём проекте Vertex Color используется для цел-шейдинга, по этому я делал через UV-маску.

Ответить
2

Комментарий удален по просьбе пользователя

Ответить
0

Извиняюсь за вопрос не по теме, но что даёт разработчику добавление его игры в желаемые? ПС: Игру добавил 😁

Ответить
7

Если игра достигает порогового значения вишлистов (в районе 5000), то Стим расценивает её как интересную и популярную и начинает показывать её пользователям со схожими интересами, чтобы они тоже добавили её в вишлист. По сути начинает сам на неё нагонять трафик. И плюс она появляется в дополнительных подборках типа "coming soon".

Ответить

Комментарий удален

Комментарий удален

Комментарий удален

Комментарий удален

2

Нормальный способ, анимировал так стаю рыб, хорошо получилось. Но очень специфичный, не всегда подходит. А также требует комплексного подхода "творчество + понимание шейдеров".

Ответить
2

Подписался, завишлистил. Сначала был настроен скептически, но сейчас переубежден. Статья огонь, пишите ещё, будет полезно.

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

Ответить
2

Всё больше убеждаюсь, что разработка игр это невероятный труд.

Ответить
1

А я правильно понимаю, что итоговая анимация, которую мы видим, это не столько изменение геометрии модели, сколько некий... "оптический" фильтр поверх неё?
(Знаком с понятием шейдеров только из движка Source)

Ответить
1

Это как раз манипуляция с геометрией модели. Каждая вершина анимируется в соответствии с алгоритмом, прописанном в шейдере.

Ответить
1

Слушай, а чем это в итоге отличается от скелетно анимированных моделей? Визуально скелетная анимация будет выглядеть намного лучше. Почему такая деформация меша будет кушать меньше ресурсов?

Ответить
7

Потому что кости и джоинты всегда считаются на CPU. Анимация через вертексные шейдеры считается на GPU. GPU всегда быстрее считает большие массивы данных, за счет параллелизации процессов. 

Ответить
4

Ну и плюс к сказанному, если мы говорим про dual-quaternion skinning (современный стандарт индустрии), то количество floating point параметров, которые надо обработать, гораздо больше, чем в случае с vertex shader'ом.

Ответить
1

Понял, пасиб, ребят!

Ответить
2

В общем, понятно, что ничего не понятно )
Раньше думал, что шейдер это нечто отвечающее сугубо за картинку в игре.

Ответить
5

Шейдер - это подпрограмма, которая выполняется на GPU, и которая может манипулировать вершинами модели или текстурой (не обязательно модели).

С помощью него можно менять то, как свет будет ложиться на объект, двигать вершины как угодно, вносить любые изменения в текстуру на лету, делать пост-эффекты (например Blur, DoF) и ещё куча всего.

Короче говоря, штука даёт кучу возможностей.

Ответить
0

Да, я уже понял, но спасибо )

Ответить
0

разные шейдеры могут управлять цветом пикселей текстур и вершинами модели, на этом строятся многие эффекты

Ответить
4

Так, в общем это просто название для алгоритма, который может как угодно взаимодействать с движком, но обрабатывается GPU а не CPU?

Ответить
7

нет, не как угодно
Шейдер отвечает за отрисовку какого-либо объекта на экране. И для этого он может как угодно менять графические данные объекта: модель, текстуру, нормали, ориентацию в пространстве и прочее. Но дальше этого он выйти не может

Ответить
2

Грубо говоря да, шейдер - это программа которая исполняется на GPU

Ответить
0

Чисто из интереса, раз уж я для себя наконец уяснил, что такое шейдер.
Значит ли это, что в обычных условиях, например, скелетной анимации, обработка идёт через ЦП?

Ответить
2

Ясно, спасибо за пояснения

Ответить
0

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

Ответить
0

Очень интересная статья, спасибо. Никак не связан ни с играми, ни с анимацией, но всё равно прочёл с удовольствием. Насчёт времени: сколько у Вас заняло создание этой анимации бега при разработке?

Ответить
4

Скажем так, статью эту я писал гораздо дольше, чем собирал шейдер :) Время не засекал, но, думаю, от получаса до часа.
Если знать, что делать такие вещи, обычно, не занимают много времени.

Ответить
1

Очень круто! Клинок по задумке супертяжёлый?

Ответить
1

не супер, но тяжёлый

Ответить

Полезный парфюмер

Андрей
1

Мне больно смотреть на трещину в полу, которую он оставляет. У него острый кончик, откуда там такие осколки? И не такой он и тяжелый, судя по тому как его персонаж держит (ему не тяжело). Диссонанс в голове от этого момента. Но с крысами крутая задумка, особенно взрыв. 

Ответить
1

Респектище! Пожалуй, первая статья на ДТФ, которую сажусь (вернее, ложусь) читать со спортивным интересом. :)

Ответить
1

Надеюсь, не разочарует :)

Ответить
0

Жена выгнала из дома, закончил читать уже в метро.
Хорошая статья. Разжевано для начинающих и рассказывает об адванснутых "секретах" вертекс шейдеров. Приятно ловить себя на мыслях, мол, "надо сделать уот так уот" и в следующем абзаце читать, что уот так уот и было сделано. :)

А не желаете подключить решение в новый граф юневских спец-эффектов?

Ответить
1

Я VFX Graph вообще не щупал ещё. Я делаю проект на default renderer'e без использования SRP и все шейдеры пишу руками. Плюс, насколько я знаю, VFX Graph делает исключительно косметические эффекты, которые ничего не знают об окружающем мире и физике. В частности, для эффекта в первой гифке я использовал компоненты Particle Trigger и Particle Collision, которые в VFX Graph'е использовать не получится.

Ответить
1

них не понятно но очень интересно. Пили еще такие посты,очень интересно

Ответить
1

Балдею с бесшовности момента, в котором появляется модель персонажа. Несколько раз пересмотрел, так и не смог зацепиться глазом.
Приятно видеть такой игрострой.

Ответить
1

Господа, расскажите мне о противостоянии Юнити и УЕ? Зачем делать игры на Юнити, когда есть Анрил? И наоборот. Вот я вижу что в основном крупные игры на Анриле, а мелкие на Юнити. Почему так? 

Ответить
0

И то и другое лишь инструмент. Кому с каким инструментом удобнее работать, тот его и выбирает. Остальное зависит от рук и мозгов.

Ответить
1

Мало что понял, но в этой статье сконцентрировано всё лучше, что есть на DTF. Рад, что собрала свои заслуженные сотни плюсов. 

Автору удачи с игрой, пишите ещё статьи, выходит круто.

Ответить
1

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

Ответить
0

жесть. Это если с одной крысой столько мороки, сколько тогда времени уходит на создание игры

Ответить
2

Несколько лет

Ответить

Мучительный файл

Андрей
0

Надеюсь, мои внуки смогут поиграть в эту игру :)

Ответить
0

Еще бы бенчмарк какой-нибудь посмотреть какой профит дает такой подход относительно классической анимации. А то пока это напоминает троллейбус из буханки хлеба.

Ответить
1

Сходу нашел только вот это - https://blogs.unity3d.com/2018/04/16/animation-instancing-instancing-for-skinnedmeshrenderer/
Перенос Skinned Mesh'ей с CPU на GPU с использованием инстансинга дал прирост произвоительности в 6 раз. Анимация vertex шейдером гораздо дешевле скиннинга, так что прирост будет еще больше.

Ответить
0

Отличная работа! Обычно такое на хабре, а не на дтф встречаешь)

Ответить
0

Я Хабр уже давно не читал. Там вообще ещё постят что-то по части геймдева? Имеет смысл туда тоже запостить?

Ответить
1

Конечно. В хабе Unity будет очень даже кстати.

Ответить
0

Давно занимаюсь эффектами для игор. Отличный тутор! Взял на вооружение :).

Ответить
0

Спасибо за статью!
Результат очень круто выглядит

Ответить
0

Лоес, безо всяких сомнений.

Ответить
0

Это же прям Plague Tale 👍

Ответить
0

Вот это я понимаю подход!) Очень интересно получилось!

Ответить
0

Просто хочу сказать, что результат выглядит круто. И статья интересная. 

Ответить
0

Класс! Спасибо за текстовую версию шейдера. Так реально понятнее.

Ответить
0

Да, финал Plague Tale сразу вспомнился)

Ответить
0

Спасибо огромное! Все очень подробно описано. Хотелось бы по-больше статей на эту тематику.

Ответить
0

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

Ответить

Комментарий удален

0

Можно было бы не по UV-координатам ориентироваться, а в цвете вершин передать веса/коэффициенты. Тогда не надо было бы так с разверткой изгаляться.

Ответить
0

Оч круто. Главное, когда все готово, то кажется не так и сложно, но это ж надо сначала придумать подходящий способ.

Шейдер граф, конечно, хорошая штука, но как же утомляет для простых операций типа +, * или преобразований vector2/3/4->vector2/3/4 целые блоки добавлять.. 

Ответить
0

Согласен, меня тоже это спагетти из нод утомляет. Поэтому в своих проектах предпочитаю писать всё в текстовом редакторе. 

Ответить
0

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

Ответить
0

Очень интересно, спасибо за статью!

Ответить
0

Очень круто. Блин для меня, как были шейдеры какой-то магией непонятной, так и остались. А вы молодец! Спасибо за статью.

Ответить
0

Очень классно сделано! Спасибо за подробный разбор.

Ответить
0

Полезно, не только для Юнити.

Ответить
0

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

Ответить
0

Видел анимацию на reddit и еще подумал "Как здорово!" А это оказывается наш соотечественник. Спасибо за детали!

Ответить
0

Ты крут!!!

Ответить
0

круть

Ответить
0

Отличный эффект получился.

И анимация с мечом в конце придает характера. <3

Ответить
0

DTF снова торт.

Ответить
0

Я так понял, что взяли ссылку на англоязычный блог и перевели, не зная про то что статья уже есть на русском? Это всё здорово, я не против перепоста, но хотелось бы видеть ссылку на первоисточник (хоть русский, хоть английский). Спасибо!

Ответить
0

Странно, когда смотрю с мобильного, ссылки на оригинал нет, а на десктопе есть.

Ответить
0

Ага, какая-то ошибка на Хабре появилась.

Ответить
0

Источник прямо под заголовком, на английский вариант.

Ответить
0

Очень сложно, игру жду

Ответить

Комментарии

{ "jsPath": "/static/build/dtf.ru/specials/DeliveryCheats/js/all.min.js?v=05.02.2020", "cssPath": "/static/build/dtf.ru/specials/DeliveryCheats/styles/all.min.css?v=05.02.2020", "fontsPath": "https://fonts.googleapis.com/css?family=Roboto+Mono:400,700,700i&subset=cyrillic" }