8

EDYCJA: Ciągle szukam pomocy w korzystaniu z shaderów OpenCL lub Compute. Wolałbym nadal używać OGL 3.3 i nie musieć radzić sobie ze złym wsparciem dla sterowników dla OGL 4.3 i OpenCL 1.2, ale nie mogę w ogóle myśleć o tym rodzaju cieniowania bez użycia jednego z dwóch (aby dopasować światła i płytki). Czy można zastosować utylizację płytkową bez użycia GPGPU?Odroczone renderowanie z ubożeniem opartym na kaflach

Napisałem odroczony render w OpenGL 3.3. W tej chwili nie robię żadnego uboju dla przejścia światła (po prostu wykonuję quad na pełnym ekranie dla każdego światła). To (oczywiście) ma mnóstwo overdraw. (Czasami wynosi ~ 100%). Z tego powodu szukałem sposobów na poprawę wydajności podczas lekkiego przejścia. Wygląda na to, że najlepszym sposobem (prawie) wszystkim jest wyłapanie sceny za pomocą kafelków ekranu. Taka była metoda zastosowana w Frostbite 2. Czytałem prezentację Andrew Lauritzena podczas SIGGRAPH 2010 (http://download-software.intel.com/sites/default/files/m/d/4/1/d/8/lauritzen_deferred_shading_siggraph_2010.pdf) i nie jestem pewien, czy w pełni rozumiem tę koncepcję. (i dlatego, że jest to lepsze niż cokolwiek innego, i jeśli jest to dla mnie lepsze)

W prezentacji Laurtizen przechodzi odroczone cieniowanie z lekkimi objętościami, quadami i kaflami w celu ubożenia sceny. Według jego danych, oparty na kaflu odroczony renderer był najszybszy (zdecydowanie). Nie rozumiem, dlaczego tak jest. Zgaduję, że ma to coś wspólnego z tym, że dla każdego kafelka wszystkie światła są grupowane razem. W prezentacji mówi, żeby raz odczytać G-Buffer, a potem obliczyć oświetlenie, ale to nie ma dla mnie sensu. Moim zdaniem, mógłbym to zaimplementować w następujący sposób:

for each tile { 
    for each light effecting the tile { 
    render quad (the tile) and compute lighting 
    blend with previous tiles (GL_ONE, GL_ONE) 
    } 
} 

Wciąż wymagałoby to pobierania próbek G-Buffer. Sądzę, że robienie tego miałoby taką samą (jeśli nie gorszą) wydajność, niż renderowanie kwadratu dla każdego światła. Od tego, jak to brzmi, choć wydaje się, że to, co się dzieje:

for each tile { 
render quad (the tile) and compute all lights 
} 

Ale ja nie rozumiem, jak można by to zrobić bez przekroczenia limitu instrukcji dla shadera fragmentów w niektórych procesorach graficznych. Czy ktoś może mi w tym pomóc? Wydaje się również, że prawie każdy oparty na odroczonej rendererze używa procesorów Compute lub OpenCL (do grupowania świateł), dlaczego tak jest, a gdybym nie używał tych rzeczy, co by się stało?

Odpowiedz

3

Ale nie widzę, jak można to zrobić bez przekraczania limitu instrukcji dla modułu cieniującego w niektórych procesorach graficznych.

To zależy od tego, ile masz świateł. "Granice instrukcji" są dość wysokie; na ogół nie jest to coś, o co musisz się martwić poza zdegenerowanymi przypadkami. Nawet jeśli 100+ świateł wpływa na płytki, szanse na to, że twoje obliczenia świetlne nie przekroczą limitów instrukcji, są dość wysokie.

Nowoczesny sprzęt GL 3.3 może uruchomić co najmniej 65536 dynamicznych instrukcji w module cieniowania fragmentów i prawdopodobnie więcej. Dla 100 świateł, wciąż jest 655 instrukcji na światło. Nawet jeśli weźmiesz 2000 instrukcji do obliczenia pozycji w przestrzeni kamery, to wciąż pozostawia 635 instrukcji na światło. Nawet jeśli robiłeś Cook-Torrance bezpośrednio w GPU, to prawdopodobnie nadal wystarczy.

+0

Interesujące. W pewnym momencie obliczyłem więcej niż jedno światło na moduł cieniujący (7) i na niektórych kartach graficznych (w szczególności na laptopach średniej i wyższej klasy, takich jak GT 540) wydawało się, że przekroczyłem limit instrukcji. Doszedłem do tego wniosku przez wiele prób i błąd, i zapytałem o to w jednym z moich wcześniejszych postów. Czy się myliłem? – Spaceman1701

+1

W rzeczywistości doświadczyłem tego samego problemu przy użyciu NVidia 8600GT. Dotarłem do limitu z 20 światłami. Jakiego rodzaju sprzętu @NicolBolas mówisz? –

+0

Mam nadzieję, że będę miał czas na wdrożenie go w ten weekend. Zobaczę, co się stanie. – Spaceman1701

Powiązane problemy