Fragment Shader/Defined Outputs: Difference between revisions
Jump to navigation
Jump to search
separate page for built-in outputs. |
Ianmackenzie (talk | contribs) Fix typo: gl_FragDepth.z -> gl_FragCoord.z |
||
(6 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
Fragment | {{pagelink|Fragment Shader}}s have the following built-in output variables. | ||
<source lang="glsl"> | <source lang="glsl"> | ||
Line 8: | Line 8: | ||
: This output is the fragment's depth. If the shader does not statically write this value, then it will take the value of {{code|gl_FragCoord.z}}. | : This output is the fragment's depth. If the shader does not statically write this value, then it will take the value of {{code|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 {{code|gl_FragDepth {{=}} ...}} expression ''anywhere'' in the shader, then it is statically written. | : 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 {{code|gl_FragDepth {{=}} ...}} expression ''anywhere'' in the shader, then it is statically written. | ||
{{warning|If the fragment shader statically writes to {{code|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.}} | |||
<span id="Conservative_Depth">{{require glsl|4.20|conservative_depth}} allows the user to specify that modifications to {{code|gl_FragDepth}} (relative to the {{code|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 Test]]s in certain situations. | |||
This is done by re-declaring {{code|gl_FragDepth}} with a special layout qualifier: | This is done by re-declaring {{code|gl_FragDepth}} with a special layout qualifier: | ||
Line 23: | Line 23: | ||
: The default. You may freely change the depth, but you lose the most potential performance. | : The default. You may freely change the depth, but you lose the most potential performance. | ||
; {{code|greater}} | ; {{code|greater}} | ||
: You will only make the depth ''larger'', compared to {{code| | : You will only make the depth ''larger'', compared to {{code|gl_FragCoord.z}}. | ||
; {{code|less}} | ; {{code|less}} | ||
: You will only make the depth ''smaller'', compared to {{code| | : You will only make the depth ''smaller'', compared to {{code|gl_FragCoord.z}}. | ||
; {{code|unchanged}} | ; {{code|unchanged}} | ||
: If you write to {{code|gl_FragDepth}}, you will write exactly {{code| | : If you write to {{code|gl_FragDepth}}, you will write exactly {{code|gl_FragCoord.z}}. | ||
Violating the {{param|condition}} yields undefined behavior. | Violating the {{param|condition}} yields undefined behavior. | ||
{{require glsl|4.00|sample_shading}} brings us: | |||
<source lang="glsl"> | <source lang="glsl"> | ||
Line 38: | Line 38: | ||
; {{code|gl_SampleMask}} | ; {{code|gl_SampleMask}} | ||
:This defines the sample mask for the fragment when performing [[Multisample|mutlisampled rendering]]. If a shader does not statically write to it, then it will be filled in by {{code|gl_SampleMaskIn}}. | :This defines the sample mask for the fragment when performing [[Multisample|mutlisampled rendering]]. If a shader does not statically write to it, then it will be filled in by {{code|gl_SampleMaskIn}}. The sample mask output here will be logically AND'd with the sample mask computed by the rasterizer. | ||
{{warning|Just as with {{code|gl_FragDepth}}, if a fragment shader writes to {{code|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 {{code|gl_SampleMaskIn}}.}} |
Latest revision as of 18:10, 28 July 2017
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.