Сегодня 20 апреля 2026
18+
MWC 2018 2018 Computex IFA 2018
реклама
Видеокарты

Эффекты объемного взрыва

Автор: Kirill Vishnyakov

В совсем недавнем прошлом в подавляющем числе 3D-игр эффекты взрывов реализовывались с помощью простейших текстурированных полигонов, ориентированных параллельно плоскости экрана. Подобная технология весьма проста в реализации и не требует чрезмерных вычислительных ресурсов. Основной минус подобной технологии – "врезание" вспышки взрыва в поверхности. Есть еще масса других недостатков (типа плоского внешнего вида и малой натуралистичности). Это, кстати, хорошо заметно и в движках Q3A, Return To Castle Wolfenstein, Serius Sam и т.п. (Рис. 1).


Рис.1. Врезавшаяся в поверхность вспышка взрыва.

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


Рис.2 Объемный взрыв.

Краткий обзор технологии объемного взрыва

Технология придания объемности работает со взрывом, как с четко определенной частью общего пространства. Я думаю, понятно, что любой видимый полигон, наблюдаемый нами непосредственно сквозь взрыв, меняет свои видимые свойства в соответствии со свойствами самого взрыва. Это касается полигонов, находящихся непосредственно в объеме взрыва (для упрощения это – сфера) и тех, что находятся позади взрыва, как показано на Рис. 3.


Рис.3. Здесь заштрихованная область – область взрыва.

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


For every rendered polygon in scene do            //Каждый закрашиваемого полигона в сцене
   If polygon visible through explosion then      //Если полигон виден сквозь взрыв, то
       Project explosion texture onto polygon     //Проецируем текстуру взрыва на полигон
       Modulate intensity of polygon depending
                    on distance from explosion    //Задаем интенсивность полигона в
                                                  //зависимости от расстояния до взрыва
       Render polygon                             //Рендеринг полигона
   End If
End For

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

Проверка на видимость

Проверка на видимость – это проверка на пересечение полигона с объемом взрыва. Как выглядит объем взрыва схематично изображено на Рисунке 3. Это – конус с вершиной в виде полушария. Точные расчеты в этом тесте не нужны, т.к. текстурные карты взрыва задаются весьма приблизительно в виде размытой круговой области в квадратном битмэпе (bitmap).


Рис.4. Текстура взрыва, использованная в Рис.1 и 2.

Наши расчеты оперируют объемом, аппроксимированным усеченной пирамидой, используемой в типовых расчетах видимого объема с передней отсекающей плоскостью, расположенной в точке на сфере взрыва, лежащей ближе к камере. Задняя отсекающая плоскость взрыва совпадает с дальней отсекающей плоскостью всей сцены. Если проверка на видимость производится в мировом пространстве, тогда необходимо проверить на видимость каждый полигон, находящийся в объеме, определенном шестью отсекающими плоскостями. Проверка на видимость в экранном пространстве – значительно более простой процесс, поскольку проекция взрыва на плоскость экрана – круг (в случае использования конического объема) или квадрат (при использовании усеченной пирамиды). Необходимо заметить, что в случае проекции с соотношением количества пикселей по вертикали и горизонтали, отличным от 1:1, результатом на экранной плоскости будет эллипс или прямоугольник (в зависимости от типа используемого объема отсечения – конус или пирамида).

Проекция текстуры

Как только по расчетам полигон попадает в объем, занимаемый взрывом, то надо будет спроецировать на него текстуру взрыва. Это достигается проецированием базовой плоской текстуры по направлению вектора камеры. Если это проецирование происходит в мировом пространстве, то самый простой метод состоит в том, чтобы трансформировать вершины треугольника в пространство камеры (наблюдателя) и выполнить проекцию там. Заметим, что эффективный радиус взрыва придется масштабировать для того, чтобы можно было применить эффекты коррекции перспективы. Это масштабирование зависит от расстояния между вершиной и камерой.

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

Вот уравнения для этих расчетов:

