15

Ok, in my GLSL fragment shader I want to be able to calculate the distance of the fragment from a particular line in space.

The result of this is that I am first trying to use a varying vec2 set in my vertex shader to mirror what ends up 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;

Now in the fragment shader I expect:

gl_FragCoord.xy==fake_frag_coord

But it does not. What operation does the pipeline do on gl_Position to turn it into gl_FragCoord that I am neglecting to do on fake_frag_coord?

Laurel
  • 5,965
  • 14
  • 31
  • 57
DaedalusFall
  • 8,335
  • 6
  • 30
  • 43

4 Answers4

11

gl_FragCoord is screen coordinates, so you'd need to have information about the screen size and such to produce it based on the Position. The fake_frag_coord you've produced will correspond to a point in the screen in normalized device coordinates I think (-1 to 1). So if you were to multiply by half the screen's size in a particular dimension, and then add that size, you'd get actual screen pixels.

Jay Kominek
  • 8,674
  • 1
  • 34
  • 51
  • 1
    I was wrong about you being wrong, but right about using gl_ModelViewProjectionMatrix * gl_Vertex potentially introducing compute errors. – Razzupaltuff Sep 08 '09 at 15:01
  • 2
    Nitpick: that will actually give you clip-space coordinates rather than normalised device coordinates, since you're not performing the perspective division which happens during the rasterisation process (between the vertex shader and fragment shader). http://www.glprogramming.com/red/chapter03.html#name1 – Pike65 Aug 19 '11 at 16:09
  • @Pike65 That's not just a nitpick, it should results in completely different values for a perspective projection. – Christian Rau Feb 09 '12 at 10:52
  • dose `gl_FragCoord.xy==gl_Position.xy/gl_Position.w` will do the perspective division? – toolchainX Mar 21 '13 at 10:46
0

The problem you have is that gl_ModelViewProjectionMatrix * gl_Vertex computed in a shader is not always what the fixed function pipeline yields. To get identical results, do fake_frag_coord = ftransform().

Edit:

And then scale it with your screen dimensions.

Razzupaltuff
  • 2,250
  • 2
  • 21
  • 37
  • ftransform produces the position, not the fragcoord. The question isn't asking how to get the position. – Jay Kominek Sep 08 '09 at 14:12
  • My answer wasn't completely wrong. You need to scale fake_frag_coord with your screen dimensions, but you may get different results depending on whether you use fake_frag_coord = gl_ModelViewProjectionMatrix * gl_Vertex or = ftransform(). – Razzupaltuff Sep 08 '09 at 15:00
0

I wish I had more rep so I could nitpick too. Here's what I know. OpenGL performs the Divide-By-W automatically for you, so by the time a position arrives in a fragment shader, it's already in NDC coordinates, and by then W will be 1.0, the only time you need to divide by W is if you want to do the same math on the CPU side, and get the same results, OR, if you for some odd reason, wanted to get NDC coordinates within your vertex shader.

Homer
  • 89
  • 2
-2
varying vec2 fake_frag_coord;
//in vertex shader:

fake_frag_coord=(gl_ModelViewMatrix * gl_Vertex).xy
stealthyninja
  • 10,343
  • 11
  • 51
  • 59