@Zeux: GDC Report – The Rendering Technologies of Crysis 3 – Tiago Sousa (Crytek)

Слайды к докладу здесь – http://crytek.com/cryengine/presentations/the-rendering-technologies-of-crysis-3

People in this conversation:
Arseny Kapoulkine (Zeux) Add
CREAT Studios, Saber3D, Sperasoft (EA Sports – FIFA). Currently making kids happy at ROBLOX. http://zeuxcg.org/

Zeux: The Rendering Technologies of Crysis 3 – Tiago Sousa (Crytek)
В целом у меня создалось впечатление что Тиаго весь этот рендер уже давно задолбал, ну или рассказывать про него по крайней мере :)
Значит, основные изменения в рендере Крайзис 3! (для тех, кто знает что-нибудь про Крайзис 2)

На проекте была маленькая команда программистов, рендер отдел был 2 человека
Поэтому ставился упор на фичи которые работают везде одинаково, либо на DX11 only фичи – их проще тестировать

Итак, во-первых, освещение!
В Крайзис 2 пришли к схеме deferred lighting
aka light pre-pass rendering
В первом проходе заполняется глубина и RT в которой есть нормаль и specular power
Дальше идет deferred освещение
Дальше идет еще один проход геометрии, в котором читается результат освещения и применяется albedo/etc.
Вот кажется линк про подробности “как было раньше” – http://www.crytek.com/download/A_bit_more_deferred_-_CryEngine3.ppt

Значит, новый релиз крайзиса – новый тек! Два прохода геометрии жаба душит, хочется один проход
Толстый gbuffer не хочется, хочется тонкий
Итого получился deferred shading!
Детали такие:
g-buffer это 2 ARGB8 RT + глубина и стенсиль
В стенсиле разные теги – зоны с разным ambient освещением, движущиеся объекты (??) и еще наверное всякое по вкусу.
8 каналов g-buffer распределены так:
- 2 канала – normal x/y
- 1 канал – 1 бит normal Z sign и 7 бит – gloss aka spec power
- 2 канала – albedo (см. ниже)
- 1 канал – specular intensity (не полный цвет)
- 1 канал – альфа (translucency) для блендинга
- оставшийся канал – доп. инфа которая могла варьироваться на разных проектах
Типа доп. свойство материала или ambient occlusion или еще что-то в таком духе.

