• No results found

Fragment Shaders

In document glspec31.20090324.pdf (Page 174-179)

3.9

Fragment Shaders

The sequence of operations that are applied to fragments that result from rasterizing a point, line segment, or polygon are described using afragment shader.

A fragment shader is an array of strings containing source code for the opera- tions that are meant to occur on each fragment that results from rasterization. The language used for fragment shaders is described in the OpenGL Shading Language Specification.

Fragment shaders are created as described in section 2.11.1using a type pa- rameter ofFRAGMENT SHADER. They are attached to and used in program objects as described in section2.11.2.

When the program object currently in use includes a fragment shader, its frag- ment shader is consideredactive, and is used to process fragments. If the program object has no fragment shader, or no program object is currently in use, the results of fragment shader execution are undefined.

3.9.1 Shader Variables

Fragment shaders can access uniforms belonging to the current shader object. The amount of storage available for fragment shader uniform variables in the default uniform block is specified by the value of the implementation-dependent constant

MAX FRAGMENT UNIFORM COMPONENTS. The total amount of combined storage available for fragment shader uniform variables in all uniform blocks (includ- ing the default uniform block) is specified by the value of the implementation- dependent constant MAX COMBINED FRAGMENT UNIFORM COMPONENTS. These values represent the numbers of individual floating-point, integer, or boolean val- ues that can be held in uniform variable storage for a fragment shader. A uniform matrix will consume no more than4×min(r, c)such values, wherer andcare the number of rows and columns in the matrix. A link error will be generated if an attempt is made to utilize more than the space available for fragment shader uniform variables.

Fragment shaders can read varying variables that correspond to the attributes of the fragments produced by rasterization. The OpenGL Shading Language Spec- ification defines a set of built-in varying variables that can be be accessed by a fragment shader. These built-in varying variables include data associated with a fragment such as the fragment’s position.

Additionally, when a vertex shader is active, it may define one or morevarying

variables (see section2.11.6 and the OpenGL Shading Language Specification). These values are, if not flat shaded, interpolated across the primitive being ren- dered. The results of these interpolations are available when varying variables of

3.9. FRAGMENT SHADERS 162

Texture Base Texture source color Internal Format Cs As

RED (Rt,0,0) 1

RG (Rt, Gt,0) 1

RGB (Rt, Gt, Bt) 1

RGBA (Rt, Gt, Bt) At

Table 3.20: Correspondence of filtered texture components to texture source com- ponents.

the same name are defined in the fragment shader.

A fragment shader can also write to varying out variables. Values written to these variables are used in the subsequent per-fragment operations. Varying out variables can be used to write floating-point, integer or unsigned integer values des- tined for buffers attached to a framebuffer object, or destined for color buffers at- tached to the default framebuffer. TheShader Outputssubsection of section3.9.2 describes how to direct these values to buffers.

3.9.2 Shader Execution

The executable version of the fragment shader is used to process incoming frag- ment values that are the result of rasterization.

Texture Access

TheShader Only Texturingsubsection of section2.11.7describes texture lookup functionality accessible to a vertex shader. The texel fetch and texture size query functionality described there also applies to fragment shaders.

When a texture lookup is performed in a fragment shader, the GL computes the filtered texture valueτ in the manner described in sections3.8.8and3.8.9, and converts it to a texture source colorCsaccording to table3.20. The GL returns a

four-component vector(Rs, Gs, Bs, As)to the fragment shader. For the purposes

of level-of-detail calculations, the derivatives dudx, dudy, dvdx, dvdy, dwdx and dwdy may be approximated by a differencing algorithm as detailed in section 8.8 of the OpenGL Shading Language specification.

Texture lookups involving textures with depth component data can either return the depth data directly or return the results of a comparison with theDrefvalue (see

section3.8.14) used to perform the lookup. The comparison operation is requested in the shader by using any of the shadow sampler types (sampler1DShadow,

3.9. FRAGMENT SHADERS 163

sampler2DShadow, or sampler2DRectShadow), and in the texture using the

TEXTURE COMPARE MODEparameter. These requests must be consistent; the re- sults of a texture lookup are undefined if:

• The sampler used in a texture lookup function is not one of the shadow sampler types, the texture object’s internal format isDEPTH COMPONENTor

DEPTH STENCIL, and theTEXTURE COMPARE MODEis notNONE.

• The sampler used in a texture lookup function is one of the shadow sam- pler types, the texture object’s internal format is DEPTH COMPONENT or

DEPTH STENCIL, and theTEXTURE COMPARE MODEisNONE.

• The sampler used in a texture lookup function is one of the shadow sampler types, and the texture object’s internal format is notDEPTH COMPONENTor

DEPTH STENCIL.

The stencil index texture internal component is ignored if the base internal format isDEPTH STENCIL.

If a fragment shader uses a sampler whose associated texture object is not com- plete, as defined in section3.8.11, the texture image unit will return(R, G, B, A)

=(0,0,0,1).

The number of separate texture units that can be accessed from within a fragment shader during the rendering of a single primitive is specified by the implementation-dependent constantMAX TEXTURE IMAGE UNITS.

Shader Inputs

The OpenGL Shading Language specification describes the values that are avail- able as inputs to the fragment shader.

