Высококачественное освещение в DooM 3

Всё началось с идеи Humus-а, выпустившего ATI tweak. Идея проста: величина отражения (specular) на объекте зависит только от самого объекта, зачем задавать её в виде отдельной текстуры? Заменив выборку текстуры на расчёт в шейдере, Humus заметно увеличил производительность видеокарт ATI, которым выполнить пару математических функций проще, чем выбрать шестую текстуру. <br/><br/>Надо заметить, что оригинальный шейдер освещения DooM 3 использует текстуры для передачи различных параметров, потому что для видеокарт NVidia это более удобный способ. <br/><br/>Следующим шагом стал шейдер idiom-а, добавившего изменение величины отражения (заметьте, не интенсивности, а именно размера блика!) обратно-пропорционально значению, заданному в альфа-канале основной текстуры. Эт...
6 мая 2005, пятница 13:02
GReY для раздела Блоги
Всё началось с идеи Humus-а, выпустившего ATI tweak. Идея проста: величина отражения (specular) на объекте зависит только от самого объекта, зачем задавать её в виде отдельной текстуры? Заменив выборку текстуры на расчёт в шейдере, Humus заметно увеличил производительность видеокарт ATI, которым выполнить пару математических функций проще, чем выбрать шестую текстуру.

Надо заметить, что оригинальный шейдер освещения DooM 3 использует текстуры для передачи различных параметров, потому что для видеокарт NVidia это более удобный способ.

Следующим шагом стал шейдер idiom-а, добавившего изменение величины отражения (заметьте, не интенсивности, а именно размера блика!) обратно-пропорционально значению, заданному в альфа-канале основной текстуры. Этим он пытался реализовать так называемый gloss map, т.е. величину гладкости поверхности. Ведь известно, что полированные поверхности дают чёткий блик, а матовые - размытый. Поскольку в оригинальном DooM 3 альфа-канал текстур практически не задействован, он подстроил расчёты так, чтобы при обычном значении альфа-канала получался блеск, соответствующий металлическому.

Получается, что для немодифицированных текстур DooM 3 поддержка gloss-map не работает, но почему тогда шейдер делает настолько красивый блеск? Потому что idiom добавил в расчёт освещённости несколько дополнительных инструкций, нормализующих вектор локальной нормали поверхности (bump mapping), который был получен из текстуры типа "карта нормалей". Эта простая операция на порядок улучшила качество имитации рельефа, что и определило общую приятственность картинки с данным шейдером.

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

Взяв за основу метод idiom-а (расчёт величины блика как степенной функции от гладкости поверхности) я реализвал более правильный и, к тому же, универсальный вариант, который полностью работоспособен в любой версии DooM 3 (скорее всего он будет нормально работать и в Quake 4). Тщательно проанализировав блеск, наблюдаемый в природе, я пришёл к выводу, что интенсивность отражения прямо-пропорциональна гладкости поверхности. Интенсивность (и спектр) отражений у нас задан в картах блеска (specular maps), значит нам не нужны gloss maps для определения величины блика! Чем выше интенсивность блика, тем более гладкая поверхность его создаёт; отталкиваясь от этого постулата, я добавил в шейдер вычисление средней интенсивности блеска как суммы R, G и B компонентов карты блеска. Подобрав правильный коэффициент мне удалось получить практически идеальный вариант: стекло блестит как стекло, металл как металл, кожа как кожа.

На этом эпопею с шейдером можно было бы закончить, если бы не вопиющая недоработка в самой модели освещения DooM 3! У каждого источника света есть жёстко заданная "область действия", зачастую противоречащая законам физики. Например рядом с ярким фонарём может быть полная темнота. А свет фонарика игрока, наоборот, нисколько не убывает с расстоянием, что выглядит весьма дико. В общем, это сильно мозолило мне глаз, поэтому после завершения работ над блеском я решил всерьёз заняться самим освещением.

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



Во первых, стало намного светлее. Во вторых, появился прелестный эффект отражений света в кафельной плитке и гладком металле.

Скачать новый шейдер можно здесь.

Установка проста - распакуйте скачанный архив в папку 'DooM3\base' (как вариант - переименуйте superlight.zip в superlight.pk4).

Для получения наилучших результатов рекомендую прописать в autoexec.cfg следующие строчки:
seta r_lightScale "1"

seta r_useLightScissors "0"


Яркость и гамму подобрать по вкусу.

Наибольший эффект новый шейдер даёт в высоких разрешениях (1024 и более) при настройках качества Ultra High Quality. При правильной настройке компьютера Ultra-качество доступно даже для Radeon 9800 Pro, не говоря уже про GeForce 6600 и 6800. Настройка заключается в следующем: обновите драйвера вашей видеокарты, установите в BIOS setup настройку AGP Aperture Size на 256 MB, в autoexec.cfg добавьте строчку seta com_videoRam "512", и можете смело включать Ultra High Quality. Если в вашем компьютере не более 1 ГБ оперативной памяти, включите в doom3config.cfg уменьшение текстур. Я остановился на размерах 512 для основных текстур, 256 для bump и 128 для specular.

Поскольку я не имею возможности протестировать все видеокарты, возможны проявления артефактов как в патче humus-а. В этом случае просто исправьте в тексте шейдера строчку "precision_hint_fastest" на "precision_hint_nicest". И сообщите мне о достигнутых результатах

По моим наблюдениям новое освещение "сжирает" 10-20% производительности видеокарты. Будет интересным собрать статистику падения производительности от нового шейдера на разных видеокартах, поэтому не премините оставить сообщение в конференции.

Обсуждение этой и других модификаций для DooM 3 ведётся в этой ветке конференции.

PS

Многомесячная работа над ещё большей реалистичностью картинки привела к выводу, что отказываться от falloff света, заданного в игре, нельзя. Поэтому я сделал небольшой трюк, добавив динамическое увеличение "дальности" света в зависимости от яркости источника. Также изменён расчёт гладкости поверхности. Шейдер значительно оптимизирован по скорости. Результат можно скачать отсюда.