5.8 - Example 4: Textures

This chapter has explained how shader programs, GPU object buffers, and JavaScript rendering code works together to create WebGL renderings. We have keep the shader programs very simple to help make the concepts understandable. However, we have barely scratched the surface on what is possible. The WebGL program below is presented to spark your interest in what is coming in future lessons. We won’t walk through the details of procedural texture mapping in this lesson, but please review the program code to get an idea of what a more complex shader program might do.

The example WebGL program below does the following:

A Texture Map Example

Show: Code   Canvas   Run Info
 
1
/**
2
 * simple_model4.js, By Wayne Brown, Fall 2017
3
 */
4
5
/**
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2015 C. Wayne Brown
9
 *
10
 * Permission is hereby granted, free of charge, to any person obtaining a copy
11
 * of this software and associated documentation files (the "Software"), to deal
12
 * in the Software without restriction, including without limitation the rights
13
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
 * copies of the Software, and to permit persons to whom the Software is
15
 * furnished to do so, subject to the following conditions:
16
 *
17
 * The above copyright notice and this permission notice shall be included in all
18
 * copies or substantial portions of the Software.
19
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
 * SOFTWARE.
27
 */
28
29
"use strict";
30
31
//-------------------------------------------------------------------------
32
/**
33
 * A triangle composed of 3 vertices.
34
 * @param vertices {Array} Three components, (x,y,z) location, RGBA color,
35
 *                         (s,t) texture coordinate.
36
 * @constructor
25
 
1
// Vertex Shader
2
// By: Dr. Wayne Brown, Spring 2016
3
4
precision mediump int;
5
precision mediump float;
6
7
uniform   mat4 u_Transform;
8
9
attribute vec3 a_Vertex;
10
attribute vec4 a_Color;
11
attribute vec2 a_Texture;
12
13
varying vec4 v_vertex_color;
14
varying vec2 v_texture;
15
16
void main() {
17
  // Transform the location of the vertex
18
  gl_Position = u_Transform * vec4(a_Vertex, 1.0);
19
20
  // Pass on the color and texture coordinates for this vertex to the fragment shader
21
  v_vertex_color = a_Color;
22
  v_texture = a_Texture;
23
}
24
25
34
 
1
// Fragment shader
2
// By: Dr. Wayne Brown, Spring 2016
3
4
precision mediump int;
5
precision mediump float;
6
7
varying vec4 v_vertex_color;
8
varying vec2 v_texture;
9
10
float grid_size = 0.2; // Percentage of whole
11
12
//-------------------------------------------------
13
// modify the color based on the texture coordinates
14
vec4 modify_color(vec2 tex_coords, vec4 color) {
15
  float s = tex_coords[0];
16
  float t = tex_coords[1];
17
  vec4 new_color;
18
19
  if ( mod((floor(s/grid_size) + floor(t/grid_size)),2.0) == 1.0) {
20
    // Use the normal face's color.
21
    new_color = color;
22
  } else {
23
    // Make the color darker
24
    new_color = vec4(vec3(color) * 0.8, 1.0);
25
  }
26
  return new_color;
27
}
28
29
//-------------------------------------------------
30
void main() {
31
  gl_FragColor = modify_color(v_texture, v_vertex_color);
32
}
33
34
../_static/05_simple_pyramid_texture/simple_pyramid_texture.html

A simple, 3D model where pixel colors are calculated using a procedural texture map.

Please use a browser that supports "canvas"
Animate
Draw the edges of the triangles using a gl.LINE_LOOP
Render the model as a "wireframe"
Render the global axes (x:red, y:green, z:blue)
Average time to render the model is 0.00000 milliseconds.
Open this webgl program in a new tab or window

Summary

To render a model, it requires a GPU shader program, one or more GPU object-buffers, and JavaScript rendering code. Let’s summarize the big picture behind rendering:

  • A vertex shader program retrieves vertex and other associated data from buffer objects. All buffer objects are 1-dimensional arrays of floats. The data in the buffer objects are organized by vertex. The vertex shader calculates the position a vertex in the scene and prepares any data needed by the fragment shader for calculating colors.
  • A fragment shader program receives data from the vertex shader for each vertex and then interpolates the values over the fragments of the primitive (either a point, line or triangle).
  • A pre-processing step must create appropriate GPU buffer objects and copy the model data into them.
  • Each time a model is rendered, a shader’s uniform variables must be assigned a value, a shader’s attribute variables must be linked to their appropriate buffer objects and a call to gl.drawArrays() executes the graphics pipeline.

Self-Assessments

Q-345: Code in the example fragment shader in the above WebGL program uses a floor function to to convert a floating point number to an integer, and a mod function to get the remainder after division by 2. What are the only possible values this expression can return?

mod((floor(s/grid_size) + floor(t/grid_size)),2.0)





Q-346: The SimpleModel4 function in the above WebGL program uses a array of arrays to define the data for each vertex like this:

vertices = [  [ [ 0.0, -0.25, -0.50], [1, 0, 0, 1], [2.0, 0.0] ],
              [ [ 0.0,  0.25,  0.00], [0, 1, 0, 1], [0.5, 1.0] ],
              [ [ 0.5, -0.25,  0.25], [0, 0, 1, 1], [1.0, 0.0] ],
              [ [-0.5, -0.25,  0.25], [1, 0, 1, 1], [0.0, 0.0] ]
           ];

Could you have defined the vertex data using a single array for each vertex like this:

vertices = [  [ 0.0, -0.25, -0.50,   1, 0, 0, 1,  2.0, 0.0 ],
              [ 0.0,  0.25,  0.00,   0, 1, 0, 1,  0.5, 1.0 ],
              [ 0.5, -0.25,  0.25,   0, 0, 1, 1,  1.0, 0.0 ],
              [ -0.5, -0.25,  0.25,  1, 0, 1, 1,  0.0, 0.0 ]
           ];





Next Section - 5.9 - Interleaved Buffers