[Перевод] Как устроен эффект ядерного взрыва в Fallout 4

ccd5a019a3dd09acfd008444f7ff7f6f.png

Давайте исследуем одну загадку: как Bethesda смогла сделать такие грибообразные облака ядерных взрывов?

Источник:  Fallout 4

Реальная жизнь

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

Источник:  NUKE TESTS «The mushroom cloud of the atomic bomb»

Верхняя часть такого взрыва состоит из сложного движения: горячие газы «вращаются» вокруг центра, образуя «бублик»:

dafe01f31570dd07d21262fd1566d29b.png

Кроме того, существует переход от состояния «только горячий газ» к состоянию «только чёрный дым»:

4d0c344dcc7e0a42006cfab548a98db9.png

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

Частицы

В некоторых старых играх не показывается целиком процесс образования облака взрыва, а вместо этого используется яркий полноэкранный эффект, после завершения которого частицы уже образуют типичное древообразную фигуру, но больше практически никакого движения не происходит. Вот пример из Mercenaries 2: World in Flames

Источник:  matthythedavian

На самом деле, не так просто реализовать это при помощи обычных частиц и без дополнительных функций, например, анимации геометрии или текстур. Но уже получилось реализовать форму облака! Чтобы сделать движение чуть интереснее, мы можем вращать частицы с разной скоростью и направлением в зависимости от начальной точки эффектов:

Вот пример (R.U. S.E.), в котором это работает очень хорошо; он показывает красивое движение в поднимающихся облаках:

Источник:  matthythedavian:  

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

UV-анимация

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

Источник:  Fallout 3

Всё это сделано при помощи UV-анимации, то есть, по сути, движением текстуры по геометрии. Если менять усиливать и уменьшать яркость этой текстуры (в начале и конце эффекта), а также добавить дым в виде частиц, то выглядит это вполне неплохо.

Источник:  Fallout 3

Вот пример того, как Fallout-Texture выглядит на тестовой геометрии с аддитивным смешением и цветами вершин, чтобы избежать резких краёв по границам геометрии:

Источник:  Fallout 3

В Fallout 4 похожая анимация текстур была использовала на частицах (а не на геометрии, как в Fallout 3), что выглядит очень красиво: одна текстура применена как форма облака, а другая тайловая текстура перемещается по частице. Это даже выглядит так, как будто точки направления скроллинга всегда направлены в центр взрыва:

Источник:  Fallout 4

Если присмотреться, то можно заметить, что это «просто» текстура, движущаяся по плоской частице. Здесь я изменил вторую текстуру, чтобы механика была видна чуть лучше:

Источник:  Fallout 4

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

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

Источник:  Battlefield 4 Trailer

Разве не здорово, что огонь «поглощается» чёрным дымом, растворяется в нём? К сожалению, у меня нет этой игры и я не могу провести расследование, но, по крайней мере, я увидел, что это возможно. Но как?

Анимация текстур

Моё единственное объяснение заключается в том, что текстуры каким-то образом были пререндерены заранее, например, с помощью FumeFx. Вот пример того, что можно симулировать при помощи этого ПО (но, разумеется не в реальном времени):

92e8431c3e6d1b4f812dd5a36f8c3b92.png

Источник:  FumeFx

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

47822fd4a365cfb5f297a6a6d45044f8.png

Вернёмся к исходному вопросу: пока я уверен, что в Fallout 4 сделано именно это — пререндеринг взрыва и демонстрация его «воспроизведения» в игре. Напомню, что взрыв в Fallout выглядит так:

Источник:  Fallout 4

Решение

Поэтому я поискал текстуры, надеясь найти текстурный атлас, состоящий из кадров взрыва, но нашёл лишь это:

848f2610e0c551e418e53179a16f51f9.png

Источник:  Fallout 4 / SmokeCrawl01_Anim_d.dds

Это действительно текстурный атлас, и при воспроизведении он выглядит великолепно, к тому же его можно зациклить!

Источник:  Fallout 4

Но в нём совсем нет пламени! Я думал, что чего-то не хватает, но потом вспомнил о концепции gradient mapping. Подробнее о ней можно прочитать в статье, а также посмотреть этот короткий пример:

Итак, мы можем раскрасить серую текстуру дыма в цветную, переопределив цвета. Здесь я переопределил чёрные значения как оранжевые, а то, что было белым, стало чёрным:

Источник:  Fallout 4

Выглядит отлично, но есть ещё две проблемы:

  1. Соотношение огня и дыма остаётся одинаковым, но у нас очень много огня в начале и только чёрный дым в конце

  2. Мы не видим никакого силуэта облака, а если применим информацию о прозрачности из текстурного атласа (альфа-канала), то это будет выглядеть так:

91c0104b994a6f74edc38bb60718598d.png

Источник:  Fallout 4

Сначала я был сбит с толку, потому что альфа-канал делает всю текстуру прозрачной почти на 50%, но в игре облака почти непрозрачные.

Похоже, решение снова заключается в gradient mapping: для вырезания формы облака разработчики используют альфа-канал текстурного атласа, но переопределяют его значения при помощи gradient mapping, получая непрозрачный результат:

