Fragment Shader/Defined Inputs: Difference between revisions
(Trying to fix broken layout on FS page.) |
(Attempting to fix highlighting errors.) |
||
(3 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{pagelink|Fragment Shader}}s have the following built-in input variables. | {{pagelink|Fragment Shader}}s have the following built-in input variables. | ||
< | <syntaxhighlight lang="glsl"> | ||
in vec4 gl_FragCoord; | in vec4 gl_FragCoord; | ||
in bool gl_FrontFacing; | in bool gl_FrontFacing; | ||
in vec2 gl_PointCoord; | in vec2 gl_PointCoord; | ||
</ | </syntaxhighlight> | ||
; {{code|gl_FragCoord}} | ; {{code|gl_FragCoord}} | ||
: The location of the fragment in window space. The X, Y and Z components are the window-space position of the fragment. The Z value will be written to the depth buffer if {{code|gl_FragDepth}} is not written to by this shader stage. The W component of {{code|gl_FragCoord}} is 1/W<sub>clip</sub>, where W<sub>clip</sub> is the interpolated W component of the clip-space vertex position output to {{code|gl_Position}} from the last [[Vertex Processing]] stage. | : The location of the fragment in window space. The X, Y and Z components are the window-space position of the fragment. The Z value will be written to the depth buffer if {{code|gl_FragDepth}} is not written to by this shader stage. The W component of {{code|gl_FragCoord}} is 1/W<sub>clip</sub>, where W<sub>clip</sub> is the interpolated W component of the clip-space vertex position output to {{code|gl_Position}} from the last [[Vertex Processing]] stage. | ||
: The space of {{code|gl_FragCoord}} can be modified by redeclaring {{code|gl_FragCoord}} with special input layout qualifiers: | : The space of {{code|gl_FragCoord}} can be modified by redeclaring {{code|gl_FragCoord}} with special input layout qualifiers: | ||
< | <syntaxhighlight lang="glsl"> | ||
layout(origin_upper_left) in vec4 gl_FragCoord; | layout(origin_upper_left) in vec4 gl_FragCoord; | ||
</ | </syntaxhighlight> | ||
: This means that the origin for {{code|gl_FragCoord}}'s window-space will be the upper-left of the screen, rather than the usual lower-left. | : This means that the origin for {{code|gl_FragCoord}}'s window-space will be the upper-left of the screen, rather than the usual lower-left. | ||
< | <syntaxhighlight lang="glsl"> | ||
layout(pixel_center_integer) in vec4 gl_FragCoord; | layout(pixel_center_integer) in vec4 gl_FragCoord; | ||
</ | </syntaxhighlight> | ||
: OpenGL window space is defined such that pixel centers are on half-integer boundaries. So the center of the lower-left pixel is (0.5, 0.5). Using {{code|pixel_center_integer}} adjust {{code|gl_FragCoord}} such that whole integer values represent pixel centers. | : OpenGL window space is defined such that pixel centers are on half-integer boundaries. So the center of the lower-left pixel is (0.5, 0.5). Using {{code|pixel_center_integer}} adjust {{code|gl_FragCoord}} such that whole integer values represent pixel centers. | ||
: Both of these exist to be compatible with D3D's window space. Unless you need your shaders to have this compatibility, you are advised not to use these features. | : Both of these exist to be compatible with D3D's window space. Unless you need your shaders to have this compatibility, you are advised not to use these features. | ||
; {{code|gl_FrontFacing}} | ; {{code|gl_FrontFacing}} | ||
: This is | : This is false if the fragment was generated by the [[Winding Order|back-face of the primitive]]; it is true in all other cases (including [[Primitive]]s that have no back face). | ||
; {{code|gl_PointCoord}} | ; {{code|gl_PointCoord}} | ||
: The location within a [[Primitive#Point Primitives|point primitive]] that defines the position of the fragment relative to the side of the point. Points are effectively rasterized as window-space squares of a certain pixel size. Since points are defined by a single vertex, the only way to tell where in that square a particular fragment is is with {{code|gl_PointCoord}}. | : The location within a [[Primitive#Point Primitives|point primitive]] that defines the position of the fragment relative to the side of the point. Points are effectively rasterized as window-space squares of a certain pixel size. Since points are defined by a single vertex, the only way to tell where in that square a particular fragment is is with {{code|gl_PointCoord}}. | ||
Line 27: | Line 27: | ||
OpenGL 4.0 and above define additional system-generated input values: | OpenGL 4.0 and above define additional system-generated input values: | ||
< | <syntaxhighlight lang="glsl"> | ||
in int gl_SampleID; | in int gl_SampleID; | ||
in vec2 gl_SamplePosition; | in vec2 gl_SamplePosition; | ||
in int gl_SampleMaskIn[]; | in int gl_SampleMaskIn[]; | ||
</ | </syntaxhighlight> | ||
; {{code|gl_SampleID}} | ; {{code|gl_SampleID}} | ||
Line 44: | Line 44: | ||
Some Fragment shader built-in inputs will take values specified by OpenGL, but these values can be overridden by user control. | Some Fragment shader built-in inputs will take values specified by OpenGL, but these values can be overridden by user control. | ||
< | <syntaxhighlight lang="glsl"> | ||
in float gl_ClipDistance[]; | in float gl_ClipDistance[]; | ||
in int gl_PrimitiveID; | in int gl_PrimitiveID; | ||
</ | </syntaxhighlight> | ||
; {{code|gl_ClipDistance}} | ; {{code|gl_ClipDistance}} | ||
: This array contains the interpolated clipping plane half-spaces, as output for vertices from the last [[Vertex Processing]] stage. | : This array contains the interpolated clipping plane half-spaces, as output for vertices from the last [[Vertex Processing]] stage. | ||
; {{code|gl_PrimitiveID}} | ; {{code|gl_PrimitiveID}} | ||
: This value is the index of the current primitive being rendered by this [[Vertex Rendering|drawing command]]. However, if a [[Geometry Shader]] is active, then the {{code|gl_PrimitiveID}} is what the GS provided as output. If the GS did not output a value, then the fragment shader gets an undefined value. | : This value is the index of the current primitive being rendered by this [[Vertex Rendering|drawing command]]. This includes any [[Tessellation]] applied to the mesh, so each individual primitive will have a unique index. | ||
: However, if a [[Geometry Shader]] is active, then the {{code|gl_PrimitiveID}} is exactly and only what the GS provided as output. Normally, {{code|gl_PrimitiveID}} is guaranteed to be unique, so if two FS invocations have the same primitive ID, they come from the same primitive. But if a GS is active and outputs non-unique values, then different fragment shader invocations for different primitives will get the same value. If the GS did not output a value for {{code|gl_PrimitiveID}}, then the fragment shader gets an undefined value. | |||
:: {{warning|The above discussion of {{code|gl_PrimitiveID}} is based on a particular reading of the OpenGL 4.6 specification. However, the specification itself is somewhat inconsistent with this view, suggesting that the primitive ID may only get incremented based on data fed to the system, not data generated by, for example, the tessellator. And the Vulkan specification seems to concur with this interpretation, and [https://forums.khronos.org/showthread.php/83726-gl_PrimitiveID-in-fragment-shader-with-tessellation-enabled at least one implementation is known to agree with that as well]. Until there is some [https://github.com/KhronosGroup/OpenGL-API/issues/47 clarification on the issue], you should consider the above to be questionable.}} | |||
GL 4.3 provides the following additional inputs: | GL 4.3 provides the following additional inputs: | ||
< | <syntaxhighlight lang="glsl"> | ||
in int gl_Layer; | in int gl_Layer; | ||
in int gl_ViewportIndex; | in int gl_ViewportIndex; | ||
</ | </syntaxhighlight> | ||
; {{code|gl_Layer}} | ; {{code|gl_Layer}} |
Latest revision as of 15:19, 23 September 2020
Fragment Shaders have the following built-in input variables.
in vec4 gl_FragCoord;
in bool gl_FrontFacing;
in vec2 gl_PointCoord;
- gl_FragCoord
- The location of the fragment in window space. The X, Y and Z components are the window-space position of the fragment. The Z value will be written to the depth buffer if gl_FragDepth is not written to by this shader stage. The W component of gl_FragCoord is 1/Wclip, where Wclip is the interpolated W component of the clip-space vertex position output to gl_Position from the last Vertex Processing stage.
- The space of gl_FragCoord can be modified by redeclaring gl_FragCoord with special input layout qualifiers:
layout(origin_upper_left) in vec4 gl_FragCoord;
- This means that the origin for gl_FragCoord's window-space will be the upper-left of the screen, rather than the usual lower-left.
layout(pixel_center_integer) in vec4 gl_FragCoord;
- OpenGL window space is defined such that pixel centers are on half-integer boundaries. So the center of the lower-left pixel is (0.5, 0.5). Using pixel_center_integer adjust gl_FragCoord such that whole integer values represent pixel centers.
- Both of these exist to be compatible with D3D's window space. Unless you need your shaders to have this compatibility, you are advised not to use these features.
- gl_FrontFacing
- This is false if the fragment was generated by the back-face of the primitive; it is true in all other cases (including Primitives that have no back face).
- gl_PointCoord
- The location within a point primitive that defines the position of the fragment relative to the side of the point. Points are effectively rasterized as window-space squares of a certain pixel size. Since points are defined by a single vertex, the only way to tell where in that square a particular fragment is is with gl_PointCoord.
- The values of gl_PointCoord's coordinates range from [0, 1]. OpenGL uses a upper-left origin for point-coordinates by default, so (0, 0) is the upper-left. However, the origin can be switched to a bottom-left origin by calling glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
OpenGL 4.0 and above define additional system-generated input values:
in int gl_SampleID;
in vec2 gl_SamplePosition;
in int gl_SampleMaskIn[];
- gl_SampleID
- This is an integer identifier for the current sample that this fragment is rasterized for.
- gl_SamplePosition
- This is the location of the current sample for the fragment within the pixel's area, with values on the range [0, 1]. The origin is the bottom-left of the pixel area.
- gl_SampleMaskIn
- When using multisampling, this variable contains a bitfield for the sample mask of the fragment being generated. The array is as long as needed to fill in the number of samples supported by the GL implementation.
Some Fragment shader built-in inputs will take values specified by OpenGL, but these values can be overridden by user control.
in float gl_ClipDistance[];
in int gl_PrimitiveID;
- gl_ClipDistance
- This array contains the interpolated clipping plane half-spaces, as output for vertices from the last Vertex Processing stage.
- gl_PrimitiveID
- This value is the index of the current primitive being rendered by this drawing command. This includes any Tessellation applied to the mesh, so each individual primitive will have a unique index.
- However, if a Geometry Shader is active, then the gl_PrimitiveID is exactly and only what the GS provided as output. Normally, gl_PrimitiveID is guaranteed to be unique, so if two FS invocations have the same primitive ID, they come from the same primitive. But if a GS is active and outputs non-unique values, then different fragment shader invocations for different primitives will get the same value. If the GS did not output a value for gl_PrimitiveID, then the fragment shader gets an undefined value.
Warning: The above discussion of gl_PrimitiveID is based on a particular reading of the OpenGL 4.6 specification. However, the specification itself is somewhat inconsistent with this view, suggesting that the primitive ID may only get incremented based on data fed to the system, not data generated by, for example, the tessellator. And the Vulkan specification seems to concur with this interpretation, and at least one implementation is known to agree with that as well. Until there is some clarification on the issue, you should consider the above to be questionable.
GL 4.3 provides the following additional inputs:
in int gl_Layer;
in int gl_ViewportIndex;
- gl_Layer
- This is either 0 or the layer number for this primitive output by the Geometry Shader.
- gl_ViewportIndex
- This is either 0 or the viewport index for this primitive output by the Geometry Shader.