O'Reilly logo

Graphics Shaders, 2nd Edition by Steve Cunningham, Mike Bailey

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

157
Fragment Shaders and
Surface Appearance
8
Just as with vertex shaders, there are specic roles for fragment processing in
the xed-function graphics pipeline. Their task is to take state variables, plus
the values that are interpolated across a polygon, and produce a nal color for
each pixel. In the xed-function world there are few things to interpolate: posi-
tion, depth, color, and texture coordinates. The classical graphics literature
contains many more things that can be done with interpolations, however,
and the fragment shader in GLSL can do a great number of them. This chapter
describes the basics of fragment shaders, including some fun techniques you
can’t do with xed-function OpenGL graphics.
Once again, we consider the role of fragment processing in the graphics
pipeline, just as we did for the role of the vertex shader. The general place of
this functionality is shown in Figure 8.1, which recalls Figure 7.1. We see that
fragment processing takes the interpolated values within a graphics primitive
in screen space and produces pixels with color and depth to be incorporated
into the framebuer.
158
8. Fragment Shaders and Surface Appearance
Basic Function of a Fragment Shader
The basic function of a fragment shader is to take uniform variables and the
output from the rasterizer and compute the color of the pixel for each frag-
ment. Figure 8.2 illustrates this process, showing rst how the distinct verti-
ces of a primitive are processed by the rasterizer to form the set of fragments
that make up the primitive.
Of course, many other built-in properties of vertices besides color and
light intensity can be interpolated in fragment processing. The two most
important of these are texture coordinates and pixel depth. If you are using
texturing, as the texture coordinates are interpolated, you can use these coor-
dinates to sample a texture (or multiple textures) to help determine the colors
of each pixel. We will focus on textures and their contribution to fragment
processing in the chapter on texturing, and will keep our focus on other frag-
ment processing here.
Inputs to Fragment Shaders
There are many dierent kinds of inputs to a fragment shader from an appli-
cation, from the OpenGL system, or from a vertex shader. By now, these are
Figure 8.1. The place of the fragment shader in the pipeline.
159
Basic Function of a Fragment Shader
quite familiar, but we want to remind our-
selves of them in the fragment shader context.
Uniform Variables
Fragment shaders can use uniform variables
that are provided by the system or by the
application. Because uniform variables do
not change within a graphics primitive, they
will not change during the interpolations that
the rasterizer performs. However, they can
be used for any computations that might be
needed in fragment processing.
As a preview, there is a special kind of
uniform variable for textures that is avail-
able to both vertex and fragment shaders,
but which is particularly important for frag-
ment shaders: the uniform sampler variable.
The uniform sampler variables correspond to
textures, so with the 1D, 2D, and 3D textures,
we have sampler types
sampler1D, sampler2D,
and
sampler3D. Since GLSL also allows cube
mapping textures, we have the additional
sampler type
samplerCube. The particular
sampler type that you use must correspond to
the texture type that was dened in your application. The value associated with
a sampler variable is the texture image number associated with the texture it
represents, which is also set up in the texture denition functions in your appli-
cation. The
texture( ) function will be used with the texture unit and texture
coordinates to return the texture value at those coordinates, as in the line
vec4 textureValue = texture( TexUnit, coordinateVector );
We will see examples of this use in texture-based fragment shader code later
in this chapter.
Input and Output Variables
Perhaps the most important inputs to fragment shaders are the variables that
are passed to the fragment shader as
out variables by the pipeline stage that
occurs right before the rasterizer and fragment processor. This could be a
vertex, geometry, or tessellation shader. These variables are the data that are
interpolated across a graphics primitive in order to give the fragment shader
enough information to set the colors of each pixel.
Figure 8.2. The vertices of a graphics primitive
and the fragments that are processed to make up
the primitive being displayed.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required