2009-08-17 15 views
14

Ok, nel mio shader di frammento GLSL voglio essere in grado di calcolare la distanza del frammento da una particolare linea nello spazio.Come calcolare gl_FragCoord in glsl

Il risultato di questo è che sto prima cercando di utilizzare un set vec2 variabile nel mio vertex shader di rispecchiare ciò che finisce in gl_FragCoord:

varying vec2 fake_frag_coord; 
//in vertex shader: 
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
fake_frag_coord=(gl_ModelViewProjectionMatrix * gl_Vertex).xy; 

Ora nello shader frammento mi aspetto:

gl_FragCoord.xy==fake_frag_coord 

Ma non è così. Che operazione fa la pipeline su gl_Position per trasformarla in gl_FragCoord che sto trascurando di fare su fake_frag_coord?

risposta

11

gl_FragCoord è le coordinate dello schermo, quindi è necessario disporre di informazioni sulle dimensioni dello schermo e tali da produrlo in base alla posizione. Il fake_frag_coord che hai prodotto corrisponderà a un punto dello schermo in coordinate normalizzate del dispositivo, credo (da -1 a 1). Quindi, se dovessi moltiplicare della metà le dimensioni dello schermo in una particolare dimensione e quindi aggiungere quella dimensione, otterresti i pixel dello schermo effettivi.

+1

Mi sbagliavo sul fatto che tu stia sbagliando, ma riguardo all'utilizzo di gl_ModelViewProjectionMatrix * gl_Vertex potrebbe potenzialmente introdurre errori di calcolo. – karx11erx

+2

Nitpick: questo in realtà fornirà le coordinate dello spazio delle clip piuttosto che le coordinate normalizzate del dispositivo, poiché non si esegue la divisione prospettica che avviene durante il processo di rasterizzazione (tra vertex shader e framment shader). http://www.glprogramming.com/red/chapter03.html#name1 – Pike65

+0

@ Pike65 Questo non è solo un nitpick, dovrebbe comportare valori completamente diversi per una proiezione prospettica. –

0

Il problema è che gl_ModelViewProjectionMatrix * gl_Vertex calcolato in uno shader non è sempre ciò che produce la funzione fissa. Per ottenere risultati identici, fai fake_frag_coord = ftransform().

Edit:

E poi scalare con i tuoi dimensioni dello schermo.

+0

ftransform produce la posizione, non il fragcoord. La domanda non è chiedere come ottenere la posizione. –

+0

La mia risposta non era completamente sbagliata. Devi ridimensionare fake_frag_coord con le dimensioni dello schermo, ma potresti ottenere risultati diversi a seconda che tu utilizzi fake_frag_coord = gl_ModelViewProjectionMatrix * gl_Vertex o = ftransform(). – karx11erx

-2
varying vec2 fake_frag_coord; 
//in vertex shader: 

fake_frag_coord=(gl_ModelViewMatrix * gl_Vertex).xy 
0

Vorrei avere più rappresentanti in modo che potessi fare il pelo nell'uovo. Ecco quello che so. OpenGL esegue automaticamente Divide-By-W per te, quindi quando una posizione arriva in un framment shader, è già in coordinate NDC, e allora W sarà 1.0, l'unica volta che devi dividere per W è se vuoi fare la stessa matematica dal lato CPU, e ottenere gli stessi risultati, OPPURE, se per qualche strana ragione, volevi ottenere le coordinate NDC all'interno del vertex shader.

+1

'gl_FragCoord' è ** non ** in NDC. È nelle coordinate della finestra. –