?

Log in

No account? Create an account

[icon] Clive Barker's Jericho - Роман Марченко — ЖЖ
View:Свежие записи.
View:Архив.
View:Друзья.
View:Личная информация.

Security:
Subject:Clive Barker's Jericho
Time:03:42 pm
После того, как демка игры Clive Barker’s Jericho появилась для свободного скачивания, многие люди оценили графику в ней как «лучшую которую они видели на сегодняшний момент». Как вы понимаете, я не мог пропустить такую игру.

Конфигурация компьютера: A64 X2 4200+, GeForce 8800 GTX, 2GB Ram. Все настройки игры на максимум.

После запуска, невооруженным глазом сразу видно, что игра сильно нагружена спецеффектами, поэтому, как я и ожидал, первым проходом идёт заполнение scene depth буфера. Это не чисто only-z проход. На нем в R32F рендер таргет выводится camera space z. Полученная текстура далее используется во множестве случаев. Все последующие проходы геометрии используют полученный z-буфер устанавливая DepthWrite в false.

Движок игры многопроходный. Для каждого источника света существует отдельный проход рендера геометрии. Если источник должен отбрасывать тень, то первым идет рендер в R32F текстуру тени (omni shadows замечены небыли). Затем отрисовывается вся геометрия, на которую влияет данный источник. Во время рендера используются:
Диффузная текстура (сделайте монитор поярче, картиночки темноваты):

Нормал мапа:


Примняется DXT5 сжатие. X и Y компоненты вектора лежат в G и A каналах. Данный способ сжатия нормал мап широко известен. Z вычисляется как sqrt(1 – x^2 – y^2), так как нормали у нас единичной длины и мы знаем, что Z координата в tangent space normal maps всегда положительное число. Более подробно про сжатие карт номалей можно почитать тут и тут
Так как R компонента пустует, то её можно использовать для хранения чего-то полезного (но не критичного к качеству). В Jericho данный канал текстуры хранит низкочастотное значение высоты, или, если говорить иностранным языком - low frequency height map. Используется данный канал для самого простого параллакс маппинга. Ни Parallax Occlusion Mapping (URL), ни Relief Mapping не реализованы. Канал B текстуры не используется.
Height map:


Также присутствует specular map:


Кубемапа с бликами приассоциированная к объекту (для оружия например):


Также используется кубемапа привязанная к висящим на потолке фонарикам.
Для правильной интерпретации цвета, которая должна давать последняя кубемапа, в шейдер передается также матрица положения соответствующего физического объекта. Таким образом трансформируя вектор направления «рисуемый объект» -> «фонарь» с помощью этой матрицы мы получаем красивенькие динамические блики на объектах вокруг данного светоизлучателя:


Сцена с одним источником:

с двумя:

с тремя:


После всех проходов геометрии, рисуется вода. Вернее, это та субстанция похожая на кровь, которая в изобилии встречается на демоуровне. Тут применяются 3 скроллящиеся с разными скоростями и в разные стороны карты нормалей. В общем ничего примечательного.

Далее идут частицы, которые забатчены довольно большими группами. К слову много частиц рисуется с аддитивным блендингом, создавая таким образом эффект volumetric light and fog.
До партиклов:

После партиклов:


Depth of Field. Для достижения данного эффекта сцена даунсемплится в РТ размером ¼ от оригинального, а затем 2 раза размывается. Полученная текстура комбинируется с исходным изображением, используя метод описанный ребятами из АТИ в ShaderX3. Ближняя плоскость, дальняя плоскость, фокусное расстояние, leak reduction используя scene depth texture – всё присутствует. Хочу отметить, что фокусное расстояние определяется динамически, в зависимости от объекта на который мы сейчас смотрим (простое пересечения луча с ближайшим объектом). Этим достигается плавное изменение степени заблуривания объектов.
Как я и предполагал, качество видео в Youtube не позволит проиллюстрировать DoF с переменным фокусным расстоянием, поэтому будет 2 картиночки (обратите внимание на дальнюю освещенную колонну):



После DoF идут т.н. “image distortion” пост-процесс эффекты. Подход достаточно оригинален и необычен. В отдельную ARGB8 текстуру рисуются все смещения текстурных координат (используются нормал мапы), которые должны искажать картинку. Это и эффект мокрого экрана (капли на стекле), и heat-haze от огня и эффект телекинеза. Затем используя полученную динамическую карту смещений и изображение сцены полученной на предыдущих шагах делаем distortion эффекты.
Динамическая карта смещений:

Полученная картинка.


