2012-11-23 21 views
6

Moje shadery często mają wiele takich samych funkcji. Na przykład obliczenie oświetlenia rozproszonego/lustrzanego. Chciałbym napisać to raz, a następnie ponownie użyć kodu w różnych shaderów.Jak napisać wielokrotny kod glsl?

Glsl nie ma wiedzy o plikach i nie obsługuje dyrektywy typu preprocesora typu C, takiej jak #include.

Wiem, że glsl obsługuje kompilację kodu źródłowego z wielu metod, ale skąd wiadomo, które fragmenty dołączyć? Czy wdrażasz własną wersję dodatku? A może tworzysz jakiś metaplik dla każdego swojego shadera?

Odpowiedz

4

W dużych projektach moduł cieniujący jest często montowany przy pierwszym uruchomieniu (lub w przypadku zmiany opcji graficznych), więc zawiera wszystkie funkcje specyficzne dla danego dostawcy i są zoptymalizowane pod kątem maszyny użytkownika i ustawień. I nie tylko shader, ale także kilka etapów renderowania.
Możesz traktować GLSL jako kod HTML \ CSS \ JavaSript, który wymiotuje skrypt PHP w odpowiedzi na żądanie. I możesz użyć tych samych technik, co "stopienie", zastrzyki kodu (na przykład ilość sprawdzania tekstury) w pętlach. Jest to również dobre dla grafików, ponieważ mają one prostą kontrolę nad źródłem cieniowania poprzez parametryzację - książeczkę czekową, pola wprowadzania itp. I mogą tworzyć unikalne moduły cieniowania dla unikalnych przypadków.

1

Mam niestandardowe rozwiązanie oparte na http://blackpixel.com/blog/494/xcode-using-includes-in-opengl-shaders/ [404 teraz]. Zasadniczo powiedział, że można użyć narzędzia m4 do wstępnego przetwarzania plików.

w plikach źródłowych GLSL właśnie to pożądany fragment, który chcesz ponownie użyć:

include(Utils.glsl) 
include(Colors.glsl) 

... 

void main (void) { 
    ... 
} 

w Xcode, dodaj wszystkie glsl plików „Kopiuj Bundle Zasoby”.

Dodaj „Run Script” fazę z tego skryptu powłoki:

#!/bin/sh 

cd ${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME} 
find . -name "*.fsh" | while read file; do 
    echo Preprocess $file 
    m4 "$file" > "$file.tmp" 
    mv "$file.tmp" "$file" 
done 

exit 0 

Scenariusz zakłada twoi shadery mają .fsh rozszerzenie. Zmodyfikowanie go tak, aby pasowało do rozszerzeń modułu cieniującego, jest banalne.

Ostrzegam: twoje shadery będą łatwo dostępne dla prawie każdego. Możesz go używać do programowania i konwertować na ciągi przed ich zwolnieniem (nie jest to prawdziwa ochrona, chyba że zaszyfrujesz ...).

Ponadto, jeśli nie ma większego współdzielenia między shaderów, otrzymasz wiele nieużywanych kodów. Domyślam się, że kompilator shaderów zaopiekuje się nim, ale nie jestem w 100% pewien, czy jest jakaś kara za wydajność.