969f9ee4628c1699b0830a3ad2c5cb37.png

Источник:  Fallout 4

Fallout хранит свои градиенты в… текстурах! Вот так сюрприз. Давайте взглянем на это:

fe914841c8d490ffe518081ebf367ea2.png

Источник:  Fallout 4 SmokeCrawlGasFireGrad.dds

Что это такое? Для стандартного gradient mapping нам бы понадобилась текстура высотой всего 1 пиксель, так почему разработчики использовали квадратную текстуру? Причина в том, что они сэмплируют разные «строки» пикселей (снизу вверх), в зависимости от времени жизни частицы!

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

Источник:  Fallout 4

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

Источник:  Fallout 4

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

Думаю, можно уверенно сказать:

Загадка решена!

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

Здесь я раскрасил нижнюю и верхнюю часть текстуры градиента в разные цвета; как и ожидалось, на определённом этапе срока жизни частиц цвет резко меняется:

Источник:  Fallout 4

Здесь я сделал то же самое, но с разными цветами слева и справа, то есть один цвет перезаписывает значения градаций серого от 0 до 127, а другой — от 128 до 255:

Источник:  Fallout 4

Этот эксперимент оказался немного странным: я поменял альфа-канал текстуры градиента (всё стало чёрным, за исключением одной строки пикселей внизу). Я бы ожидал, что текстуры пропадут очень рано. Но посмотрите на результат сами:

Источник:  Fallout 4

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

В своём последнем примере я сделал так, чтобы альфа-канал видимой текстуры скрывался всё больше и больше в процессе жизни облака:

Источник:  Fallout 4

Дополнение 1

Ravendarke показал примеры из игры, над которой он работает (Wayward Terran Frontier), где нечто подобное выполняется интересным образом для того, чтобы текстура со швом казалась бесшовной (подробнее об этом ниже):

Источник:  Wayward Terran Frontier

Варьирование цвета выполняется как в Fallout 4. Текстура дыма просто имеет серый цвет.

2be3b953d7d0b6d4c81a008f6ed9b4c8.gif

Источник:  Wayward Terran Frontier

Текстура дыма в игре состоит из 14 кадров, но первый и последний не совпадают идеально. Эта проблема была решена так: вместо покадрового воспроизведения анимации кадры смешиваются друг в друга:

0873b843628167b29088a584c7e80013.png

Источник:  Wayward Terran Frontier

Дополнение 2

Froyok опубликовал в Twitter отличную статью о частицах + модификации цветов, написанную Alkemi.

8d8983d87e7c6794bf3772c55950b39b.png

Источник:  Alkemi

Также он упомянул обсуждение, в котором кто-то задал вопрос, как реализовали взрыв в Battlefield 4.

Дополнение 3

Флориан Смолка показал свою работу над шейдером для игры отличного немецкого разработчика Mimimi Productions! Мы можем даже взглянуть на текстуры и код шейдера с комментариями! Разве не здорово?

Текстура Color Ramp

Текстура Color Ramp

Текстура Alpha Ramp

Текстура Alpha Ramp

067deeded48f1518a1708b9b91008357.png

Дополнение 4

Золтан Эрдокови объясняет в своём посте свою методику добавления движения в этот дым без покадровой текстуры. Особенно потрясающе выглядит огненное ядро!

5ff24821d22843fa874e24b5f9f6f074.gif

Источник:  Drone Alone

Дополнение 5

Я нашёл видео, в котором игрок подошёл очень близко к грибу из Fallout 4, и это позволило нам лучше рассмотреть, как оно сделано.

eeb71f12ebaf052e44a7b4adbb8298c9.gif

Источник:  Fallout 4: GOING TO THE NUKE Before it Kills You

Дополнение 6

«Nebbul vfx» опубликовал на своём Youtube-канале видео о комбинировании градиентов Fallout 4 с векторами движения. Выглядит фантастически!

8ff7ea171bb5644507e97c30af88d8ef.png

Дополнение 7

Pawige опубликовал потрясающий анализ созданного им пиксельного взрыва!

Дополнение 8

thwix поделился в Discord realtime vfx отличным трюком для добавления «скорректированного для камеры» движения частиц ударной волны, но его можно использовать и для добавления красивого движения вращения, подобного описанному в моей статье. Цитата:

«Для имитации несжимаемости в динамике жидкостей часто пригождаются частицы, вращающиеся противоположно их вектору скорости»

c47658bfc59a31564d771aca9956b386.gif

«но при просмотре под другим углом картинка начинает ломаться из-за того самой природы спрайтов, вращающихся относительно камеры»

97d2f5eff11cc2147b8f34a4ed4d44e9.gif

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

5b86891382e148ea8c4a63bf9c0b3f0d.png

«Так мы получаем внешне одинаковое вращение с обоих углов»

177d796f21d52cc112cde391a548a4c1.gif

«Это также очень подходит для эффектов ударной волны»

02c8c723b5dd1e69b845374b332c3021.gif

© Habrahabr.ru