Shadery a sprawa preprocesora

Uwaga! Informacje na tej stronie mają ponad 5 lat. Nadal je udostępniam, ale prawdopodobnie nie odzwierciedlają one mojej aktualnej wiedzy ani przekonań.

# Shadery a sprawa preprocesora

Sun
19
Aug 2007

Fakt nr 1 - shadery warto pisać w HLSL albo innym tego typu języku. Kompilatory generują dobry kod, więc nie ma sensu babrać się w czystym asemblerze. Fakt nr 2 - shaderów potrzeba wiele. Najlepiej, żeby można było generować nowe shadery z różnych kombinacji jakiś swoich ustawień. Niektórzy radzą sobie bez tego, ale ja nie wyobrażam sobie jak. Shadery zastępują przecież niektóre ustawienia renderowania z dawnego nieprogramowalnego potoku i tak też na nie patrzę - jak na własny potok sterowany ustawieniami. Mają przy tym tą zaskakującą na początku nauki cechę, że nie można ich łączyć - na raz może być ustawiony jeden shader, który musi zawierać wszystko, co jest do zrobienia na wierzchołku albo pikselu.

Rozwiązaniem jest dołączenie do gry źródła shadera (np. pliku FX) i jego kompilacja w czasie ładowania albo w czasie samej gry, w razie potrzeby, z odpowiednimi ustawieniami. Jak odwzorować to w kodzie shadera? Opcje są dwie, a nawet trzy.

Ta, która dla mnie odpada natychmiast to skorzystanie z instrukcji warunkowych Static Branching. Po co marnować cenny czas na instrukcje sprawdzania warunku, który zawsze będzie niespełniony, jeśli można wygenerować osobny shader, który danego kodu po prostu nie zawiera?

Opcja pierwsza to wstawienie do kodu dyrektyw warunkowych preprocesora typu #ifdef (OPCJA == 1), gdzie OPCJA będzie makrem przekazywanym jako parametr podczas kompilacji shadera. Opcja druga to wstawienie do kodu warunków typu if (OPCJA == 1), gdzie OPCJA również będzie makrem. Obydwa rozwiązania wygenerują równie dobry kod. To drugie wydaje się przy tym bardzie eleganckie.

Niestety ma jedną wadę. O ile fragmenty kodu można objąć w if (OPCJA == 1), o tyle czegoś takiego nie można napisać dla pól struktury definiującej dane przekazywane z VS do PS. Tam natomiast muszą występować różne pola, niektóre nieużywane, zależnie od parametrów kompilacji danego shadera. Każde takie pole natomiast, nawet jeśli nieużywane, musi być wypełniane przez VS, choćby samymi zerami (swoją drogą - cóż za bzdura! - to powinno generować ostrzeżenie a nie błąd kompilacji), a to kosztuje dodatkową, niepotrzebną instrukcję w VS.

Toteż pozostaje objąć te nie zawsze wykorzystywane pola struktury w dyrektywy #ifdef. Skoro przy niektórych wartościach makr w ogóle ich nie będzie, to nie można też ich wtedy używać w kodzie. Tak więc warunki w kodzie też trzeba wtedy objąć w #ifdef zamiast w if. Co Należało Dowieść :) Tak też mam zrobione u siebie.

Comments | #rendering #directx Share

Comments

STAT NO AD
[Stat] [STAT NO AD] [Download] [Dropbox] [pub] [Mirror] [Privacy policy]
Copyright © 2004-2019