реклама
Видеокарты

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

Автор: 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
Тренды 🔥
Nintendo прекратит выдавать золотые очки за покупку игр незадолго до новой презентации Switch 2 3 ч.
Epic Games засудила киберспортсмена-читера по Fortnite, отняла его призовые, навечно забанила и заставила перед всеми извиниться 4 ч.
«Корпоративный Telegram» с ГОСТ-шифрованием: «Иридиум» представил защищённый мессенджер DMTChat 5 ч.
Разработчики Company of Heroes и Warhammer 40,000: Dawn of War анонсировали пошаговую стратегию Earth vs Mars про вторжение марсиан на Землю 6 ч.
До конца февраля в Game Pass добавят всего три игры, но среди них есть Warhammer 40,000: Rogue Trader и Watch Dogs: Legion 7 ч.
Инсайдер раскрыл количество предзаказов Assassin’s Creed Shadows и дату выхода первых обзоров игры 7 ч.
WhatsApp стал слишком популярен в Европе и теперь попадёт под более жёсткое регулирование 8 ч.
Пошаговое ролевое приключение Dead Weight отправит игроков в стимпанковый мир летучих кораблей и Древних Богов 9 ч.
«Лаборатория Касперского» усовершенствовала защиту для виртуальных и облачных сред 9 ч.
Microsoft отменила автоматический вход в учётные записи, о котором сообщалось ранее 9 ч.
Новая статья: Обзор realme C75: неубиваемый смартфон, недорого 3 ч.
В связи с ростом цен расходы госкомпаний на закупки коммуникационного оборудования выросли в 2024 году на 15 % 4 ч.
Acer анонсировала скорое повышение цен на ноутбуки, но только в одной стране 7 ч.
Учёные не нашли препятствий для течения времени вспять, но путешествовать в прошлое это не поможет 7 ч.
Представлены SSD для потребительских компьютеров Micron 4600 — до 4 Тбайт и 14 500 Мбайт/с 7 ч.
Благодаря ИИ мировое производство полупроводников показало уверенный рост в четвёртом квартале 2024 года 7 ч.
DJI представила стабилизаторы Osmo Mobile 7 для смартфонов для плавной кинематографической съёмки 8 ч.
Ведущие производители DRAM полностью прекратят выпуск DDR3 и DDR4 к концу 2025 года, но это не точно 8 ч.
Представлены умные часы OnePlus Watch 3 с автономностью на пять дней и ценой $329 8 ч.
Nothing показала превосходство грядущих Phone (3a) и (3a) Pro над iPhone 16 Pro Max по части возможностей камеры 8 ч.