# How do I calculate NDC coordinates in a fragment shader?

I have some weird problem going on in my openGL shader.

First,, I pass the viewspace position from the vertex shader to the fragment shader like this:

vec4 view_pos = V * M * vec4(world_position.xyz, 1.0);


Then, in the fragment shader, I do this:

vec4 clip_pos = P * view_pos;
vec2 ndc_xy = clip_pos.xy / clip_pos.w
vec2 ndc_fragcoord = 2.0 * gl_FragCoord.xy / viewport_wh - 1.0


I would expect that ndc_xy is the same as ndc_fragcoord; however, when rendering them to textures, they are not nearly the same:

Can someone explain to me the differences? How can I get the same result in ndc_fragcoord by using view space position or vice versa?

This is important information for me for a later stage, when reconstructing the view space position from the depth. I have already been sitting on this the whole day, and am close to despair.

It looks like you are rendering point primitives. The vertex shader only operates on the center points of each primitive and the varying will hold the same value for all fragments on the primitive. That's why your first image looks the way it does.

I do not know of any way to get the NDC for point primitives other than calculating them from gl_FragCoords.

Not an open GL guy but it looks like its not getting interpolation over the vertex, I was just going to make a comment but to low on the points.

Not sure I know how to fix it in open GL but in dx I would make sure it gets passed from vertex shader to pixel shader with TEXCOORD[n] so it gets interpolation.

Again I just wanted to comment, sorry if I'm wrong.

• In GL, pretty much everything passed to the fragment shader gets interpolated, and we don't have semantics like TEXCOORD. Oct 27, 2016 at 18:16

move the projection multiplication in the vertex shader:

vec4 view_pos = P * V * M * vec4(world_position.xyz, 1.0);


vec4 clip_pos = view_pos;
vec2 ndc_xy = clip_pos.xy / clip_pos.w


It is better to stick with gl_FragCoord because you avoid the need to have a varying that you have to calculate.

gluProject does exactly what you want i.e. it maps a vertex from object space to the window space.

Lets take the formula for X from its spec:

winX = viewportLeft + ((viewportWidth * (ndc.x + 1)) / 2)

You've stopped just after calculating NDC coordinates, but this step is also needed to get the same result as gl_FragCoord.