The built-in variable gl FragCoord holds the window coordinates x, y, z, and w1 for the fragment. The z component ofgl FragCoord undergoes an im- plied conversion to floating-point. This conversion must leave the values 0 and 1 invariant. Note that thisz component already has a polygon offset added in, if enabled (see section3.6.4). The w1 value is computed from thewccoordinate (see

section2.12).

The built-in variablegl FrontFacingis set toTRUEif the fragment is gen- erated from a front-facing primitive, andFALSEotherwise. For fragments gener- ated from triangle primitives (including ones resulting from primitives rendered as points or lines), the determination is made by examining the sign of the area computed by equation3.8of section3.6.1(including the possible reversal of this sign controlled byFrontFace). If the sign is positive, fragments generated by the

3.9. FRAGMENT SHADERS 164

primitive are front-facing; otherwise, they are back-facing. All other fragments are considered front-facing.

The built-in variablegl PrimitiveIDis filled with the number of primitives processed by the rasterizer since the last drawing command was called. The first primitive generated by a drawing command is numbered zero, and the primitive ID counter is incremented after every individual point, line, or polygon primitive is processed. For polygons drawn in point or line mode, the primitive ID counter is incremented only once, even though multiple points or lines may be drawn.

Restarting a primitive using the primitive restart index (see section2.8) has no effect on the primitive ID counter.

gl PrimitiveID is only defined under the same

conditions thatgl VertexID is defined, as described under “Shader Inputs” in section2.11.7.

Shader Outputs

The OpenGL Shading Language specification describes the values that may be output by a fragment shader. These outputs are split into two categories, user-defined varying out variables and the built-in variables gl FragColor,

gl FragData[n], and gl FragDepth. If fragment color clamping is enabled and the color buffer has an unsigned normalized fixed-point, signed normalized fixed-point, or floating-point format, the final fragment color, fragment data, or varying out variable values written by a fragment shader are clamped to the range

[0,1]. Only user-defined varying out variables declared as a floating-point type are clamped and may be converted. If fragment color clamping is disabled, or the color buffer has an integer format, the final fragment color, fragment data, or varying out variable values are not modified. For fixed-point depth buffers, the final fragment depth written by a fragment shader is first clamped to[0,1]and then converted to fixed-point as if it were a windowzvalue (see section2.12.1). For floating-point depth buffers, conversion is not performed but clamping is. Note that the depth range computation is not applied here, only the conversion to fixed-point.

Color values written by a fragment shader may be floating-point, signed inte- ger, or unsigned integer. If the color buffer has an signed or unsigned normalized fixed-point format, color values are assumed to be floating-point and are converted to fixed-point as described in equations2.6or2.4, respectively; otherwise no type conversion is applied. If the values written by the fragment shader do not match the format(s) of the corresponding color buffer(s), the result is undefined.

Writing to gl FragColor specifies the fragment color (color number zero) that will be used by subsequent stages of the pipeline. Writing to

3.9. FRAGMENT SHADERS 165

or color components, associated with a fragment that are not written by the frag- ment shader are undefined. A fragment shader may not statically assign values to more than one ofgl FragColor,gl FragData, and any user-defined varying out variable. In this case, a compile or link error will result. A shader statically assigns a value to a variable if, after pre-processing, it contains a statement that would write to the variable, whether or not run-time flow of control will cause that statement to be executed.

Writing to gl FragDepth specifies the depth value for the fragment being processed. If the active fragment shader does not statically assign a value to

gl FragDepth, then the depth value generated during rasterization is used by sub- sequent stages of the pipeline. Otherwise, the value assigned togl FragDepthis used, and is undefined for any fragments where statements assigning a value to

gl FragDepthare not executed. Thus, if a shader statically assigns a value to

gl FragDepth, then it is responsible for always writing it.

The binding of a user-defined varying out variable to a fragment color number can be specified explicitly. The command

void BindFragDataLocation(uintprogram, uintcolorNumber, const char*name);

specifies that the varying out variablenameinprogramshould be bound to frag- ment color colorNumber when the program is next linked. If name was bound previously, its assigned binding is replaced with colorNumber. name must be a null-terminated string. The error INVALID VALUE is generated if colorNum- beris equal or greater thanMAX DRAW BUFFERS.BindFragDataLocationhas no effect until the program is linked. In particular, it doesn’t modify the bindings of varying out variables in a program that has already been linked. The error

INVALID OPERATIONis generated ifnamestarts with the reservedgl prefix. When a program is linked, any varying out variables without a binding spec- ified through BindFragDataLocation will automatically be bound to fragment colors by the GL. Such bindings can be queried using the command GetFrag- DataLocation. LinkProgramwill fail if the number of active outputs is greater than the value ofMAX DRAW BUFFERS. LinkProgramwill also fail if more than one varying out variable is bound to the same number. This type of aliasing is not allowed.

BindFragDataLocationmay be issued before any shader objects are attached to a program object. Hence it is allowed to bind any name (except a name starting withgl) to a color number, including a name that is never used as a varying out variable in any fragment shader object. Assigned bindings for variables that do not exist are ignored.

In document glspec31.20090324.pdf (Page 174-179)