Вне границ в играх ААА


21

Во многих распространенных играх ААА (особенно в играх с движком исходного кода), когда игрок попадает в зону, не обслуживаемую, например, за пределы игрового поля или без щелчка по карте; странный эффект возникает на экране (разрыв буфера?).

Это можно описать как сходство со следом окон, которые Windows XP может оставить за перетаскиваемым окном, пока система зависает.

Могу только постулировать, что разработчики не очищают буфер цвета при обновлении экрана?

Это верно? Если так, то почему?


8
Кстати, это часто называют эффектом «Зала зеркал» или HOM.
Натан Рид

Ответы:


35

Когда-то очистка буферов цвета и глубины на самом деле занимала время. Выполнение очистки означало, что видеокарта должна пройти каждый пиксель кадрового буфера и записать в него значение.

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

Цветовой буфер легче всего игнорировать. Менее простым является буфер глубины, потому что он будет загрязнен старыми данными. Так что они сделали просто.

На кадре 0, они будут оказывать с glDepthRange(или D3D эквивалент) (0, 0,5), и они будут использовать glDepthFuncиз GL_LESS(или GL_LEQUAL). Это означает, что самое дальнее значение глубины, которое вы когда-либо получите в буфере глубины, равно 0,5. Таким образом, наибольшее значение в буфере глубины в конце кадра 0 составляет 0,5 (при условии, что вы записали каждый пиксель).

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

И тогда они повторяются.

На любом оборудовании, выпущенном примерно с 2003 года, это больше не является оптимизацией. Действительно, это отрицательная оптимизация . Очистка буфера глубины делает аппаратное обеспечение быстрее . Нет, правда.

По сути, происходит то, что очищающие буферы ничего не записывают. Они хранят некоторые биты в кэшах графического процессора, которые позволяют системе узнать, к какому цвету / глубине они были очищены. Когда система пытается записать в строку кэша кадрового буфера, она не удосуживается прочитать, что там, потому что она уже знает, что это пустое поле значения чистого цвета / глубины. Если вы попытаетесь смешать с тем, что есть, или проведете тест глубины, опять же, не нужно читать: он знает, какое значение смешивать / тестировать с / против.

Таким образом, каждое первое чтение / изменение / запись, которое вы выполняете в каждой строке кэша после очистки, - это в основном запись. Это бесплатно .

Кроме того, наличие зубчатого буфера глубины может работать против Hyper-Z / Hierarchial-Z / любых оптимизаций Z-отбора в аппаратном обеспечении. Да, ваша сцена будет работать против тех, кто со временем будет добавлять детали. Но если ваш буфер глубины выровнен по сравнению с предыдущими рендерингами, даже если эти фоновые объекты находятся в фоновом режиме, это может повлиять на эффективность методов Z-отбора. И это не поможет производительности.

Таким образом, вы никогда не должны делать эту технику изменения глубины в современных играх.

Примечание. Jari хорошо подходит для архитектур рендеринга на основе плиток (как в большинстве мобильных платформ). Не очистка глубины может сделать вещи там неприятными.


Ваше последнее утверждение подразумевает, что буфер глубины никогда не будет чередоваться или? Отличный ответ.
замедленная

1
@ Даниель Да. Я уточнил свой пост.
Николь Болас

3
Кроме того, пропуск архитектуры очистки (как и большинство чипов OpenGL ES) приводит к значительным потерям производительности, поскольку графический чип не может делать предположения о состоянии цветового буфера.
Яри ​​Комппа

5

Да, вы правы, что задний буфер не очищается.

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

Таким образом, при нулевой стоимости вы экономите один буфер на кадр.


1
Я не знаю о глубоком пинг-понге; каждый движок, с которым я знаком, очищает буфер глубины / трафарета для каждого кадра. Но кроме этого, да, если игра отображает все пиксели (как и должно быть), вам не нужно очищать буфер цвета.
Натан Рид

Не могли бы вы привести пример для шейдера, хороший ответ в противном случае.
замедленная

1
Я понимаю, что вы спрашиваете о последних движках, читая комментарий @ NathanReed о том, сколько движков только для ПК работает сейчас. Поворот Z-буфера - более старая техника, я посмотрю, смогу ли я найти ссылку. Консольные движки также в основном очищают весь цветовой буфер, даже один пиксель, показывающий эффект HOM, названный Натаном, провалит заголовок и заставит его снова проходить через представления.
Патрик Хьюз
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.