Следующим идёт генерация velocity буфера для motion blur эффекта.
Подход такой же как и во многих других играх. В шейдер передаются предыдущая и текущая матрицы трансформации. После их применения вычисляется вектор смещения в XY плоскости, который записывается в ARGB8 текстуру. Дабы увеличить точность значений и зря не расходовать память а R канале содержится +Х, в G –X. В каналах B и A содержится +Y и –Y соответственно.
Визуализация velocity буфера в момент включения зума на снайперке у Black (она один из 3-х играбельных персонажей в демке).


На следующем этапе используя полученный буфер размываем изображение:
соответственное размытое изображение

и видео:


На следующем шаге идет очередной пост-процесс эффект. Сцена даунсемплится и размывается в несколько шагов до 1х1 изображения в котором хранится средняя яркость. Используя эту мини-текстуру выполняется bright pass, или говоря нашим, родным языком, выделяются яркие области. Текстура с яркими областями подвергается «диагональному» размыванию в виде буквы Х. Вверх-вправо, вверх-влево, вниз-вправо, вниз-влево. Полученные лучи крестообразных бликов собираются в одно изображение и блендится с оригинальной картинкой.

Обратите внимание на glow в районе руки:


Последни пунктом идет UI, которого совсем немного.

С 5-ю активными источниками получается где-то 1800 dip’ов и до 400К полигонов в кадре. Средние значения: 1200 draw calls и 200K полигонов. Вся геометрия в невыровненных вертекс-форматах, хотя данные немного сжаты: позиция во float3 и нормали в short4n. В движке хорошая сортировка как по шейдерам, так и по текстурам. ЦПУ в драйвере не сидит, что тоже хорошо. Смущает только объем загруженных в видеопамять текстур. Аж 550 мегабайт. Вот вам и хай-энд :)

В послесловии я хочу подлиться своими соображениями по поводу многопроходности. Раньше я думал, что с длинными шейдерами данный подход себя изжил. Но данный реверс отчетливо показал, что мои выводы были преждевременными. Главное это бороться за минимизацию pixel-processing overhead и количество батчей. Рендер Clive Barker’s Jericho демонстрирует отличные показатели по обоим пунктам.
comments: Оставить комментарий Previous Entry Поделиться Next Entry


murkt
Link:(Link)
Time:2007-10-12 01:23 pm
Текстура с яркими областями подвергается «диагональному» размыванию в виде буквы Х. Вверх-вправо, вверх-влево, вниз-вправо, вниз-влево. Полученные лучи крестообразных бликов собираются в одно изображение и блендится с оригинальной картинкой.

Ээээ... Имеется в виду, что области, которые светятся - они светятся не равномерным ореолом, а диагональными лучами? Что-то этот момент до меня туго доходит.
(Ответить) (Thread)


__vortex__
Link:(Link)
Time:2007-10-12 01:26 pm
Ага. На картинке это плохо видно, надо смотреть в игре в динамике.
(Ответить) (Развернуть) (Parent) (Thread)


zeux
Link:(Link)
Time:2007-10-12 02:22 pm
Спасибо.

1. distortion - ровно так же в сталкере, нет?

2.
> Дабы увеличить точность значений и зря не расходовать память а R канале содержится +Х, в G –X.
> В каналах B и A содержится +Y и –Y соответственно.
Не понятно, по какой причине увеличивается точность и что именно таки хранится в каналах.

3.
> Рендер Clive Barker’s Jericho демонстрирует отличные показатели по обоим пунктам.
1800 дипов это отличные показатели? :)
(Ответить) (Thread)


__vortex__
Link:(Link)
Time:2007-10-12 03:26 pm
> 1. distortion - ровно так же в сталкере, нет?
Ой, я не помню как в сталкере. И я не помню упоминал ли ты эт ов своем реверсе. :)

> 2. Не понятно, по какой причине увеличивается точность и что именно таки хранится в каналах.
Было у меня чувство, что не так поймут. :) Для Х. Если значение больше 0 то идет в R, если меньше 0 то абсолютное значение идет в G. Т.е. мы range [-1,1] пакуем не в один 8-и битный канал, а в два.

> 1800 дипов это отличные показатели? :)
Ээээ. 5 проходов на освещение, first z-pass и velocity буфер. Считаю, что для 7 проходов неплохо. Обычно источников 1-2, в таких случаях 1000-1200.
(Ответить) (Развернуть) (Parent) (Thread)


justbacek
Link:(Link)
Time:2007-10-15 06:31 am
Большое спасибо. Слушай, мне кажется, было бы очень интересно всем почитать про сталкера. Что ты тоб этом думаешь?
(Ответить) (Thread)


