9
votes

I have the following shaders

VertexShader

#version 330
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec4 inColour;
layout (location = 2) in vec2 inTex;
layout (location = 3) in vec3 inNorm;
uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
out vec4 ShadowCoord;
void main()
{
  gl_Position = projectionMatrix * transformationMatrix * vec4(inPosition, 1.0);
  ShadowCoord = gl_Position;
}

FragmentShader

#version 330
in vec4 ShadowCoord;
out vec4 FragColor;
uniform sampler2D heightmapTexture;
void main()
{
  FragColor =  vec4(vec3(clamp(ShadowCoord.x/500,0.0,1.0),clamp(gl_FragCoord.y/500,0.0,1.0),0.0),1.0);
}

What I would expect this to do is to draw the scene, with green in the top left, yellow in the top right, red in the bottom right and black in the bottom left. Indeed this is what happens when I replace ShadowCoord.x with gl_FragCoord.x in my fragment shader. Why then, do I only get a vertical gradient of green? Evidently something screwy is happening to my ShadowCoord. Anyone know what it is?

1
"Anyone know what it is?" No. Because the contents of ShadowCoord depend entirely on the contents of two matrices that we have no idea what they are. We don't even know if you're using a perspective or orthographic project. - Nicol Bolas
Ok, but the point is that if I replace ShadowCoord with gl_FragCoord in the frag shader then it works. Is gl_FragCoord not derived from gl_Position? If so why does ShadowCoord not undergo the same interpolation? <EDIT> FYI, its a perspective projection of a camera transformation. - rspencer

1 Answers

15
votes

Yes, gl_FragCoord is "derived from gl_Position". That does not mean that it is equal to it.

gl_Position is the clip-space position of a particular vertex. gl_FragCoord.xyz contains the window-space position of the fragment. These are not the same spaces. To get from one to the other, the graphics hardware performs a number of transformations.

Transformations that do not happen to other values. That's why the fragment shader doesn't call it gl_Position; because it's not that value anymore. It's a new value computed from the original based on various state (the viewport & depth range) that the user has set.

User-defined vertex parameters are interpolated as they are. Nothing "screwy" is happening with your user-defined interpolated parameter. The system is doing exactly what it should: interpolating the value you passed across the triangle's surface.