2013-07-01 4 views
11

Patrzę na źródło aplikacji OpenGL, która używa cieniowania. Jeden szczególności shader wygląda następująco:Stałe wartości zmiennoprzecinkowe w modułach cieniujących GLSL - jakikolwiek powód używania uniformów?

uniform float someConstantValue; 
void main() 
{ 
    // Use someConstantValue 
} 

Mundur jest ustawiony raz z kodu i nie zmienia się w całym czasie wykonywania aplikacji.

W jakich przypadkach chciałbym zadeklarować someConstantValue jako uniform, a nie jako ?

Edytuj: Aby wyjaśnić, stała wartość jest stałą fizyczną.

Odpowiedz

7

Po pierwsze, różnica w wydajności między używaniem jednolitego lub stałego jest prawdopodobnie nieistotna. Po drugie, tylko dlatego, że wartość jest zawsze stała w naturze, nie oznacza, że ​​zawsze będziesz chciał, aby była ona stała w twoim programie. Programiści często dostosowują wartości fizyczne, aby uzyskać najlepiej wyglądający wynik, nawet jeśli nie jest to zgodne z rzeczywistością. Na przykład przyspieszenie spowodowane grawitacją jest często zwiększane w niektórych typach gier, aby były szybsze.

Jeśli nie chcemy mieć do ustalenia jednolitej w kodzie można podać wartość domyślną w GLSL:

uniform float someConstantValue = 12.5; 

Powiedział, że nie ma powodu, aby nie używać const czegoś podobnego pi tam gdzie byłoby niewielką wartość w modyfikacji ....

+3

"Różnica w wydajności między używaniem munduru lub stałej jest ** prawdopodobnie ** znikoma" Nie jest dobrze zgadywać. Deklaracja stałej wartości pozwala kompilatorowi GLSL wykonywać optymalizacje, które w przeciwnym razie nie byłyby możliwe. Niestety, kompilatory GLSL zwykle mają błędy i zachowują się w nieprzewidywalny sposób. Tak więc ogólna odpowiedź naprawdę nie jest możliwa. Napotkałem poważne różnice w wydajności między używaniem tablic stałych i niezmiennych (w zależności od ich długości), chociaż ich wartość nigdy nie zostanie zmodyfikowana. Zakładam, że jest to błąd kompilatora. – Tara

+0

Mimo że poprzedni komentarz był prawdopodobnie dokładny w tym czasie, można się teraz spodziewać tego typu kompilacji na czas. Jednolite wartości można zoptymalizować tak, jakby były stałymi. Zobacz [this] (https://www.khronos.org/opengl/wiki/Core_Language_ (GLSL) #Dynamically_uniform_expression), aby uzyskać więcej informacji. –

1

mogę myśleć o dwóch powodów:

  1. Deweloper ponownie wykorzystuje bibliotekę shaderów w wielu zastosowaniach. Zamiast dostosowywać każdy moduł cieniujący do każdej aplikacji, programiści próbują zachować ich ogólną.

  2. Deweloper przewiduje, że zmienna ta będzie później konfigurowana przez użytkownika. Stwierdzenie, że jest to uniform, jest przygotowaniem do tej nadchodzącej funkcji.

Gdybym był twórcą i żaden z powyższych punktów dotyczy to chciałbym zadeklarować ją jako „const” zamiast ponieważ może dać korzyści wydajności i nie będę musiał ustawić uniformu z mojego kodu.

15

Ogromne powodem:

Error: Loop index cannot be compared with non-constant expression.

Jeśli używam:

uniform float myfloat; 
... 
for (float i = 0.0; i < myfloat; i++) 

pojawia się błąd ponieważ myfloat nie jest constant expression.


Jednak ten jest całkowicie poprawny:

const float myfloat = 10.0; 
... 
for (float i = 0.0; i < myfloat; i++) 

Dlaczego?

When GLSL (and HLSL for that matter) are compiled to GPU assembly instructions, loops are unrolled in a very verbose (yet optimized using jumps, etc) way. Meaning the myfloat value is used during compile time to unroll the loop; if that value is a uniform (ie. can change each render call) then that loop cannot be unrolled until run time (and GPUs don't do that kind of JustInTime compilation, at least not in WebGL).

+1

Te przypadki są bardzo rzadkie i pojawiają się w modułach cieniujących Compute bardziej niż cokolwiek (i niektóre systemy animacji szkieletowej). –

+1

Obecnie można oczekiwać, że nowoczesne OpenGL i D3D wykonają kompilację "na czas" dla jednolitych wartości (każda wartość, która nie zostanie zmieniona na czas trwania * jednego * renderowania). Na przykład instrukcja if sprawdzająca jednorodną zmienną logiczną zostanie skompilowana po zainicjowaniu wywołania renderowania - nie zostanie wykonana kontrola czasu wykonywania w GPU. Aby uzyskać więcej informacji, zobacz [to wiki] (https://www.khronos.org/opengl/wiki/Core_Language_ (GLSL) #Dynamically_uniform_expression). –

+0

To odpowiada na przeciwieństwo pytania - OP chce wiedzieć, dlaczego używałbyś munduru zamiast stałej, a nie odwrotnie. – Karu

Powiązane problemy