2013-09-25 19 views
8

Così stavo esaminando il libro arancione (terza edizione) e ho trovato un passaggio nel capitolo 9 sul qualificatore invariante. E dice:Confusione circa il qualificatore invariante OpenGL

L'invariante qualificatore istruisce il compilatore e collegato ad ignorare le espressioni e le funzioni che non sono direttamente legate al calcolo della produzione.

Questo passaggio viene dopo due frammenti simili del codice:

uniform mat4 MVPmatrix; 
// ... 

in vec4 MCVertex; 
// ... 

a(); // does not modify gl_Position, MVP or MCVertex 

// ... 
// Transform vertex to clip space 
gl_Position = MVP * MCVertex; 

e

uniform mat4 MVPmatrix; 
// ... 

invariant gl_Position; 
in vec4 MCVertex; 
// ... 

a(); // does not modify gl_Position, MVP or MCVertex 

// ... 
// Transform vertex to clip space 
gl_Position = MVP * MCVertex; 

Il libro passa poi a stato:

Il primo caso può o potrebbe non calcolare le posizioni trasformate esattamente allo stesso modo, indipendentemente dalla funzione non correlata o l'espressione è collegata allo shader. Ciò può causare problemi nel rendering se si utilizza un algoritmo multipass per eseguire il rendering della stessa geometria più di una volta.

Quale mi ha confuso. Se a() non influisce in alcun modo sulle variabili coinvolte nel calcolo della posizione trasformata, in che modo il calcolo varia? (E in che modo esattamente l'aggiunta di invariant aiuta con quello?). E riferendosi alla prima citazione, cosa intendono esattamente con "ignorare le funzioni non correlate"? Non vengono semplicemente giustiziati?

risposta

8

Lo scopo di invariant è quello di assicurarsi che il calcolo che si sta eseguendo produrrà sempre lo stesso risultato, indipendentemente da ciò che lo shader optimizer farà allo shader (in particolare attraverso più compilazioni di shader).

Trovo che il fraseggio del libro arancione sia scadente (e fuorviante, come hai notato). Il paragrafo 4.6 specifica GLSL (lingua 1.2) è molto più chiara:

In questa sezione, varianza si riferisce alla possibilità di ottenere valori differenti dalla stessa espressione in diversi programmi. Per esempio , diciamo due vertex shader, in programmi diversi, ogni set gl_Position con la stessa espressione in entrambi gli shader ei valori di input in quella espressione sono gli stessi quando vengono eseguiti entrambi gli shader. È possibile , a causa della compilazione indipendente dei due shader, che i valori assegnati a gl_Position non siano esattamente identici quando si eseguono i due shader . In questo esempio, ciò può causare problemi con l'allineamento della geometria in un algoritmo a più passaggi. In generale, tale variazione tra gli shader è consentita. Quando tale varianza non esiste per una variabile di uscita specifica , quella variabile è detta invariante.

e si prosegue spiegando che il qualificatore invariant ottiene garanzie per evitare questo problema.

+0

Non penso che questo risponda all'origine due domande. e la citazione non blocca né – suitianshi

+0

@suitianshi: l'OP voleva capire l'invariante, e ha continuato a sezionare ciò che il libro arancione aveva da dire al riguardo. Il contenuto del libro arancione può essere sostanzialmente considerato sbagliato. Così ho scelto di rispondere dalla fonte originale, la specifica GLSL. Le domande originali stanno cercando di capire le affermazioni sbagliate. Quale risposta corretta vorresti? – Bahbar

+0

ho trovato una pagina che descrive il motivo per cui avremmo bisogno di un "invariante" a volte. Dice che il problema del multi-pass può essere causato dal riordino delle istruzioni della cpu (e qualcos'altro, mi spiace non ricordarlo chiaramente e non riesco a trovare di nuovo il contenuto). Ad esempio, se eseguo il rendering di un triangolo due volte con gli stessi programmi shader, ma durante i due passaggi ottengo il sonno o faccio shopping, i due triangoli risultanti potrebbero non sovrapporsi (ovviamente, l'offset può essere veramente piccolo). In realtà ho letto le specifiche GLSL, ma sono ancora confuso. – suitianshi

3

invariant parola chiave è, (in breve e in contrasto con la risposta più dettagliata di Bahbar) ulteriori informazioni sulle differenze computazionali molto sottili che potrebbero apparire, come hai già detto, più passaggi geometrici.

Ecco un esempio: Disegna un triangolo arbitrario, strano (per renderlo più difficile) sullo schermo. Il rasterizzatore ottiene i vertici normalizzati e calcola tutti i frammenti che occupa, quindi esegue uno shader di frammenti su di esso. Ora immagina che ti piacerebbe disegnare un altro triangolo esattamente sopra di esso, ma 3 ore più tardi, mentre il tuo PC è immerso, la temperatura cala e nel frattempo mangi un pranzo. Quindi ricompilate gli shader e bam ...

Tutti quelli potenzialmente possono influire sul rasterizzatore. Le ottimizzazioni dello shader potrebbero dare il via e apportare modifiche minuscole all'output. Anche se tecnicamente corretto, il risultato non deve necessariamente essere esattamente uguale al primo triangolo, e "i problemi" saranno alcuni pixel dal primo rimasto.

invariant assicura che venga adottato un approccio potenzialmente più lento. Io non sono un architetto di guida, bada bene, ma in generale questo potrebbe significare qualche reset di stato, pulizie o, a volte, stack/pop dello stack di stato. Solo così ti rimane lo stato computazionale "pulito", e finché il tuo hardware è a posto, il risultato dovrebbe essere esattamente lo stesso.