Где u и v - координаты текстуры,
c – центр взрыва (в экранном пространстве)
V - текущая вершина (в экранном пространстве)
Rad – масштабируемый радиус взрыва

У нас получатся значения в диапазоне [0...1] для точек в объеме взрыва. Точкам за пределами объема взрыва присваиваются значения <0 и >1. Это можно выполнить отсечением полигонов по граням объема (вообще-то, этот вариант не рекомендуется, поскольку он чреват некачественным рендерингом) или подгонкой режима отсечения текстуры в соответствии с настройкой отсечения плоскостями. В этом режиме пикселю, чьи координаты текстуры выходят за пределы диапазона [0...1], присваивается величина цвета 0 или 1 соответственно. Отсечение необходимо только для тех полигонов, чьи координаты текстур лежат за пределами максимума диапазона, определяемого API (Direct3D ограничивает координаты текстуры в диапазоне [-128...+127]).Отсечению подвергаются также те полигоны, которые находятся между передней и тыльной сторонами камеры.

Модуляция интенсивности

Этот этап изменяет интенсивность взрыва в зависимости от расстояния между вершиной (vertex) и геометрическим центром взрыва. Для простоты полагают, что любое изменение интенсивности по направлениям экранных осей X и Y совпадает с интенсивностями на текстурной карте. Все, что нам нужно – это схема, где мы запишем величины интенсивности в зависимости от расстояния из вершины по направлению экранной оси Z. Это можно проделать двумя путями. В первом случае мы считаем, что любая точка, лежащая дальше центра взрыва по направлению от камеры, обладает максимальной интенсивностью. Во втором случае полагаем, что любая точка, лежащая позади объема взрыва по направлению от камеры, обладает максимальной интенсивностью. Какую схему выбрать, зависит от конкретной реализации вашего приложения. Необходимо заметить, что второй вариант более корректный, хотя первый – лучше поддается оптимизации (см. следующий раздел). В качестве результирующего вычисления можно применить простейшую линейную интерполяцию, хоть у этого варианта и страдает точность из-за того, что не учитывается эффект перспективы. Как и в первом случае, необходимо отсечь полигоны для получения корректных результатов. Полигоны отсекаются по плоскостям максимальной и минимальной интенсивности (т.е. передняя плоскость, проходящая через фронт взрыва и плоскость, проходящая через его центр или заднюю часть).

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

Оптимизация

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

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

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

Проблемы при отсечении

Может стать заметным ряд артефактов в изображении после отсечения полигонов по объему взрыва. Как мы выяснили ранее, это отсечение нам необходимо для того, чтобы получить правильные результаты при вычислении интенсивности и избежать генерации слишком больших величин координат текстуры. Отсечение модифицирует экранную область, что требует ее перерисовки. Главная проблема с отсеченными полигонами – это проблема Z-буфера. Более приемлемое решение (другое, нежели отсечение) можно выполнить на основе возможностей Z-bias’а (по-русски можно сказать "Z-сечение"), входящего в API, для того, чтобы мы смогли правильно рендерить перекрывающиеся полигоны. К сожалению, Z-bias на сегодня применяется весьма ограниченно. Тот же самый эффект можно получить, применяя трансляцию координат экранного пространства после их генерации в Z. Этого можно достичь последующей простейшей модификацией матрицы проецирования. (Direct3D требует записи матрицы проецирования в формате, показанном далее). Требуемое Z-сечение зависит не только от разрешающей способности Z-буфера, но и от возможностей применяемого железа.

- Матрица Проекции

- Матрица Z-преобразования

Ограничения

В процессе реализации этого алгоритма был выявлен ряд ограничений. Самое неприятное ограничение было вызвано реализацией экранного пространства в Direct3D. Метод IDirect3Ddevice::ProcessVertices используется совместно с буферами вершин для чтения координат экранного пространства. Проблема в том, что необходимо работать со всеми полигонами и вершинами всего экранного пространства, включая обработанные алгоритмами отсечения. Проще говоря, эффективная обработка экранного пространства требует, чтобы приложение само производило вычисления геометрических преобразований и освещения.

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


