A '''Fragment Shader''' is a user-supplied program that, when executed, will process a [[Fragment]] from the rasterization process into a set of colors and a single depth value.

A '''Fragment Shader''' is a user-supplied program that, when executed, will process a [[Fragment]] from the rasterization process into a set of colors and a single depth value.

−

== Overview ==

+

== Overview ==

The fragment shader is the OpenGL pipeline stage after a primitive is [[Rasterization|rasterized]]. For each sample of the pixels covered by a primitive, a "fragment" is generated. Each fragment has a [[Window Space]] position, a few other values, and it contains all of the interpolated per-vertex output values from the last [[Vertex Processing]] stage.

The fragment shader is the OpenGL pipeline stage after a primitive is [[Rasterization|rasterized]]. For each sample of the pixels covered by a primitive, a "fragment" is generated. Each fragment has a [[Window Space]] position, a few other values, and it contains all of the interpolated per-vertex output values from the last [[Vertex Processing]] stage.

Line 16:

Line 18:

Fragment shaders have a lot of input variables who's values are generated primarily by the rendering system.

Fragment shaders have a lot of input variables who's values are generated primarily by the rendering system.

Contents

Overview

The fragment shader is the OpenGL pipeline stage after a primitive is rasterized. For each sample of the pixels covered by a primitive, a "fragment" is generated. Each fragment has a Window Space position, a few other values, and it contains all of the interpolated per-vertex output values from the last Vertex Processing stage.

The output of a fragment shader is a depth value, a possible stencil value (unmodified by the fragment shader), and zero or more color values to be potentially written to the buffers in the current framebuffers.

Inputs

The inputs to the fragment shader are either generated by the system or passed from prior fixed-function operations and potentially interpolated across the surface of the primitive.

The user-defined outputs from the last Vertex Processing stage will be interpolated according to their assigned interpolation qualifiers. The fragment shader must define its user-defined inputs exactly as they were defined in the last Vertex Processing stage (with the exception of the centroid​ qualifier).

System inputs

Fragment shaders have a lot of input variables who's values are generated primarily by the rendering system.

