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

Источник: Fallout 4

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

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

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

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

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

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

Частицы

В некоторых старых играх не показывается целиком процесс образования облака взрыва, а вместо этого используется яркий полноэкранный эффект, после завершения которого частицы уже образуют типичное древообразную фигуру, но больше практически никакого движения не происходит. Вот пример из 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. Вот пример того, что можно симулировать при помощи этого ПО (но, разумеется не в реальном времени):

Источник: FumeFx

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

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

Источник: Fallout 4

Решение

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

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

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

Источник: Fallout 4

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

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

Источник: Fallout 4

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

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

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

Источник: Fallout 4

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

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

Источник: Fallout 4

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

Источник: 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. Текстура дыма просто имеет серый цвет.

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

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

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

Дополнение 2

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

Источник: Alkemi

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

Дополнение 3

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

Текстура Color Ramp
Текстура Color Ramp
Текстура Alpha Ramp
Текстура Alpha Ramp

Дополнение 4

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

Источник: Drone Alone

Дополнение 5

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

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

Дополнение 6

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

Дополнение 7

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

Дополнение 8

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

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

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

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

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

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

Комментарии (3)


  1. ArtTwink
    26.12.2024 12:39

    Некоторые видео не перенеслись - вставились картинкой, например здесь


  1. Jijiki
    26.12.2024 12:39

    спасибо, действительно интересная статья. Дополнение 3 это как раз то что нужно, в игре (я так думаю) нет смысла прям емулировать 1 к 1, поэтому да текстуры + небольшой микродвижок для партиклей - тут важно заметить (микродвижок - аля управление характеристиками партиклей ), получается на выходе самое не накладное это дополнение 3, там прям реально еффекты можно делать.
    СинкМатрикс еще показал как это можно реализовать на своём канале в Ютубе, там он показывает, получается базовую как и у вас в Вашей статье, базовые принципы рендеринга такой техникой (если сократить описание - это маленькие билборды направленные на зрителя)


  1. Dadadam999
    26.12.2024 12:39

    Статья правда интересная.

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