The Fragment Shader - WebGL Textures & Vertices: Beginner's Guide (2015)

WebGL Textures & Vertices: Beginner's Guide (2015)

The Fragment Shader

This section covers the default fragment shader line by line. The file GLControl.js defines a default vertex and default fragment shader. If a Web page includes a shader, then the controller uses the shader. Otherwise the controller uses shaders defined in GLControl.js. The book's examples all use the default shaders.

Fragment Shader Introduction

The default fragment shader samples a texture. The fragment shader retrieves color from a texture at a specific location. The built in variable gl_FragColor receives the color. gl_FragColor describes the output color for the particular fragment. The fragment displays on the rendering surface. The Web page's canvas element serves as a rendering surface for the book's examples. gl_FragColor of type vec4, represents red, green, blue, and alpha channels for one color.

The fragment shader section presents a few new concepts for readers unfamiliar with shaders. However later sections in the book, tie the information together. The section titled Prepare Textures begins the discussion. Subsections explain how to upload a texture to the GPU, then assign the texture to a sampler2D.

The following listing includes the entire fragment shader. We added line numbers to identify each line for discussion.

1. precision mediump float;

2. uniform sampler2D u_sampler0;

3. varying vec2 v_tex_coord0;

4. void main(void) {

5. gl_FragColor = texture2D(u_sampler0, v_tex_coord0);

6. }

Listing 43: Fragment Shader with Line Numbers

Line 1 precision mediump float declares precision for all floating point variables in the shader. Precision determines the number of digits, defined by bits, available to describe the value of the number. Precision qualifiers includehighp, mediump, and lowp. When applied to floating point types, highp requires 32 bits, mediump requires 16 bits, and lowp requires 8 bits. Not all hardware supports highp, and lowp may produce artifacts. In other words texels might map incorrectly, resulting in misaligned textures. Therefore the shader applies mediump.

Floating point numbers within matrices and vectors use float precision settings. Therefore the precision setting precision mediump float;, applies to line 3 varying vec2 v_tex_coord0;.

Line 2 uniform sampler2D u_sampler0; declares a uniform of type sampler2D named u_sampler0. A sampler2D accesses a texture. The texture represents a set of pixel color values. The shader retrieves pixel colors from the sampler2Dwith texel coordinates.

Line 3 varying vec2 v_tex_coord0;. Hopefully line 3 looks familiar. The vertex shader declares the same varying, type, and name.

A varying in the vertex shader provides output. A varying in the fragment shader provides input. The varying v_tex_coord0 maintains interpolated texels. The texels we previously assigned to a Float32Array follow a process with five steps. First prepare the texels with a JavaScript array. Second upload the texels to a GPU buffer. Third output the texels through a vertex shader varying. Fourth the GPU pipeline interpolates the texels. Last the fragment shader receives the modified varying texels.

Line 4 void main(void) { represents the entry point for the fragment shader. In other words, the function named main() executes when the fragment shader runs.

Line 5 gl_FragColor = texture2D(u_sampler0, v_tex_coord0); The entire body of the main() function executes with this one line.

The OpenGL ES Shader Language implements the function texture2D(sampler2D,vec2). Function texture2D(sampler2D,vec2) returns a color from a texture bound to the sampler2D parameter. The color comes from the location indicated by the S and T coordinates within the vec2 parameter. gl_FragColor receives one color value.

The book's examples bind either a lighthouse image, Butterfly Fish image, or procedural texture to the actual parameter, u_sampler0. The book's examples generate an array with texel data which passes through the actual parameter, v_tex_coord0.

The following graphic illustrates texture2D(sampler2D,vec2) taking a sample from the lighthouse texture, then returning a color to gl_FragColor. The sampler2D parameter references a texture representing a lighthouse. The vec2parameter has S and T texel coordinates. Finally gl_FragColor contains the color from the texture at the S and T texel coordinates.

texture2D Diagram

Diagram 12: WebGL API texture2D(sampler2D, vec2)

Line 6 } The closing curly brace ends the function main(), which terminates one run of the fragment shader.

Fragment Shader Summary

The fragment shader used with the book's examples, takes a sample from one texture. The fragment shader retrieves the color from a texture at specified texels. The built in variable gl_FragColor receives the output color as red, green, blue, and alpha channels. gl_FragColor describes the output color for the particular pixel fragment, to display on the rendering surface.

The fragment shader section presents a few new concepts for readers unfamiliar with shaders. However later sections in the book, tie the information together. The section titled Prepare Textures begins the discussion. Subsections explain how to upload a texture to the GPU, then assign the texture to a sampler2D.