![](https://habrastorage.org/webt/zo/cc/o4/zocco49yvcnsbel4siyce03w1jm.jpeg)
Когда только начался переход с DX9 на DX10 стало появляться много игр с круто смоделированной водой с правильными эффектами. Тогда разница была очень заметной, особенно если сравнивать игры прошлых поколений и тот же Crysis. Поэтому когда наткнулся на гайд, как сделать простую, но реалистичную симуляцию реки через плагин Houdini для UE4, то даже не стал задумываться и быстро перевел.
Пролог
- Скачайте ассеты Unreal и Houdini. Видео по установке — тут.
- Большую часть проекта я следовал туториалам Бена Шрайвера и Андреаса Глэда.
- Не бойтесь нод и скриптов. Это не так сложно, как может показаться.
- Для воды я использовал карту нормалей из Unreal Starter content.
Введение
Меня зовут Саймон. Я начал программировать на QBasic и Pascal еще в молодости (вот примеры), сразу осознал, что кодить сложно, и перешел в 3D-искусство. При этом я всегда сохранял интерес к технической стороне создания игр — вылилось в то, что я стал VFX-художником. Эта профессия хорошо сочетает в себе искусство и технологии.
Я работал 3D-художником над Sacred 2 и X:Rebirth, и VFX-художником над RiME, The Invisible Hours. Сейчас работаю над WiLD.
![](https://habrastorage.org/webt/kv/d3/0o/kvd30oaovx4wnjixasgjvz3fylg.jpeg)
У меня также есть несколько личных проектов, связанных с разработкой игр: блог Game Art Trick, немецкий Game Dev Podcast и YouTube-каналы с туториалами по Unreal и Houdini.
Знакомство с Houdini
Я подружился с Houdini во время работы над The Invisible Hours. Тогда я сделал небольшой симулятор жидкости, который можно было приостановить, развернуть и воспроизвести задом наперед в реальном времени. Результат был таким:
![](https://habrastorage.org/webt/vj/do/pq/vjdopq_bwik4j18nz56askkairm.gif)
Источник: Симуляция жидкости из The Invisible Hours
Я понятия не имел, как добавить жидкое моделирование в Unreal. К счастью, удивительная технология под названием Vertex-Count-Agnostic Morph Target-Based Fluid Animation была реализована в Houdini, и поэтому я смог добавить свою симуляцию жидкости в игру. Технология первоначально была разработана Норманом Шааром.
![](https://habrastorage.org/webt/ih/2w/_w/ih2w_wc1hwwkj6eoaop-swctcri.gif)
Источник: Vertex-Count-Agnostic Morph targets в UE4 Нормана Шаара
Если вы хотите узнать больше о реализации, то посмотрите этот раздел моего доклада Cool Stuff with Textures:
Эффект реки: начало проекта
Я хотел узнать, как сделать процедурно-генерируемую реку для Realtime VFX River Challenge, но понятия не имел, с чего начать. Случайно я наткнулся на шикарный туториал от Бена Шрайвера, где он рассказывает о реках в Horizon Zero Dawn. Меня зацепило и я решил попробовать!
Кстати, есть еще один очень крутой туториал по рекам Houdini от Андреаса Глада:
Эти видео очень помогли мне в начале и стали фундаментом.
Очень сложный способ построения ландшафтов
Рельеф был очень сложным. Проиллюстрирую процесс создания, чтобы все поняли:
![](https://habrastorage.org/webt/cg/xz/bj/cgxzbjhkufvwcv8gw82rpzrzr1k.gif)
Источник: Создание местности в Houdini
Шучу. Это слишком просто.
Эффект реки
Первые шаги на 100% скопированы из туториала Бена, и они крутые. Сначала вы создаете сплайн и даете ему «упасть» на местности. Это делается путем считывания высоты рельефа в точках сплайна, а затем перемещения точек на эту высоту:
![](https://habrastorage.org/webt/us/yi/xw/usyixwesrlu0b3gnqcsotytydfm.gif)
Затем вы позволяете сплайн-точкам «скатиться» вниз по склону, чтобы лучше интегрировать реку в рельеф:
![](https://habrastorage.org/webt/ml/zp/-h/mlzp-hvsp1fjpxrpov-rvs6ycyu.gif)
На самом деле, они не скатываются физическим способом. Вместо этого используется базовая нормаль поверхности и нормаль точки для вычисления локальной оси для каждой точки (которая перемещается от сплайна вниз по склону). Затем вы немного перемещаете точки вдоль расчетной оси (этот процесс очень хорошо показан в видео Бена).
Следующий шаг — убедиться, что река не течет вверх по течению из-за ландшафта (потому что есть небольшой холм, где река идет вдоль).
![](https://habrastorage.org/webt/sd/j2/kw/sdj2kwej7nwjgxii1cwollgw2eu.jpeg)
Небольшой скрипт на Python гарантирует, что точка сплайна в 3D-пространстве никогда не будет выше, чем предыдущая:
![](https://habrastorage.org/webt/ug/b-/y1/ugb-y1cw7pd3cuzph48diedsm7w.gif)
Еще один трюк, чтобы добавить естественности — это избегание непрерывных склонов. Вместо этого позвольте реке течь поэтапно (для лучшей визуализации я показываю геометрию реки здесь, но на самом деле мы все еще работаем только с одним сплайном).
![](https://habrastorage.org/webt/vp/cj/65/vpcj65p-xzp9zb26uzeqvnrddts.gif)
Наконец, мы доходим до шага, где я вношу собственные идеи: добавляю цвета к сплайну, чтобы отметить, где уклон (зеленый), где он начинается (бирюзовый) и где заканчивается (красный). Это поможет мне позже смешивать различные текстуры воды и размещать системы частиц.
![](https://habrastorage.org/webt/34/kk/je/34kkjekzjvkt1vk71sadbdiw8mk.jpeg)
Давайте быстрее перейдем к созданию геометрии реки, так как все это прекрасно объяснено в видео Бена. Наиболее важным моментом является то, что только внешние края реки снова выравниваются с рельефом (как мы это делали со сплайном в первую очередь):
![](https://habrastorage.org/webt/cb/k_/0o/cbk_0oekhh4qv0_rwaxcsh-n1ey.gif)
Деформирование ландшафта согласно потоку
Опять же, это 100% рабочий процесс Бена, начинающийся с перемещения рельефа ниже геометрии реки, чтобы они никоим образом не пересекались:
![](https://habrastorage.org/webt/ao/a1/ad/aoa1adr5lgjo6qdqhyxiwc6vv_u.gif)
Затем для каждой точки местности вы проводите лучи вверх. Если они попадают в геометрию реки, то эти точки переместятся вверх в место попадания:
![](https://habrastorage.org/webt/w3/ap/nm/w3apnmoupwccs1xzv0pvqmowmgs.gif)
Каждая точка, которая никуда не попала, получит первоначальную высоту.
![](https://habrastorage.org/webt/vo/pq/70/vopq70pbljo9t--vuuvs6d4ekto.gif)
На этой гифке видно, что происходит при изменении сплайна:
![](https://habrastorage.org/webt/tv/ej/ly/tvejlykun03wkeuvisao1o-vg-4.gif)
Затем область высоты ландшафта преобразуется в полигоны и повторно перемешивается. Теперь она готова для использования в Unreal:
![](https://habrastorage.org/webt/5s/z8/bx/5sz8bxsdmnktiotlc83wajh5yh4.gif)
Теперь поговорим о UV-преобразовании, материалах, картах течений и многом другом.
Геометрия реки
Геометрия реки, которую вы видели раньше, была использована только для вырезания местности. Настоящая река немного тоньше, имеет UV и была разделена (обратите внимание, что мои цвета склонов все еще там):
![](https://habrastorage.org/webt/sv/b8/av/svb8avrrg1gd_1uhxo38kqry_sy.jpeg)
Генерация UV
Поскольку сплайн всегда варьируется по длине, UV должен адаптироваться к этому. К счастью, это очень легко в Houdini. Сначала вы создаете UV в 0-1-UV-Space, а затем измеряете длину сплайна. Это значение можно использовать для масштабирования UV. Здесь вы видите, как я меняю сплайн, а в нижней части — как UV автоматически адаптируется. Поверьте мне, если вы однажды попробовали это, то больше никогда не захотите создавать UV вручную.
![](https://habrastorage.org/webt/wc/xt/bg/wcxtbgtruxdphsewttvvxhz6htk.gif)
Русло
Еще одна деталь: я хотел сделать русло темнее и мокрым. Для этого я провожу вверх несколько лучей с каждого полигона ландшафта, и если попадаю в реку, то назначаю цвет всем точкам этого многоугольника. Созданная маска выглядит следующим образом:
![](https://habrastorage.org/webt/7n/y5/0y/7ny50yh2opc_nw8vnz7uxbyimxk.jpeg)
А вот пример с использованием маски в материале для присвоения различных значений расплывчатости и шероховатости:
![](https://habrastorage.org/webt/lm/3j/q0/lm3jq0smmrte5rgngq41quczlfk.gif)
Карта течения
Создать карту течения реки с Houdini очень легко. Вы просто говорите специальному ноду «это моя геометрия реки, а это сплайн, который указывает направление реки» и бум, геометрия внезапно получает цвета вершин, представляющие поток реки:
![](https://habrastorage.org/webt/lo/ni/so/lonisoo-qw1n5sm0fkyvlrrzv6s.gif)
Можно добавить еще один нод, который заставит карту потока реагировать на препятствия. Теперь вода потечет вокруг них:
![](https://habrastorage.org/webt/tf/js/le/tfjsle853agjxektemwpibn23ao.gif)
И самое крутое: вы можете вызвать запекание карты потока в Unreal! Нет необходимости переключаться между Unreal и Houdini. Просто выставьте кнопку Render в Houdini в качестве параметра. Здесь вы видите, как я меняю препятствия, а затем визуализирую новую карту потока (учтите, что запекание занимает больше времени, чем на гифке):
![](https://habrastorage.org/webt/cm/6g/n7/cm6gn7hlvksqupcuvohwt6y31xw.gif)
Маска пены
Чтобы сделать пену на воде вокруг препятствий, я использую так называемый нод isoOffset. В основном он хранит расстояние до объекта в цвет вершины реки. Затем я добавил немного шума и маска готова:
![](https://habrastorage.org/webt/su/_b/jq/su_bjqg4awfkxsp4gv4gitep2cu.gif)
Чтобы сделать маску пены менее статичной, я использую простой облачный шаблон Photoshop, который перемещаю вдоль реки и вычитаю его из оригинальной маски:
![](https://habrastorage.org/webt/_j/xd/re/_jxdrekk6uxwlynw0dmmqri8l2g.gif)
И поскольку мы говорим о пене: каскады тоже имеют простую текстуру пены, которая показана только на склоне реки. Структура пены прокручивается быстрее, чем речная вода:
![](https://habrastorage.org/webt/dc/s0/vl/dcs0vler9nwiru_ll82wbonigvq.gif)
Системы частиц
Я отметил, где находятся верхняя и нижняя части моего каскада, поэтому могу фильтровать эти элементы (линии использовались для создания геометрии реки), создать точку в их центре и скопировать в нее dummy-box. Позже заменим ее на систему частиц в Unreal:
![](https://habrastorage.org/webt/yx/wk/uj/yxwkujd9hyyriqlse1pwytkg9ea.gif)
Для частиц вокруг препятствий я использую нод под названием Intersection Analysis, чтобы получить пересечение препятствий и реки. Эти ребра пересечения имеют точки. К их случайному числу я снова копирую dummy-box (который позже обменивается с системой частиц в Unreal):
![](https://habrastorage.org/webt/2p/cz/67/2pcz67ex6i3arika_ktlfpb9nae.gif)
Так это выглядит, когда я заменю dummy-boxes в Unreal:
![](https://habrastorage.org/webt/u7/wh/ze/u7whze-vypqb9dlftd1e-t8dhvc.gif)
Экспорт проекта в Unreal
Так называемый движок Houdini представляет собой плагин для Unity, Unreal, 3ds Max, Maya и Cinema 4D и выполняет сети нод, которые вы создаете в Houdini непосредственно в указанных программах. Мне нужно сделать так, чтобы появилась местность и река для сохранения Houdini-файла как цифрового ассета. Его можно импортировать и использовать, как любой другой ресурс в Unreal:
![](https://habrastorage.org/webt/uj/s_/ak/ujs_ak1r7u9sazit7ruj1oh0zm8.gif)
Теперь я могу изменить параметры (которые я выставил в Houdini) или изменить сплайн, чтобы река текла другим путем:
![](https://habrastorage.org/webt/yk/na/_q/ykna_qoftdpvnkh6paoqpurknl0.gif)
Материалы по-прежнему создаются и назначаются в Unreal, но вы можете назначить их предварительно (ниже мой туториал об этом).
Должны ли мы одинаково изучать рабочие процессы Houdini?
В Houdini предстоит многому научиться. Кроме того, это новые инструменты разработки, поэтому в документации будут встречаться неточности.
Но это обычная ситуация для разработчиков игр. Мы постоянно работаем с передовыми технологиями, которые нужно сначала приручить. Самое главное: вы не одиноки. Thinking Procedural Discord полон крутых ребят, которые которые помогут и научат. В этих чатах вы даже можете найти разработчиков SideFX!
Ссылки
- Ассеты Unreal и Houdini. Видео по установке — тут.
- Чат Discord: Houdini Thinking Procedural
- Туториал Бена Шрайвера
- Туториал Андреаса Глэда
- River Challenge Thread
- Доклад о Liquid Implementation в The Invisible Hours
- YouTube-каналы с туториалами по Unreal и Houdini
- Vertex-count-agnostic Morph Targets Нормана Шаара
Комментарии (3)
gaploid
21.11.2018 23:12А можно ли сделать у такой реки вес/силу давления? Чтобы к примеру могла двигать/смывать обьекты и тд?
SpiritOfDarkDragon
Спасибо огромное за перевод.