Vertex Shader - WebGL Textures: Introduction to Mipmaps, Sub Images & Atlases (2015)

WebGL Textures: Introduction to Mipmaps, Sub Images & Atlases (2015)

Vertex Shader

The first book named WebGL Textures and Vertices: Beginner's Guide, describes the default vertex shader in detail. This book uses the same default vertex shader for each project. The following listing includes the entire vertex shader. Values from attribute a_position process one vertex at a time. Values from attribute a_tex_coord0 pass unmodified to the varying v_tex_coord0 within the vertex shader. The GPU interpolates values for the varying, then passes those values to the fragment shader. The varying v_tex_coord0 provides coordinates to sample from the currently active texture. The next few paragraphs demonstrate how to assign different sets of texels to the attribute a_tex_coord0, with the WebGL API method vertexAttribPointer().

attribute vec4 a_position;

attribute vec2 a_tex_coord0;

varying vec2 v_tex_coord0;"

uniform mat4 um4_matrix;

uniform mat4 um4_pmatrix;

void main(void) {

gl_Position = um4_pmatrix * um4_matrix * a_position;

v_tex_coord0 = a_tex_coord0;"

}

Listing 5: Vertex Shader

WebGL API vertexAttribPointer()

The WebGL API method vertexAttribPointer() tells the shader how to process data from a buffer. The book's examples each create an array of vertices and texels. The controller uploads the array's values to a buffer. MethodvertexAttribPointer() sets up a stream of information from the buffer to process through the vertex shader. Additionally vertexAttribPointer() tells the processor which shader attribute receives the stream of data.

Use method vertexAttribPointer() to describe exactly which set of values from the buffer, to process with a vertex shader's attribute. In this case use vertexAttribPointer() to change processing for the attribute named a_tex_coord0.

The parameters to vertexAttribPointer() in order represent:

1. Location: The location of an attribute within the vertex shader.

2. Size: The number of entries in the buffer, to assign to the attribute.

3. Type: The type of values to assign to the attribute.

4. Normalize: false if values are in normalized range {0.0 ... 1.0}.

5. Stride: Number of Bytes between attributes within the buffer.

6. Offset: Number of Bytes from the start of the buffer.

The location is a JavaScript variable which points to the vertex shader's attribute named a_tex_coord0. This project's GLEntity saves the location of a_tex_coord0 to the instance variable named aTexCoord. Pass aTexCoord as the first parameter to vertexAttribPointer().

The size always equals 2 for the book's texel processing attribute. We prepare two coordinates for each texel. One coordinate represents S. The other coordinate represents T. Therefore pass 2 as vertexAttribPointer()'s second parameter.

The type always equals FLOAT for the book's projects. Each entry in an array of vertices with texels, represents a floating point number.

The normalized parameter indicates whether or not values are within the range 0.0 to 1.0. If the values aren't in range, then tell the GPU to normalize them. The book's projects always prepares texels within range, therefore the normalized parameter should equal false. Values don't need normalization.

Changing Stride and Offset

Change the last two parameters representing stride and offset to process different texels. This example uses stride and offset to change texels which map the image on display. The texels map either the left side or the right side of the graphic, to the mesh. Calculate stride and offset based on the size and number of entries in the original array of vertices and texels.

First we need to know the size of each entry in the array. Calculate the size for both stride and offset in Bytes. All of the book's projects prepare an array of numbers. The controller uploads the array to the GPU as a vertex buffer object. Each entry in the buffer represents one floating point value. One floating point type requires 4 Bytes of memory. The size of one entry in the buffer equals 4. Therefore each entry in the original array uses 4 Bytes of memory.

First Set of Texels

Stride represents the distance between attributes in the array, in Bytes. The listing titled Switch Images: Vertex and Texel Array, shows a JavaScript array which begins with three coordinates representing the X, Y, and Z values of one vertex. After the vertex, two coordinates represent one texel's S and T values. Each texel is separated by 3 vertex coordinates, plus 2 texel coordinates.

