🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Is gl_FragDepth equal gl_FragCoord.z when msaa enable?

Started by
1 comment, last by MJP 3 years, 1 month ago

I know gl_FragDepth will take the value of gl_FragCoord.z from opengl wiki.

https://www.khronos.org/opengl/wiki/Fragment_Shader/Defined_Outputs

But I have a problem. If I enable MSAA and write gl_FragDepth = gl_FragCoord.z in fragment shader, the display will not work fine. You can see a black line on the white triangle.

If I don't write gl_FragDepth in fragment shader, it will work fine.

If I disalbe MSAA, it also work fine no matter if I write gl_FragDepth.

The correct display image is no black line:

The render scene is easy, I just draw 2 white triangles and they are intersected on an edge.

I add a simple light in vertex shader. The codes show as below:

const char *vertexShaderSource[] = {

"#version 120\n",

"varying vec4 lightColor;\n",

"void main()\n",

"{\n",

" vec3 n = normalize(gl_NormalMatrix * gl_Normal);\n",

" vec3 l = normalize(vec3(0.0, 1.0, 1.0));\n",

" float NdotL = clamp(dot(n, l), 0.001, 1.0);\n",

" lightColor = vec4(1.0)*(NdotL + 0.2);\n",

" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n",

"}\n"

};

const char *fragmentShaderSource[] = {

"#version 120\n",

"varying vec4 lightColor;\n",

"void main(void)\n",

"{\n",

" gl_FragColor = vec4(lightColor.rgb, 1.0);\n",

" gl_FragDepth = gl_FragCoord.z;\n"

"}\n"

};

Advertisement

Outputting depth from a pixel/fragment shader does not play nice with MSAA. The issue is that the hardware will only invoke the pixel/fragment shader once for each covered pixel, however with MSAA you normally have unique depth values for each subsample within a pixel. When you output depth from the shader you end up with one depth value written per fully-covered pixel, which is not what you want. You can avoid this by running the pixel shader at per-sample frequency (or at least you can do this in D3D, I'm honestly not sure how that works in OpenGL), but that mostly defeats the purpose of MSAA since it will be as expensive as supersampling.

This topic is closed to new replies.

Advertisement