Poza granicami w grach AAA

21

W wielu popularnych tytułach AAA (szczególnie gry z silnikiem Source), gdy gracz osiąga obszar „bez wyżywienia”, na przykład poza granicami lub nocowanie pod mapą; na ekranie pojawia się dziwny efekt (rozrywanie bufora?).

Można to opisać jako podobne do śladu okien, które Windows XP może pozostawić podczas przeciągania okna, gdy system się zawiesza.

Mogę jedynie postulować, że programiści nie usuwają bufora kolorów podczas odświeżania ekranu?

Czy to jest poprawne? Jeśli tak, dlaczego?

zwalniał
źródło
8
BTW, często nazywa się to efektem „Hall of Mirrors” lub HOM.
Nathan Reed,

Odpowiedzi:

35

Dawno, dawno temu wyczyszczenie buforów koloru i głębokości zabierało dużo czasu. Zrobienie tego oznaczało, że karta graficzna będzie musiała przejść każdy piksel bufora ramki i zapisać do niego wartość.

Z tego powodu twórcy gier stwierdzili, że bardziej efektywne byłoby po prostu założenie, że każdy piksel zostanie zrenderowany. Opracowali wiele technik, aby to zrobić.

Bufor kolorów jest najłatwiejszy do zignorowania. Mniej łatwy jest bufor głębokości, ponieważ zostałby zanieczyszczony starymi danymi. To, co zrobili, było proste.

Na ramie 0, stałoby się z glDepthRange(lub ekwiwalent D3D I) (0, 0,5), i ich użyć glDepthFuncz GL_LESS(lubGL_LEQUAL ). Oznacza to, że najdalsza wartość głębokości, jaką kiedykolwiek uzyskasz w buforze głębokości, to 0,5. Zatem największa wartość w buforze głębokości na końcu ramki 0 wynosi 0,5 (zakładając, że zapisałeś każdy piksel).

W ramce 1 zmieniliby zakres głębokości na (1, 0,5). Zauważ, że w tym przypadku wartość głębokości bliskiej jest większa niż głębokość dalekiej. Ale zmieniliby także funkcję głębokości na GL_GREATER(lub GL_GEQUAL), co odwraca znaczenie testu głębokości. Ponieważ największa wartość w buforze głębokości wynosi 0,5, wszystko, co napiszesz, będzie miało większą wartość . Ponieważ test głębokości został odwrócony, oznacza to, że wszystko, co zostało zapisane w ramce 0, jest teraz dalej niż wszystko, co mogłoby być zapisane w ramce 1. Na końcu ramki 1, najmniejszy wartość w buforze głębokości wynosi teraz 0,5.

A potem się powtarzają.

Na każdym sprzęcie wyprodukowanym od około 2003 r. Nie jest to już optymalizacja. Rzeczywiście, jest to optymalizacja negatywna . Wyczyszczenie bufora głębokości przyspiesza sprzęt . Nie naprawdę.

Zasadniczo dzieje się tak, że czyszczenie buforów tak naprawdę nic nie pisze. Przechowują niektóre bity w pamięci podręcznej GPU, które informują system o tym, do jakiego koloru / głębi zostały usunięte. Kiedy system próbuje zapisać do linii bufora ramki, nie zawraca sobie głowy czytaniem, co tam jest, ponieważ już wie, że jest to puste pole o wyraźnej wartości koloru / głębokości. Jeśli spróbujesz połączyć się z tym, co tam jest lub wykonasz test głębokości, znowu nie musisz czytać: wie, jaką wartość należy mieszać / testować z / przeciw.

Więc każdy pierwszy odczyt / modyfikacja / zapis, który wykonujesz w każdej linii pamięci podręcznej po wyczyszczeniu, jest w zasadzie zapisem. Jest za darmo .

Co więcej, posiadanie poszarpanego bufora głębokości może działać przeciwko Hyper-Z / Hierarchial-Z / dowolnej optymalizacji sprzętowej. Tak, twoja scena będzie działać przeciwko tym ostatecznie, gdy dodasz szczegóły. Ale jeśli bufor głębokości jest postrzępiony w porównaniu z poprzednimi renderingami, nawet jeśli te obiekty w tle znajdują się w tle, może to wpłynąć na efektywność technik cullingu. I to nie pomoże wydajności.

Więc nigdy nie powinieneś wykonywać tej techniki odwracania głębi we współczesnych grach.

Uwaga: Jari ma dobrą opinię na temat architektur renderowania opartych na kafelkach (jak w większości platform mobilnych). Nie wyczyszczenie głębokości może również sprawić, że będzie tam nieprzyjemnie.

Nicol Bolas
źródło
Czy twoje ostatnie stwierdzenie sugeruje, że nigdy nie zmieniaj bufora głębokości na przemian? Świetna odpowiedź.
deceleratedcaviar
1
@Daniel Tak. Wyjaśniłem swój post.
Nicol Bolas,
3
Dodatkowo pominięcie wyraźnej architektury binowania (jak większość układów OpenGL ES) powoduje ogromną utratę wydajności, ponieważ układ graficzny nie może przyjmować założeń dotyczących stanu bufora kolorów.
Jari Komppa,
5

Tak, masz rację, że bufor tylny nie jest czyszczony.

Dlaczego, ponieważ (głównie) szybsze jest korzystanie z niestandardowego modułu cieniującego, który pinguje wartości głębokości ping-ponga w przeciwnych kierunkach dla każdej klatki i polega na tym, że gra zawsze renderuje każdy piksel na ekranie.

Dzięki temu przy zerowym koszcie oszczędzasz jeden bufor na klatkę.

Patrick Hughes
źródło
1
Nie wiem o głębokim ping-pongu; każdy silnik, który znam, czyści bufor głębokości / matrycy dla każdej klatki. Ale poza tym, tak, jeśli gra renderuje wszystkie piksele (tak jak powinno), nie musisz czyścić bufora kolorów.
Nathan Reed,
Czy możesz podać przykład modułu cieniującego, w przeciwnym razie dobra odpowiedź.
deceleratedcaviar
1
Zdaję sobie sprawę, że pytasz o najnowsze silniki, czytając komentarz @ NathanReed, ile silników teraz działa na PC. Skręt bufora Z jest starszą techniką, zobaczę, czy mogę znaleźć referencję. Silniki konsolowe w większości usuwają również cały bufor kolorów, nawet jeden piksel pokazujący efekt HOM nazwany przez Nathana utraci tytuł i zmusi go do ponownego przesłania zgłoszeń.
Patrick Hughes,