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

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

Shader Details

Each WebGL application requires one vertex shader and one fragment shader. The book's default vertex shader processes each attribute from a buffer, one at a time. Each execution of the vertex shader prepares one vertex and one texel attribute, for output. The OpenGL ES pipeline interpolates vertex shader output before passing information on to the fragment shader. Interpolation involves preparing fragment shader inputs based on vertex shader outputs. The fragment shader may run more often than the vertex shader. Modified values may arrive in stages to the fragment shader.

The vertex shader processes first. Data from the vertex shader processes through the pipeline before passing to the fragment shader. The fragment shader displays color to the rendering surface. This book's rendering surface is an HTML5 canvas element.

We previously demonstrated how to declare vertices and texels with a JavaScript array. The section titled Prepare Buffers explains how to upload the array to the GPU, for shader access. This section explains how shaders use the vertex and texel data.

The shader language is based on the C programming language syntax. However shaders include some unique features designed specifically for high speed graphics.

Shader Storage Qualifiers

Storage qualifiers modify the use of a variable. WebGL storage qualifiers include const, attribute, uniform, and varying. The book's shaders use attribute, uniform, and varying qualifiers. This section discusses the qualifiers used within the book's shaders.

Shader Uniforms

Shaders only read values from uniforms. Both the vertex and fragment shader access uniform values. Assign values to uniforms with JavaScript between drawing operations. The developer can't modify a uniform, until WebGL methods drawElements() or drawArrays() finish execution. WebGL methods drawElements() and drawArrays() render to the drawing surface. This book calls drawElements() to render to the canvas.

For example upload rotation matrix values to a uniform, then call the WebGL API method drawElements(). The next few sections explain how the book's vertex shader moves or rotates every vertex by a uniform matrix.

Shader Varyings

Varyings allow the vertex shader to pass information to the fragment shader. Varyings represent output from the vertex shader and input to the fragment shader. The vertex shader may modify a varying. The fragment shader can only read a varying. The pipeline interpolates values for a varying before sending the varying to the fragment shader. Modified values for a varying may arrive in stages to the fragment shader.

The book's fragment and vertex shaders declare a varying of type vec2 with the name v_tex_coord0. The varying processes texels uploaded from a JavaScript array.

Shader Attributes

Attributes are accessed only within the vertex shader. Attributes represent a subset of data from a buffer, for each execution of the vertex shader. For each drawing operation, the vertex shader runs repeatedly, until every element of data passes through attributes according to specified settings. The developer designates exactly which elements from a buffer must pass through an attribute, for one full drawing operation.

WebGL API method calls upload buffers from JavaScript arrays, for use with attributes. The method vertexAttribPointer() describes the layout and limits of data for individual attributes. Method vertexAttribPointer() instructs the shader how to process a stream of data, which originates from a JavaScript array. The section titled Prepare Buffers explains how to upload JavaScript arrays to WebGL buffers. The section titled WebGL API vertexAttribPointer() demonstrates how to prepare shader attributes, to process buffer data. This section focuses on shader code.

Shader Variable Types

The book's shaders use types vec2, vec4, mat4, and sampler2D. The next few sections discuss each type.

Shader Type vec2

vec2 indicates a vector with 2 floating point numbers. Vectors contain sets of floating point numbers. The number of values in a vector are specified as vec<n> where n represents a number between 2 and 4. The book uses vec2 to process texels.

Developers may access entries in a vector with swizzles. Swizzles include {x,y,z,w}, {r,g,b,a}, or {s,t,r,q} components. For example access the s component of a vec2 named a_tex_coord0 with a_tex_coord0.s.

Shader Type vec4

A vec4 indicates a vector with 4 floating point numbers. The book's vertex shader uses a vec4 to process vertices. The first, second, and third entries in the vec4 process the X, Y, and Z values uploaded from one of the book's arrays. The fourth entry in the vec4 receives the default value 1.0.

Shader Type mat4

A mat4 represents a 4 x 4 matrix. Visualize matrices as tables with rows and columns. A 4 x 4 matrix contains four rows and four columns, with a total of 16 entries. Matrices are useful for transforming vertices. In other words use matrices to move, rotate, or scale a mesh, one vertex at a time. See the section titled 4 x 4 Matrices for more details.

Shader Type sampler2D

A sampler2D points to a texture stored within the GPU. The texture represents pixel colors. Visualize a sampler2D as an image formed from a set of pixels. The sampler2D provides a texture surface for the shader to sample, at specified texture coordinates. The book's fragment shader retrieves colors from the texture based on texels.