2013-07-01 5 views
11

Sto guardando il sorgente di un'applicazione OpenGL che usa shader. Uno shader particolare si presenta così:Valori float costanti negli shader GLSL: qualsiasi motivo per utilizzare le uniformi?

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

L'uniforme viene impostata una volta dal codice e non cambia mai durante il tempo di esecuzione dell'applicazione.

In quali casi, desidero dichiarare someConstantValue come uniform e non come const float?

Modifica: Giusto per chiarire, il valore costante è una costante fisica.

risposta

7

Prima di tutto, la differenza di prestazioni tra l'utilizzo di un'uniforme o di una costante è probabilmente trascurabile. In secondo luogo, solo perché un valore è sempre costante in natura non significa che vorrete sempre che sia costante nel vostro programma. I programmatori spesso modificano i valori fisici per produrre il risultato migliore, anche quando ciò non corrisponde alla realtà. Ad esempio, l'accelerazione dovuta alla gravità è spesso aumentata in certi tipi di giochi per renderli più veloci.

Se non si vuole avere a impostare l'uniforme nel codice si potrebbe fornire un valore di default in GLSL:

uniform float someConstantValue = 12.5; 

Detto questo, non v'è alcun motivo per non utilizzare const per qualcosa come pi dove ci sarebbe poco valore modificandolo ....

+3

"la differenza di prestazioni tra l'utilizzo di un'uniforme o di una costante è ** probabilmente ** trascurabile" Non è consigliabile indovinare. La dichiarazione di un valore costante consente al compilatore GLSL di eseguire ottimizzazioni che altrimenti non sarebbero possibili. Purtroppo, i compilatori GLSL tendono ad avere bug e comportarsi in modi imprevedibili. Quindi una risposta generale in realtà non è possibile. Ho riscontrato gravi differenze nelle prestazioni tra l'utilizzo di array const e non-const (a seconda della loro lunghezza) anche se il loro valore non verrà mai modificato. Presumo che questo sia un bug del compilatore. – Tara

+0

Sebbene il commento precedente fosse probabilmente accurato al momento, ora è possibile attendersi questo tipo di compilazione just-in-time. I valori uniformi possono essere ottimizzati come se fossero costanti. Vedi [questo] (https://www.khronos.org/opengl/wiki/Core_Language_ (GLSL) #Dynamically_uniform_expression) per maggiori informazioni. –

1

posso pensare a due ragioni:

  1. Lo sviluppatore riutilizza una libreria di shader in diverse applicazioni. Quindi, invece di personalizzare ogni shader per ogni app, lo sviluppatore cerca di mantenerle generali.

  2. Lo sviluppatore prevede che questa variabile sarà in seguito un'impostazione controllata dall'utente. Quindi dichiararlo uniforme è la preparazione per quella caratteristica imminente.

Se fossi lo sviluppatore e nessuno di questi casi la quindi vorrei dichiareremo come "const" invece perché può dare un miglioramento delle prestazioni e non avrebbe dovuto impostare la divisa dal mio codice.

15

ragione enorme:

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

Se uso:

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

ottengo un errore perché myfloat non è un constant expression.


Tuttavia questo è perfettamente valida:

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

Perché?

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

Questi casi sono molto rari e compaiono negli shader computali più di ogni altra cosa (e in alcuni sistemi di animazione scheletrica). –

+1

In questi giorni, ci si può aspettare che i moderni OpenGL e D3D eseguano la compilazione just-in-time per valori uniformi (qualsiasi valore che non viene modificato per la durata di * una * chiamata di rendering). Ad esempio, un'istruzione if che controlla una variabile uniforme booleana verrà compilata quando viene avviata la chiamata di rendering - nessun controllo di runtime verrà eseguito sulla GPU. Vedi [questo wiki] (https://www.khronos.org/opengl/wiki/Core_Language_ (GLSL) #Dynamically_uniform_expression) per ulteriori informazioni. –

+0

Questo sta rispondendo all'opposto della domanda - OP vuole sapere perché useresti una divisa invece di una const, non il contrario. – Karu

Problemi correlati