2009-08-17 14 views
14

Ok, in meinem GLSL-Fragment-Shader möchte ich in der Lage sein, den Abstand des Fragments von einer bestimmten Linie im Raum zu berechnen.Wie man gl_FragCoord in glsl berechnet

Das Ergebnis davon ist, dass ich zum ersten Mal einen variierendes vec2 Satz in meinem Vertex-Shader zu verwenden ist versucht zu spiegeln, was in gl_FragCoord up endet:

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

Jetzt im Fragment-Shader erwarte ich:

gl_FragCoord.xy==fake_frag_coord 

Aber es tut es nicht. Welche Operation macht die Pipeline auf gl_Position, um es in gl_FragCoord zu verwandeln, die ich vernachlässige, auf fake_frag_coord zu machen?

Antwort

11

gl_FragCoord ist Bildschirmkoordinaten, so würden Sie Informationen über die Bildschirmgröße haben müssen und so, um es auf der Grundlage der Position zu erzeugen. Die fake_frag_coord, die Sie erzeugt haben, entspricht einem Punkt auf dem Bildschirm in normalisierten Gerätekoordinaten (-1 bis 1). Wenn Sie also die Bildschirmgröße in einer bestimmten Dimension um die Hälfte multiplizieren und dann diese Größe hinzufügen, erhalten Sie die tatsächlichen Bildschirmpixel.

+1

Ich war falsch über Sie falsch sein, aber recht gl_ModelViewProjectionMatrix * gl_Vertex mit potenziell Rechenfehler einzuführen. – karx11erx

+2

Nitpick: das gibt Ihnen tatsächlich Clip-Space-Koordinaten anstelle von normalisierten Gerätekoordinaten, da Sie nicht die perspektivische Teilung durchführen, die während des Rasterungsprozesses (zwischen dem Vertex-Shader und dem Fragment-Shader) stattfindet. http://www.glprogramming.com/red/chapter03.html#name1 – Pike65

+0

@ Pike65 Das ist nicht nur ein Nitpick, es sollte zu ganz anderen Werten für eine perspektivische Projektion führen. –

0

Das Problem, das Sie haben, ist, dass gl_ModelViewProjectionMatrix * gl_Vertex in einem Shader berechnet ist nicht immer das, was die feste Funktion Pipeline Erträge. Um identische Ergebnisse zu erhalten, führen Sie fake_frag_coord = ftransform() aus.

Edit:

Und es dann mit Ihrem Bildschirm Dimensionen skalieren.

+0

Ftransform erzeugt die Position, nicht die Fragcoord. Die Frage lautet nicht, wie man die Position bekommt. –

+0

Meine Antwort war nicht völlig falsch. Sie müssen fake_frag_coord mit Ihren Bildschirmdimensionen skalieren, aber abhängig davon, ob Sie fake_frag_coord = gl_ModelViewProjectionMatrix * gl_Vertex oder = ftransform() verwenden, können Sie unterschiedliche Ergebnisse erhalten. – karx11erx

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

fake_frag_coord=(gl_ModelViewMatrix * gl_Vertex).xy 
0

Ich wünschte, ich mehr rep hatte, so konnte ich kleinlich. Hier ist, was ich weiß. OpenGL führt Divide-By-W automatisch für Sie aus. Wenn also eine Position in einem Fragment-Shader ankommt, ist sie bereits in NDC-Koordinaten, und dann wird W 1.0 sein, die einzige Zeit, die Sie durch W dividieren müssen, ist if Sie möchten die gleiche Rechenoperation auf der CPU-Seite ausführen und die gleichen Ergebnisse erzielen ODER Wenn Sie aus irgendeinem Grund NDC-Koordinaten innerhalb Ihres Vertex-Shaders abrufen möchten.

+1

'gl_FragCoord' ist ** nicht ** in NDC. Es ist in Fensterkoordinaten. –