3 + 2 = 5.

Each coordinate requires 4 Bytes.

4 * 5 = 20

From the start of the first texel to the start of the second texel equals 20 Bytes. The first four texels in the array are interleaved. The stride between each interleaved texel equals 20. The fifth parameter to vertexAttribPointer()equals 20.

Offset represents the distance from the start of the buffer, to the start of a set of attributes. We want to find the offset for the first texel. The array begins with three coordinates representing one vertex. The vertex offset equals 0, because the array begins with vertices. However the first texel coordinate begins after the first vertex. One vertex equals 3 coordinates with one X coordinate. one Y coordinate and one Z coordinate. Each coordinate requires 4Bytes.

3 * 4 = 12

The first texel coordinate begins at offset 12. The sixth parameter to vertexAttribPointer() equals 12.

The following listing from method changeImage() assigns the first set of texels to the vertex shader's attribute location aTexCoord. The stride parameter equals 20 and the offset parameter equals 12.

gl.vertexAttribPointer

(

aTexCoord,

2,

gl.FLOAT,

false,

20,

12

);

Listing 6: Switch Images: vertexAttribPointer() First Texel Set

Second Set of Texels

Stride represents the distance between attributes in the array. The second set of texels in the listing titled Switch Images: Vertex and Texel Array, includes only texels. No other entries separate one texel from the next. Therefore the stride equals 0. The fifth parameter to vertexAttribPointer() equals 0.

We want to calculate the offset from the start of the buffer, to the start of the second set of texels. The first set of interleaved vertices and texels contain four vertices plus four texels. Each vertex uses three buffer entries including one entry for the X coordinate, one entry for the Y coordinate, and one entry for the Z coordinate. Each texel uses two buffer entries including one entry for the S coordinate and one entry for the T coordinate.

From the start of the buffer to the second set of texels, we have 4 vertices times 3 coordinates per vertex. We also have 4 texels times 2 coordinates per vertex. The buffer has 20 entries before the second set of texels.

4 * 3 + 4 * 2 = 20

Each entry uses 4 Bytes of memory. 80 Bytes exist between the start of the buffer and the second set of texels.

20 * 4 = 80

The second texel coordinate begins at offset 80. The sixth parameter to vertexAttribPointer() equals 80.

The following listing from method changeImage() assigns the second set of texels to the vertex shader's attribute location aTexCoord. The stride parameter equals 0 and the offset parameter equals 80.

gl.vertexAttribPointer

(

aTexCoord,

2,

gl.FLOAT,

false,

0,

80

);

Listing 7: Switch Images: vertexAttribPointer() Second Texel Set

The following chart includes cells for each entry in the array used to switch images on a mesh. The values assigned to WebGL method vertexAttribPointer() for stride and offset, display with dark backgrounds. The first set of texels use stride = 20 and offset = 12. The second set of texels use stride = 0 and offset = 80. The chart demonstrates calculating and incrementing offsets. The next project Texture Atlas: Animation, animates with an array offsets. We calculate the offsets in advance.

Vertex Texel Table 01

Diagram 2: Switch Images: Vertex Texel Table

Summary Texture Atlas: Switch Images

The first texture atlas project demonstrated how to switch images dynamically. The Texture Atlas: Switch Images project alternately displays sides of a graphic, on a square mesh. The mesh first displays the triangle. When the user taps the Change Image button, the sphere displays on the square mesh. Tap the Change Image button to switch back and forth between images mapped to the square mesh.

We demonstrated how to switch images with a texture atlas. The Texture Atlas: Switch Images project explained how to calculate offset and stride parameters for the WebGL method vertexAttribPointer(). Once you understand how to calculate offset and stride, it's relatively easy to adjust texels or animate with texels. See the entire JavaScript file for the Texture Atlas: Switch Images project.