invec4gl_FragCoord;inboolgl_FrontFacing;invec2gl_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)invec4gl_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​)invec4gl_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 {{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.

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​.

This is an integer identifier for the current sample that this fragment is rasterized for.

Warning: Any use of this variable at all will force this shader to be evaluated per-sample. Since much of the point of multisampling is to avoid that, you should use it only when you must.

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.

Warning: Any use of this variable at all will force this shader to be evaluated per-sample. Since much of the point of multisampling is to avoid that, you should use it only when you must.

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.

User overridden inputs

Some built-in inputs will take values specified by OpenGL, but these values can be overridden by user control.

infloatgl_ClipDistance[];inintgl_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 rendering command. However, if a Geometry Shader is active, then the 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.

Outputs

User-defined output values from the fragment are written to one or more color buffers in the current framebuffer.

There are some built-in output values with special meaning:

outfloatgl_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.

OpenGL 4.2/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>)outfloatgl_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_FragDepth.z​.

less​

You will only make the depth smaller, compared to gl_FragDepth.z​.

unchanged​

If you write to gl_FragDepth​, you will write exactly gl_FragDepth.z​.

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​.

Warning: Just as with gl_FragDepth​, if a fragment shader writes to it 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 is sized the same way as for gl_SampleMaskIn​.

Output buffers

The output from a fragment shader is a series of colors, which are directed into specific buffers based on the glDrawBuffers​ state. These are called "fragment colors". Much like vertex shader input assignment, there are three ways to do this. The methods for assigning these are listed in priority order, with the highest priority first. The higher priority methods take precedence over the later ones.

In-shader specification

The shader internally defines the fragment colors. This is done using the following layout​ syntax:

layout(location=3)outvec4diffuseColor;

This sets the diffuseColor​'s fragment color to 0.

Pre-link specification

Before linking a program that includes a fragment shader, the user may tell OpenGL to assign a particular output variable to a particular fragment color. This is done with the following function:

colorNumber​ is the fragment color to assign. name​ is the name of the fragment shader output to assign the given fragment color to.

Note that it is perfectly legal to assign names to fragment colors that are not mentioned in the fragment shader. The linking process will only use the names that are actually mentioned in the fragment shader. Because of that, it is also perfectly legal to assign multiple names to the same number; this is only an error if you attempt to link a program that uses both names.

Automatic assignment

If neither of the prior two methods assign an output to a fragment color, then the fragment color is automatically assigned by OpenGL when the program is linked. The fragment color assigned is completely arbitrary and may be different for different programs that are linked, even if they use the exact same fragment shader code.

Automatic assignment for fragment shader outputs makes even less sense than for vertex shader inputs. The color numbers (as explained below) refer to a draw buffer as defined by glDrawBuffers​. You are very likely to use the same Framebuffer Object for many different programs (while you will probably frequently change VAOs); changing glDrawBuffers​ state, and revalidating the FBO every time, is probably not a good idea.

Fragment shader output variables can be aggregated into arrays (though you are strongly advised to avoid this). Fragment colors for them are assigned consecutively, just as for vertex attributes, with the exception that double-precision outputs of dvec3​ or dvec4​ type take two fragment colors instead of one.

The limit on the number of fragment colors is defined by GL_MAX_DRAW_BUFFERS​, or GL_MAX_DUAL_SOURCE_DRAW_BUFFERS when using dual-source blending as below.

diffuseColor​ uses fragment color 0. The 0th index of the array passed to glDrawBuffers​ contains GL_COLOR_ATTACHMENT4. Therefore, the value written to diffuseColor​ will go to the buffer bound to the GL_COLOR_ATTACHMENT4 slot. Here's a table of the outputs and the associated buffers:

Output name

Color attachment

materialID

GL_COLOR_ATTACHMENT2

normal

GL_NONE

diffuseColor

GL_COLOR_ATTACHMENT4

position

GL_COLOR_ATTACHMENT0

specularColor

GL_NONE

normal​ is assigned GL_NONE (and therefore the written value is discard) because it attempts to access an index that was beyond the size of the array passed to glDrawBuffers​. All of those indices implicitly use GL_NONE. specularColor​ is assigned GL_NONE because that is what was given for the 2nd index (zero-based) of the array.

Dual-source blending

Dual-source blending is a technique whereby two (or theoretically more) output values can be used on the same buffer via blending. It is a way to get more values into the blend equation.

This is achieved by assigning another parameter to fragment output variables: an index. All outputs have an index in addition to a fragment color number. If any of the outputs is assigned a non-zero index, then the fragment shader uses dual-source blending.

When a fragment shader provides dual-source output, it reduces the number of buffers it can write to. The new maximum fragment color output is GL_MAX_DUAL_SOURCE_DRAW_BUFFERS, which is 1 on every piece of hardware that supports this feature. In short: if you want dual-source blending, you can only write to one buffer from the fragment shader.

The index of a fragment shader output can be assigned similarly to the fragment color. There is an in-shader specification:

Fragment shaders also have access to the discard​ command. When executed, this command causes the fragment's output values to be discarded in the same way that a fragment is discarded if the depth test failed. Thus, the fragment does not proceed on to the next pipeline stages.

Normally, early tests, performing the depth/etc test before the fragment shader, is a transparent optimization. However, with GL 4.2/ARB_shader_image_load_store, early depth tests can be forced for a fragment shader using this syntax:

layout(early_fragment_tests)in;

Warning: This does not mean that you can subvert the meaning of the depth test. You cannot, for example, perform the depth test with one value and then write a different value to the depth buffer than the one you tested. If you attempt to write to gl_FragDepth​ when you force early-fragment tests, then the value written will be ignored. The value written to the depth buffer will always be the value tested against the depth buffer.