Fragment Shader/Defined Outputs

From OpenGL Wiki
< Fragment Shader
Revision as of 18:10, 28 July 2017 by Ianmackenzie (talk | contribs) (Fix typo: gl_FragDepth.z -> gl_FragCoord.z)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Fragment Shaders have the following built-in output variables.

out float gl_FragDepth;
gl_FragDepth
This output is the fragment's depth. If the shader does not statically write this value, then it will take the value of gl_FragCoord.z.
To "statically write" to a variable means that you write to it anywhere in the program. Even if the writing code is technically unreachable for some reason, if there is a gl_FragDepth = ... expression anywhere in the shader, then it is statically written.
Warning: If the fragment shader statically writes to gl_FragDepth, then it is the responsibility of the shader to statically write to the value in all circumstances. No matter what branches may or may not be taken, the shader must ensure that the value is written. So, if you conditionally write to it in one place, you should at least make sure that there is a single non-conditional write sometime before that.

GLSL 4.20 or ARB_conservative_depth allows the user to specify that modifications to gl_FragDepth (relative to the gl_FragCoord.z value it would have otherwise had) will happen in certain ways. This allows the implementation the freedom to not turn off Early Depth Tests in certain situations.

This is done by re-declaring gl_FragDepth with a special layout qualifier:

layout (depth_<condition>) out float gl_FragDepth;

The condition​ can be one of the following:

any
The default. You may freely change the depth, but you lose the most potential performance.
greater
You will only make the depth larger, compared to gl_FragCoord.z.
less
You will only make the depth smaller, compared to gl_FragCoord.z.
unchanged
If you write to gl_FragDepth, you will write exactly gl_FragCoord.z.

Violating the condition​ yields undefined behavior.

GLSL 4.00 or ARB_sample_shading brings us:

out int gl_SampleMask[];
gl_SampleMask
This defines the sample mask for the fragment when performing mutlisampled rendering. If a shader does not statically write to it, then it will be filled in by gl_SampleMaskIn. The sample mask output here will be logically AND'd with the sample mask computed by the rasterizer.
Warning: Just as with gl_FragDepth, if a fragment shader writes to gl_SampleMask at all, it must make sure to write to the value for all execution paths. But it must also make sure to write to each element in the array. The array has the same size as gl_SampleMaskIn.