5.7 - Example 3: One Color per Vertex

This example will help you understand varying variables in shader programs, which allow the color of the pixels across a triangle’s face to “vary”. This allows all kinds of special effects, such as gradient colors and lighting effects. To demonstrate how varying variables work, we can keep the previous shader programs and just change our data. We will assign a different color to each vertex of a triangle.

The Model

In the WebGL program below, a Triangle3 object will contain 3 vertices, but each vertex is defined by a (x,y,z) location and a RGBA color.

Lines Description
60-64 The vertices are defined by two separate arrays, a (x,y,z) location and a RGBA color.
38 A Triangle3 object now stores 3 vertices, but each vertex definition contains both a location and a color.
Show: Code   Canvas   Run Info
 
1
/**
2
 * simple_model3.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
 * A simple triangle composed of 3 vertices.
33
 * @param vertices {Array} An array of 2 arrays - first (x,y,z) location, then RGBA color.
34
 * @constructor
35
  */
36
window.Triangle3 = function (vertices) {
37
  let self = this;
../_static/05_color_per_vertex/simple_pyramid3.html

Render the model with a different color assigned to each vertex.

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

The Shader Programs

Our shader programs remain unchanged from the previous example, but they are displayed below so that we can discuss them again.

Show: Code   Canvas   Run Info
19
 
1
// Vertex Shader
2
precision mediump int;
3
precision mediump float;
4
5
uniform mat4 u_Transform;
6
7
attribute vec3 a_Vertex;
8
attribute vec4 a_Color;
9
10
varying vec4 v_Color;
11
12
void main() {
13
  // Transform the location of the vertex
14
  gl_Position = u_Transform * vec4(a_Vertex, 1.0);
15
16
  // Set the color of the vertex from the attribute VOB
17
  v_Color = a_Color;
18
}
19
11
 
1
// Fragment shader program
2
precision mediump int;
3
precision mediump float;
4
5
varying vec4 v_Color;
6
7
void main() {
8
  gl_FragColor = v_Color;
9
}
10
11
../_static/05_color_per_vertex/simple_pyramid3.html

Render the model with a different color assigned to each vertex.

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

The previous explanations of vertex shaders said that a vertex shader’s job was to position a vertex and set the gl_Position output variable for that vertex. This is true, but it is only half the story. A vertex shader also prepares and passes data about the vertex to the fragment shader. Remember, a fragment is a collection of data related to an individual pixel. Well, any varying variable declared in a vertex shader will be passed to the fragment shader for that individual vertex. If we declared and calculated six varying variables in a vertex shader, all six values will be passed on to the fragment shader. Varying variables can be thought of as parameters to the fragment shader for that individual vertex.

Why are they call them varying variables? It is because they automatically change their value as they are applied to individual pixels on a triangle’s face (or along a line segment). Technically the values are linearly interpolated. The term interpolated means that given a starting and ending value, the values in-between are gradually changed to morph from the starting value into the ending value. For example, starting with 10 and ending in 22, with 3 intermediate values, a linear interpolation would produce the sequence [10, 13, 16, 19, 22]. The term linearly interpolated means that the difference between any two sequential values is the same.

The linear interpolation of varying variables happens automatically. You have no control over the interpolation and you can’t stop the interpolation. If you have a value that you want to remain constant over all the pixels in a triangle’s face, you must still declare it as a varying variable, but you can set the starting and ending values to be the same and the interpolation will calculate a value that doesn’t change. For example, interpolating from 10 to 10 will calculate 10 for every value in-between.

The Buffer Object(s)

In the WebGL program below each vertex has a distinct color. Therefore the data in the buffer object that contains the vertex colors must be created differently, as compared to the previous lesson. Study the code in the model_to_gpu.js file below, especially lines 80-109.

Show: Code   Canvas   Run Info
116
 
1
/**
2
 * model_to_gpu.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
 * Given a model description, create the buffer objects needed to render
33
 * the model. This is very closely tied to the shader implementations.
34
 * @param gl {WebGLRenderingContext} WebGL context
35
 * @param model {SimpleModel} The model data.
36
 * @param out {ConsoleMessages} Can display messages to the web page.
37
 * @constructor
../_static/05_color_per_vertex/simple_pyramid3.html

Render the model with a different color assigned to each vertex.

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

Access to Shader Variables

The shader program did not change, so there are no changes to the code that gets the shader variable locations.

Linking a Buffer Object to an Attribute Variable

Linking to the buffer objects remained unchanged.

Rendering

The rendering of the model remained unchanged. The rendering function in the example below is in lines 71-128.

Show: Code   Canvas   Run Info
146
 
1
/**
2
 * simple_model_render3.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
 * Given a model description, create the buffer objects needed to render
33
 * the model. This is very closely tied to the shader implementations.
34
 * @param gl {WebGLRenderingContext} WebGL context
35
 * @param uniform_program {object} The shader program the will render the same
36
 *                               color for each vertex.
37
 * @param color_program {object} The shader program the will render a different
../_static/05_color_per_vertex/simple_pyramid3.html

Render the model with a different color assigned to each vertex.

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

The colors of fragments that compose a point, line or triangle are assigned colors using interpolated values. The values calculated at the vertices are the starting and ending values used for the interpolation.

Self-Assessments

Q-112: A varying variable in a shader program is … (Select all that apply.)





Q-113: Which of the following are valid linear interpolations between 10 and 20? (Select all that apply.)





Next Section - 5.8 - Example 4: Textures