[Перевод] Как было реализовано пламя в Doom на Playstation
![[Перевод] Как было реализовано пламя в Doom на Playstation [Перевод] Как было реализовано пламя в Doom на Playstation](https://habrastorage.org/webt/j6/ea/7_/j6ea7_kttb5sakep9dakj5kw47i.png)
Целая глава моей книги Game Engine Black Book: DOOM посвящена консольным портам DOOM и сложностям, с которыми сталкивались их разработчики. Можно долго рассказывать о полном провале на 3DO, о сложностях на Saturn из-за аффинного наложения текстур и о потрясающем «реверс-инжиниринге с нуля», выполненном Рэнди Линденом для Super Nintendo.
Изначально двинувшись в направлении, ведущем к катастрофе[1], разработчики порта под Playstation 1 (PSX) в дальнейшем сменить курс и создать порт, завоевавший успех у критиков и рынка. Final DOOM был первым истинным портом, сравнимым с PC-версией. Цветовые сектора с альфа-смешением не только усовершенствовали визуальное качество, но и улучшили геймплей благодаря индикации ключа нужного цвета. Также благодаря эффектам реверберации Audio Processing Unit консоли PSX был улучшен звук.
Команда разработчиков выполнила настолько качественную работу, что у неё осталось ещё немного свободных циклов ЦП, которые они решили использовать для генерации анимированного огня в интро и геймплее. Меня это настолько привело в благоговейный трепет, что я решил разобраться, как был реализован эффект. Когда первые поиски не дали ответа, я приготовился уже сдувать пыль с книги по MIPS для взлома исполняемого файла, но Сэмюэль Вильяреал вовремя ответил в Twitter, что он уже выполнил обратную разработку версии для Nintendo 64[2]. Мне достаточно было просто немного её подчистить, упростить и оптимизировать.
Было интересно заново обнаружить этот классический эффект демосцены; лежащая в его основе идея похожа на первую водную рябь, которая входила в обязательный набор программ многих разработчиков 90-х. Эффект огня стал живым свидетелем того времени, когда тому, что сочетание тщательно подобранной цветовой палитры и простого трюка были единственным способом добиться желаемого.
Базовая идея
В своей основе эффект огня использует простую карту высот. Массив размером с экран заполняется 37 значениями в интервале от 0 до 36. Каждое значение связывается с цветом от белого до чёрного, и захватывает по дороге между ними жёлтый, оранжевый и красный. Идея заключается в моделировании температуры частицы пламени, которая поднимается вверх и постепенно охлаждается.

Буфер кадра инициализируется полностью чёрным (заполненным нулями) с единственной белой строкой белых пикселей внизу (36), которая является «источником» пламени.

При каждом обновлении экрана «тепло» поднимается вверх. Для каждого пикселя в буфере кадра вычисляется новое значение. Каждый пиксель обновляется с учётом значения, расположенного непосредственно под ним. В коде нижний левый угол это нулевой индекс массива, а верхний правый угол имеет индекс FIRE_HEIGHT * FIRE_WIDTH — 1.
function doFire() { for(x=0 ; x < FIRE_WIDTH; x++) { for (y = 1; y < FIRE_HEIGHT; y++) { spreadFire(y * FIRE_WIDTH + x); } } } function spreadFire(src) { firePixels[src - FIRE_WIDTH] = firePixels[src] - 1; }
Заметьте, что строка 0 никогда не обновляется (итерация по y начинается не с 0, а с 1). Эта заполненная нулями строка является «генератором» огня. Простая версия с линейным охлаждением (-=1) даёт нам скучные равномерные выходные данные.

Мы можем немного изменить функцию spreadFire() и модифицировать скорость затухания значений теплоты. Вполне подойдёт добавление случайности.
function spreadFire(src) { var rand = Math.round(Math.random() * 3.0) & 3; firePixels[src - FIRE_WIDTH ] = pixel - (rand & 1); }

Так уже лучше. Чтобы усовершенствовать иллюзию, можно случайным образом распространять не только вверх, но также влево и вправо.
function spreadFire(src) { var rand = Math.round(Math.random() * 3.0) & 3; var dst = src - rand + 1; firePixels[dst - FIRE_WIDTH ] = firePixels[src] - (rand & 1); }
[Прим. пер.: Youtube ужасно пережимает видео, лучше смотреть демо на Javascript в оригинале статьи.]
Вуаля! Заметьте, что изменяя процесс распространения пламени можно также симулировать ветер. Я оставлю это в качестве упражнения для читателей, которым удалось дочитать статью.
Полный исходный код
Версия Сэмюэля (логически) выглядела больше похожей на ассемблерную. Если хотите взглянуть на неё, то здесь есть подчищенная и упрощённая версия.
Справочные материалы
[1] Источник: Полная история подробно рассказана в книге Game Engine Black Book: DOOM
[2] Источник: пост в Twitter за 25 марта 2018 года
Источник
На съемках «Народа против Гориллы Гродда» заметили намеки на появление Короля Соломона
Premium Collectibles Studio открыла предзаказ на статую ксеноморфа из фильма Чужой высотой 124 сантиметра
Серии Crash Bandicoot исполнилось 30 лет, но Xbox практически никак не отметила юбилей
Градостроительный симулятор XIRI Oasis Cities посвящен выживанию города будущего
Разработчики Moss закрыли студию после релиза игры на всех платформах
Авторы Fable пообещали сделать боевую систему глубокой вместо копирования старых RPG
По данным СМИ, Sony забрала у студии Kojima Productions движок Decima
Российская инди-студия анонсировала градостроительный симулятор XIRI Oasis Cities