Итак, как же в 2 канала влезает albedo?
Цвет мы кодируем в YCbCr, Y мы храним в полном разрешении, CbCr – используем chrominance subsampling, храня как я понял одно в четных пикселях а второе в нечетных
(стандартная техника сжатия, еще формат такой был в DX9)
Нормаль – XY хранится в стереографической проекции? (http://aras-p.info/texts/CompactNormalStorage.html#method07stereo не знаю откуда еще знак)

Дальше идет deferred rendering методом, использованным сначала в STALKER – после того, как мы заполнили G-Buffer
Мы рендерим шейпы лайтов, заполняя не сразу output, а light accumulation buffer
В Крайзисе 3 это 2 RT формата R11G11B10F
(диффуз и спекуляр)
Дальше полноэкранный квад который на основе g-buffer и light accumulation buffer считает финальный результат.
Есть сложные материалы, волосы и кожа – для них меш рендерится еще раз после полноэкранного квада
С более сложным шейдером, который тоже использует light accumulation buffer.
Т.е. в STALKER это была исходная схема, а в Crysis 3 как я понял к ней пришли через полный deferred lighting.
G-buffer запакован относительно скромно (каналы не перемешаны) чтобы иметь возможность вбленживать в него всякое.

Так, с базой все, теперь эффекты.
Эффект раз – Silhouette Parallax Occlusion Mapping – по-моему это то ли было в DX SDK то ли еще где-то. В GS треугольник на силуэте вытягивается в призму, в PS луч, соответствующий пикселю, переводится в пространство треугольника и проводится ray marching.
Техника дорогая, удивительно но оказалась уперта в GS а не в PS. Использовали на уровнях мало, будут стараться использовать больше.

Эффект два – объемный туман с тенями. По-моему плохо рассказан, я не буду говорить за детали т.к. точно навру…
Там в целом просто в каждом пикселе на уменьшенном разрешении делается несколько семплов из shadow map, они комбинируются как-то чтобы получить shadow factor, а потом это все апскейлится до полного разрешения с bilateral фильтром. Но была какая-то мощная идея про кажется reuse результатов в пределах 8х8 решетки, но я ее во-первых не понял, а во-вторых потом подошел спросил, и Тиаго мне ее не смог коротко объяснить, так что я в недоумении жду слайдов.

Эффект три – много травы.
Хотели много травы, симулирующейся физически.
Ничего интересного я не заметил – много листьев травы, каждый лист это несколько точек с spring constraints, написана коллизия со сферами (все примитивы мира аппроксимируются сферами для коллизий с травой)
Симулируется ветер, коллизии и force-fields
На CPU трансформируются инстансы (skinning) и запекаются в буферы (батчинг) примерно фиксированного в world-space размера
До 50к видимых инстансов (один инстанс – от травинки до чего-то более сложного), в инстансе от 18 до 3.6к вершин (don’t ask)
Каждый батч пересчитывается (симулируется), ближние батчи – каждый кадр, далекие – time slicing в зависимости от расстояния
Используется техника для менеджмента vertex/index буферов для этого добра, описанная на GDC 2012: Don’t Throw it All Away – Managing Buffers Efficiently. Speaker: John McDonald
Каждый батч считается отдельным job-ом в их job системе, в пике все это занимает 10-16 ms когда много травы (на разных платформах чуть по-разному).
Много травы – много overdraw; думали, как с этим побороться, ничего не придумали и заставляли артистов уменьшать площадь поверхности геометрии.

Последний кусок доклада был посвящен MSAA. На консолях у них FXAA, а на DX11 решили сделать честный MSAA, с упором на корректность а не на скорость.
Базовая реализация уже традиционна для deferred – отдельным resolve проходом вытягиваем из gbuffer нулевой семпл и строим маску, в которой 1/0 в зависимости от того, равны все семплы в пикселе нулевому или нет.
Дальше все full-screen проходы делаются дважды.
Первый раз на вход идет отрезолвленная текстура с нулевым семплом, по той маске (маска кладется в 0-й бит стенсиля)
Второй раз на вход идет MSAA буфер, и спец. шейдер который выполняется per-sample а не per-pixel (это фича DX10.1), и читает-пишет текущий семпл.
Так пришлось переработать много эффектов, т.к. большинство были не MSAA-aware
Дополнительная фишка – для alpha-test геометрии делать несколько семплов из alpha текстуры при шейдинге с правильными смещениями, каждый сравнивать с alpha threshold, и результирующую маску писать в SV_Coverage – это тоже DX10.1 техника, так MSAA начинает работать с альфа-тест геометрией (было освещено в AMD презентациях)
В качестве оптимизации для теней вместо того чтобы их считать per-sample для части пикселей, они всегда считаются только per-pixel, а затем bilateral upsample с полным z-buffer.
Soft-particles используют максимальную глубину из всех семплов в пикселей для alpha fade.

Ну и под конец Тиаго поплакался про жизненные проблемы
На PC все GPU профайлеры какие-то мало юзабельные, по сравнению с тем что есть на консолях
Хочется значит уже какой-нибудь качественный, который работает везде.
И, говорит, скоро big next generation leap – долой 10 year old console hardware, ура-ура, будем думать что с новым железом получится сделать
Ну и традиционно хочется хорошего realtime GI.
А, специально для касега – парни добавили в свой туман пару artist-controlled градиентов, типа “макс. плотность тумана на высоте A/мин. плотность на высоте B” и какие-то доп. параметры для тумана вокруг солнца.
Говорят, совсем не physically based, но так сильно просили что мы сдались и сделали.

Уф, про крайтек все! Дальше был coffee break, я тоже прервусь пожалуй.

Zeux: Еще Тиаго спросил, есть ли в аудитории кто из MS, и поскольку никто не признался, то в воздух поругался на документацию DX11, и спросил, когда уже DX12. Наивный…