Рис. 5. Одно из ограничений "истинного" метода.

Чего ждать в будущем

Эта техника довольно эффективно делает плоскостное проецирование текстуры на уровне приложения, т.е. программно. В принципе, вы можете переписать свое приложение, если эта техника будет поддерживаться на уровне API. Такой вариант хорош тем, что устранил бы необходимость в отсечении и, следовательно, устранил бы необходимость в Z-bias-рендеринге. Это касается и двойного использования текстур для графики и интенсивности взрыва. Карта интенсивности представляла бы собой простейшую градиентную текстуру, проецируемую вертикально - вдоль отрицательной части оси Y экранного пространства. Взрыв проецировался бы вдоль экранной Z-оси. Это позволило бы использовать эту технику в системах с W-буферизацией и избавило бы от всяких "нехорошестей", сильно ухудшающих производительность.

В статье использованы идеи и мысли девелоперов, "витающие в воздухе", на различных форумах и конференциях. Реализация была опробована на видеокарте GeForce2MX 400.

 
 
Если Вы заметили ошибку — выделите ее мышью и нажмите CTRL+ENTER.

window-new
Soft
Hard
Тренды 🔥
В российском Steam открылся предзаказ постапокалиптического боевика Beast of Reincarnation от создателей «Покемонов» 16 мин.
Дата выхода, актёрский состав и самый амбициозный проект A24: раскрыты новые подробности фильма по Elden Ring 41 мин.
Microsoft повысила скорость и производительность «Проводника» в Windows 11 58 мин.
Релиз российской облачной платформы KeyStack 2026.1: расширенная Enterprise-функциональность и архитектура Secure by Default 59 мин.
Vitality разгромила Spirit в финале IEM Rio 2026 и выиграла $1 млн в золотых слитках в гонке Grand Slam 5 ч.
Спустя 28 лет фанаты раскрыли «один из старейших» секретов The Elder Scrolls — что скрывается под женскими юбками в Redguard 6 ч.
Регуляторы увидели в ИИ-модели Anthropic Mythos угрозу для банковской системы 6 ч.
Продажи пиратского симулятора выживания Windrose превысили 1 млн копий, а пиковый онлайн в Steam — 222 тыс. игроков 7 ч.
Capcom похвасталась «мощным стартом» Pragmata — миллион проданных копий за два дня 7 ч.
Инсайдер: Far Cry 7 угодила в «ад», ремейк Splinter Cell не выйдет в 2026 году, а Assassin’s Creed Black Flag Resynced покажут 23 апреля 8 ч.
Huawei представила смарт-часы Watch Ultimate Star Diamond Edition с 99 бриллиантами и оценкой риска гипергликемии 4 мин.
Ещё капельку: XPO-модули повысят плотность сетей в ИИ ЦОД, но CPO всё равно не избежать 34 мин.
Huawei представила смарт-часы Watch Fit 5 и Fit 5 Pro c измерением ЭКГ и уровня сахара в крови 55 мин.
Гиперскейлеры убедили Евросоюз, что экологические показатели ЦОД — это коммерческая тайна 3 ч.
Huawei представила смартфон Pura 90 — тройная камера, 6,8" экран, 7-мм корпус и аккумулятор на 6500 мА·ч 3 ч.
Huawei представила широкоформатный складной смартфон Huawei Pura X Max с чипом Kirin 9030 Pro и ценой от $1615 3 ч.
Huawei представила флагман Pura 90 Pro Max с 200-Мп зум-камерой почти за $1000 и версию Pura 90 Pro подешевле 4 ч.
Набирающий силу профсоюз Samsung намерен запустить 18-дневную забастовку в мае 5 ч.
На IMEI сто рублей: новый закон может сделать смартфоны в России дороже, но операторы уже готовы распорядиться деньгами 5 ч.
Для самых мощных видеокарт: Micron начала поставки 3-Гбайт чипов GDDR7 со скоростью 32 Гбит/с 5 ч.