tagvardthinks
Link:(Link)
Time:2007-10-17 08:23 am
> Сцена даунсемплится и размывается в несколько шагов до 1х1 изображения в котором хранится средняя яркость. Используя эту мини-текстуру выполняется bright pass, или говоря нашим, родным языком, выделяются яркие области.

Правильно я понимаю, что весь рендер до этого идет в RT ARGB8888-формата? Т.е. исходник для брайт-пасса 8-ми битный у них? Если так, пишут ли в альфу какую-то инфу вроде овербрайта?
(Ответить) (Thread)


__vortex__
Link:(Link)
Time:2007-10-17 10:31 am
> Правильно я понимаю, что весь рендер до этого идет в RT ARGB8888-формата?
Не совсем. Картинку даунсемплим в 1/4 размера. Тут ARGB. Затем в текстурку 64х64 формата R32F пишем grayscale, с коэффийиентами. Затем 16х16->4x4->2x2->1x1 (все R32F) просто устредняем соседей.
(Ответить) (Развернуть) (Parent) (Thread)

zemedelec
Link:(Link)
Time:2007-10-17 08:46 am
Симпатично зариверсил, спасибо. Познавательно так.
Особенно удивляет ниское количество геометрии - сколько из етих dip-ов skinned, можеш прикинуть? Особенно после motion blur-а... офигеть, как мало геометрии.
И как там со стримами, где-то больше одного есть? Типа как в UT - один на позицию, а все остальное во втором и кое-где третий, на per-instance per-vertex цвет.

Du/dv ето уже классика, кстати.

Также интересно про частицъ - там они мягкие, а все ли смотрят на камеру? Волюметрики вроде не должнъ. И если нет, то исчезают ли, когда dot(V,N) -> 0...?
(Ответить) (Thread)


__vortex__
Link:(Link)
Time:2007-10-17 10:40 am
> сколько из етих dip-ов skinned, можеш прикинуть?
5-6 на персонажа. Это 1 проход.

> И как там со стримами, где-то больше одного есть?
Нет, всё в одном стриме.

> Также интересно про частицъ - там они мягкие, а все ли смотрят на камеру? Волюметрики вроде не должнъ.
Мягкие. Те что ненавязчивые и практически незаметные (дымка например) то screen aligned. Те, что более видимые и чёткие (лучи света из дырки в крыше), выстроенны в виде хитрых структур. Концентрическими кольцами например. Пратиклы two-sided.

> И если нет, то исчезают ли, когда dot(V,N) -> 0...?
Партиклы не освещаются, и таких проверок видимости для них не делается. У них даже нормалей нет.
(Ответить) (Развернуть) (Parent) (Thread)

(Anonymous)
Subject:Спасибо!
Link:(Link)
Time:2007-10-19 07:00 am
Просто чудеснейший ресурс! Автор молодец ;-)

Добавляю в закладки
(Ответить) (Thread)


__vortex__
Subject:Re: Спасибо!
Link:(Link)
Time:2007-10-19 08:28 am
Рад полезности :)
(Ответить) (Parent) (Thread)

(Anonymous)
Link:(Link)
Time:2007-11-16 08:42 pm
Отличные статьи. Автору огромный респект.
Осталось только дождаться разбора рендера "Кризиса". Там они наворотили что-то невероятное и очень хочется узнать как это работает.
(Ответить) (Thread)

(Anonymous)
Link:(Link)
Time:2008-01-15 09:09 am
Уважаемый _vortex_, когда уже что-то свеженькое появится? :)) Нет сил ждать, т.к. всегда с удовольствием читаю твои статьи
(Ответить) (Развернуть) (Parent) (Thread)

kinddragon
Link:(Link)
Time:2008-06-07 04:29 pm
А куда картинки делись?
(Ответить) (Thread)

(Anonymous)
Link:(Link)
Time:2008-06-08 09:39 am
ImgageShack глючил тогда, я положил на другой какой-то хостинг. Хостинг оказался саксовый. Исправлю завтра.
(Ответить) (Развернуть) (Parent) (Thread)


golergka
Link:(Link)
Time:2008-06-10 11:37 am
Картинки убиты, можно обновить?
Пользуясь случаем, огромное спасибо за статьи :)
(Ответить) (Thread)


__vortex__
Link:(Link)
Time:2008-06-10 01:06 pm
Картинки исправил. Пожалуйста.
(Ответить) (Parent) (Thread)

[icon] Clive Barker's Jericho - Роман Марченко — ЖЖ
View:Свежие записи.
View:Архив.
View:Друзья.
View:Личная информация.