- WebGL - Home
- WebGL - Introduction
- WebGL - Html5 Canvas Overview
- WebGL - Basics
- WebGL - Graphics Pipeline
- WebGL - Sample Application
- WebGL - Context
- WebGL - Geometry
- WebGL - Shaders
- Associating Attributes & Buffer Objects
- WebGL - Drawing a Model
- WebGL Examples
- WebGL - Drawing Points
- WebGL - Drawing a Triangle
- WebGL - Modes of Drawing
- WebGL - Drawing a Quad
- WebGL - Colors
- WebGL - Translation
- WebGL - Scaling
- WebGL - Rotation
- WebGL - Cube Rotation
- WebGL - Interactive Cube
- WebGL Useful Resources
- WebGL - Quick Guide
- WebGL - Useful Resources
- WebGL - Discussion
WebGL - Colors
In all our previous examples, we applied color to the object by assigning a desired color value to the gl_FragColor variable. In addition to that, we can define colors for each vertex − just like vertex coordinates and indices. This chapter takes an example to demonstrate how to apply colors to a quadrilateral using WebGL.
Applying Colors
To apply colors, you have to define the colors for each vertex using the RGB values, in JavaScript array. You can assign the same values to all the vertices to have a unique color to the object. After defining the colors, you have to create a color buffer and store these values in it, and associate it to the vertex shader attributes.
In the vertex shader, along with the coordinates attribute (that holds the position of the vertices), we define an attribute and a varying to handle colors.
The color attribute holds the color value per vertex, and varying is the variable that is passed as an input to the fragment shader. Therefore, we have to assign the color value to varying.
In the fragment shader, the varying that holds the color value is assigned to gl_FragColor, which holds the final color of the object.
Steps to Apply Colors
The following steps are required to create a WebGL application to draw a Quad and apply colors to it.
Step 1 − Prepare the Canvas and Get the WebGL Rendering Context
In this step, we obtain the WebGL Rendering context object using getContext().
Step 2 − Define the Geometry and Store it in the Buffer Objects
A square can be drawn using two triangles. Therefore, in this example, we provide the vertices for two triangles (with one common edge) and indices. Since we want to apply colors to it, a variable holding the color values is also defined and the color values for each (Red, Blue, Green, and Pink) are assigned to it.
var vertices = [ -0.5,0.5,0.0, -0.5,-0.5,0.0, 0.5,-0.5,0.0, 0.5,0.5,0.0 ]; var colors = [ 0,0,1, 1,0,0, 0,1,0, 1,0,1,]; indices = [3,2,1,3,1,0];
Step 3 − Create and Compile the Shader Programs
In this step, you need to write the vertex shader and fragment shader programs, compile them, and create a combined program by linking these two programs.
Vertex Shader − In the vertex shader of the program, we define vector attributes to store 3D coordinates (position), and the color of each vertex. A varing variable is declared to pass the color values from the vertex shader to the fragment shader. And finally, the value stored in the color attribute is assigned to varying.
var vertCode = 'attribute vec3 coordinates;'+
'attribute vec3 color;'+
'varying vec3 vColor;'+
'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'vColor = color;'+
'}';
Fragment Shader − In the fragment shader, we assign the varying to the gl_FragColor variable.
var fragCode = 'precision mediump float;'+
'varying vec3 vColor;'+
'void main(void) {'+
'gl_FragColor = vec4(vColor, 1.);'+
'}';
Step 4 − Associate the Shader Programs with the Buffer Objects
In this step, we associate the buffer objects and the shader program.
Step 5 − Drawing the Required Object
Since we are drawing two triangles that will form a quad, using indices, we will use the method drawElements(). To this method, we have to pass the number of indices. The value of indices.length indicates the number of indices.
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
Example Applying Color
The following program demonstrates how to draw a quad using WebGL application and apply colors to it.
<!doctype html>
<html>
<body>
<canvas width = "300" height = "300" id = "my_Canvas"></canvas>
<script>
/*============= Creating a canvas ==================*/
var canvas = document.getElementById('my_Canvas');
gl = canvas.getContext('experimental-webgl');
/*========== Defining and storing the geometry ==========*/
var vertices = [
-0.5,0.5,0.0,
-0.5,-0.5,0.0,
0.5,-0.5,0.0,
0.5,0.5,0.0
];
var colors = [0,0,1, 1,0,0, 0,1,0, 1,0,1,];
indices = [3,2,1,3,1,0];
// Create an empty buffer object and store vertex data
var vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
// Create an empty buffer object and store Index data
var Index_Buffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
// Create an empty buffer object and store color data
var color_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
/*======================= Shaders =======================*/
// vertex shader source code
var vertCode = 'attribute vec3 coordinates;'+
'attribute vec3 color;'+
'varying vec3 vColor;'+
'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'vColor = color;'+
'}';
// Create a vertex shader object
var vertShader = gl.createShader(gl.VERTEX_SHADER);
// Attach vertex shader source code
gl.shaderSource(vertShader, vertCode);
// Compile the vertex shader
gl.compileShader(vertShader);
// fragment shader source code
var fragCode = 'precision mediump float;'+
'varying vec3 vColor;'+
'void main(void) {'+
'gl_FragColor = vec4(vColor, 1.);'+
'}';
// Create fragment shader object
var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
// Attach fragment shader source code
gl.shaderSource(fragShader, fragCode);
// Compile the fragmentt shader
gl.compileShader(fragShader);
// Create a shader program object to
// store the combined shader program
var shaderProgram = gl.createProgram();
// Attach a vertex shader
gl.attachShader(shaderProgram, vertShader);
// Attach a fragment shader
gl.attachShader(shaderProgram, fragShader);
// Link both the programs
gl.linkProgram(shaderProgram);
// Use the combined shader program object
gl.useProgram(shaderProgram);
/* ======== Associating shaders to buffer objects =======*/
// Bind vertex buffer object
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
// Bind index buffer object
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);
// Get the attribute location
var coord = gl.getAttribLocation(shaderProgram, "coordinates");
// point an attribute to the currently bound VBO
gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
// Enable the attribute
gl.enableVertexAttribArray(coord);
// bind the color buffer
gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
// get the attribute location
var color = gl.getAttribLocation(shaderProgram, "color");
// point attribute to the volor buffer object
gl.vertexAttribPointer(color, 3, gl.FLOAT, false,0,0) ;
// enable the color attribute
gl.enableVertexAttribArray(color);
/*============Drawing the Quad====================*/
// Clear the canvas
gl.clearColor(0.5, 0.5, 0.5, 0.9);
// Enable the depth test
gl.enable(gl.DEPTH_TEST);
// Clear the color buffer bit
gl.clear(gl.COLOR_BUFFER_BIT);
// Set the view port
gl.viewport(0,0,canvas.width,canvas.height);
//Draw the triangle
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
</script>
</body>
</html>
If you run this example, it will produce the following output −