Discuss WebGL ”; Previous Next WebGL (Web Graphics Library) is the new standard for 3D graphics on the Web, designed for rendering 2D graphics and interactive 3D graphics. This tutorial starts with a basic introduction to WebGL, OpenGL, and the Canvas element of HTML-5, followed by a sample application. This tutorial contains dedicated chapters for all the steps required to write a basic WebGL application. It also contains chapters that explain how to use WebGL for affine transformations such as translation, rotation, and scaling. Print Page Previous Next Advertisements ”;
Category: webgl
WebGL – Modes of Drawing
WebGL – Modes of Drawing ”; Previous Next In the previous chapter (Chapter 12), we discussed how to draw a triangle using WebGL. In addition to triangles, WebGL supports various other drawing modes. This chapter explains the drawing modes supported by WebGL. The mode Parameter Let’s take a look at the syntax of the methods − drawElements() and draw Arrays(). void drawElements(enum mode, long count, enum type, long offset); void drawArrays(enum mode, int first, long count); If you clearly observe, both the methods accept a parameter mode. Using this parameter, the programmers can select the drawing mode in WebGL. The drawing modes provided by WebGL are listed in the following table. Sr.No. Mode & Description 1 gl.POINTS To draw a series of points. 2 gl.LINES To draw a series of unconnected line segments (individual lines). 3 gl.LINE_STRIP To draw a series of connected line segments. 4 gl.LINE_LOOP To draw a series of connected line segments. It also joins the first and last vertices to form a loop. 5 gl.TRIANGLES To draw a series of separate triangles. 6 gl.TRIANGLE_STRIP To draw a series of connected triangles in strip fashion. 7 gl.TRIANGLE_FAN To draw a series of connected triangles sharing the first vertex in a fan-like fashion. Example – Draw Three Parallel Lines The following example shows how to draw three parallel lines using gl.LINES. Live Demo <!doctype html> <html> <body> <canvas width = “300” height = “300” id = “my_Canvas”></canvas> <script> /*======= Creating a canvas =========*/ var canvas = document.getElementById(”my_Canvas”); var gl = canvas.getContext(”experimental-webgl”); /*======= Defining and storing the geometry ======*/ var vertices = [ -0.7,-0.1,0, -0.3,0.6,0, -0.3,-0.3,0, 0.2,0.6,0, 0.3,-0.3,0, 0.7,0.6,0 ] // Create an empty buffer object var vertex_buffer = gl.createBuffer(); // Bind appropriate array buffer to it gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); // Pass the vertex data to the buffer gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); // Unbind the buffer gl.bindBuffer(gl.ARRAY_BUFFER, null); /*=================== Shaders ====================*/ // Vertex shader source code var vertCode = ”attribute vec3 coordinates;” + ”void main(void) {” + ” gl_Position = vec4(coordinates, 1.0);” + ”}”; // 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 = ”void main(void) {” + ”gl_FragColor = vec4(0.0, 0.0, 0.0, 0.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); // 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); /*============ Drawing the triangle =============*/ // 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 and depth buffer gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Set the view port gl.viewport(0,0,canvas.width,canvas.height); // Draw the triangle gl.drawArrays(gl.LINES, 0, 6); // POINTS, LINE_STRIP, LINE_LOOP, LINES, // TRIANGLE_STRIP,TRIANGLE_FAN, TRIANGLES </script> </body> </html> If you run this example, it will produce the following output − Drawing Modes In the above program, if you replace the mode of drawArrays() with one of the following drawing modes, it will produce different outputs each time. Drawing Modes Outputs LINE_STRIP LINE_LOOP TRIANGLE_STRIP TRIANGLE_FAN TRIANGLES Print Page Previous Next Advertisements ”;
WebGL – Colors
WebGL – Colors ”; Previous Next 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. Live Demo <!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 −
WebGL – Drawing a Quad
WebGL – Drawing a Quad ”; Previous Next In the previous chapter, we discussed the different drawing modes provided by WebGL. We can also use indices to draw primitives using one of these modes. To draw models in WebGL, we have to choose one of these primitives and draw the required mesh (i.e., a model formed using one or more primitives). In this chapter, we will take an example to demonstrate how to draw a quadrilateral using WebGL. Steps to Draw a Quadrilateral The following steps are required to create a WebGL application to draw a quadrilateral. 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. In this example, we provide the vertices for two triangles (with one common edge) and indices. 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 ]; 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 the vector attribute to store 3D coordinates and assign it to gl_position. var vertCode = ”attribute vec3 coordinates;” + ”void main(void) {” + ” gl_Position = vec4(coordinates, 1.0);” + ”}”; Fragment Shader − In the fragment shader, we simply assign the fragment color to the gl_FragColor variable. var fragCode = ”void main(void) {” +” gl_FragColor = vec4(0.5, 0.3, 0.0, 7.5);” +”}”; Step 4 − Associate the Shader Programs to Buffer Objects In this step, we associate the buffer objects with the shader program. Step 5 − Drawing the Required Object Since we are drawing two triangles to 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 gives the number of indices. gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0); Example – Draw a Quadrilateral The following program shows how to create a WebGL application to draw a quadrilateral. Live Demo <!doctype html> <html> <body> <canvas width = “570” height = “570” 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 ]; indices = [3,2,1,3,1,0]; // Create an empty buffer object to store vertex buffer var vertex_buffer = gl.createBuffer(); // Bind appropriate array buffer to it gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); // Pass the vertex data to the buffer gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); // Unbind the buffer gl.bindBuffer(gl.ARRAY_BUFFER, null); // Create an empty buffer object to store Index buffer var Index_Buffer = gl.createBuffer(); // Bind appropriate array buffer to it gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer); // Pass the vertex data to the buffer gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); // Unbind the buffer gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); /*====================== Shaders =======================*/ // Vertex shader source code var vertCode = ”attribute vec3 coordinates;” + ”void main(void) {” + ” gl_Position = vec4(coordinates, 1.0);” + ”}”; // 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 = ”void main(void) {” + ” gl_FragColor = vec4(0.0, 0.0, 0.0, 0.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); /*============= 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 − Print Page Previous Next Advertisements ”;
WebGL – Html5 Canvas Overview ”; Previous Next To create graphical applications on the web, HTML-5 provides a rich set of features such as 2D Canvas, WebGL, SVG, 3D CSS transforms, and SMIL. To write WebGL applications, we use the existing canvas element of HTML-5. This chapter provides an overview of the HTML-5 2D canvas element. HTML5 Canvas HTML-5 <canvas> provides an easy and powerful option to draw graphics using JavaScript. It can be used to draw graphs, make photo compositions, or do simple (and not so simple) animations. Here is a simple <canvas> element having only two specific attributes width and height plus all the core HTML-5 attributes like id, name, and class. Syntax The syntax of HTML canvas tag is given below. You have to mention the name of the canvas inside double quotations (“ ”). <canvas id = “mycanvas” width = “100” height = “100”></canvas> Canvas Attributes The canvas tag has three attributes namely, id, width, and height. Id − Id represents the identifier of the canvas element in the Document Object Model (DOM). Width − Width represents the width of the canvas. Height − Height represents the height of the canvas. These attributes determine the size of the canvas. If a programmer is not specifying them under the canvas tag, then browsers such as Firefox, Chrome, and Web Kit, by default, provide a canvas element of size 300 × 150. Example – Create a Canvas The following code shows how to create a canvas. We have used CSS to give a colored border to the canvas. Live Demo <html> <head> <style> #mycanvas{border:1px solid red;} </style> </head> <body> <canvas id = “mycanvas” width = “100” height = “100”></canvas> </body> </html> On executing, the above code will produce the following output − The Rendering Context The <canvas> is initially blank. To display something on the canvas element, we have to use a scripting language. This scripting language should access the rendering context and draw on it. The canvas element has a DOM method called getContext(), which is used to obtain the rendering context and its drawing functions. This method takes one parameter, the type of context 2d. The following code is to be written to get the required context. You can write this script inside the body tag as shown below. Live Demo <!DOCTYPE HTML> <html> <body> <canvas id = “mycanvas” width = “600” height = “200”></canvas> <script> var canvas = document.getElementById(”mycanvas”); var context = canvas.getContext(”2d”); context.font = ”20pt Calibri”; context.fillStyle = ”green”; context.fillText(”Welcome to Tutorialspoint”, 70, 70); </script> </body> </html> On executing, the above code will produce the following output − For more example on HTML-5 2D Canvas, check out the following link HTML-5 Canvas. WebGL Context HTML5 Canvas is also used to write WebGL applications. To create a WebGL rendering context on the canvas element, you should pass the string experimental-webgl, instead of 2d to the canvas.getContext() method. Some browsers support only ”webgl”. Live Demo <!DOCTYPE html> <html> <canvas id = ”my_canvas”></canvas> <script> var canvas = document.getElementById(”my_canvas”); var gl = canvas.getContext(”experimental-webgl”); gl.clearColor(0.9,0.9,0.8,1); gl.clear(gl.COLOR_BUFFER_BIT); </script> </html> On executing, the above code will produce the following output − Print Page Previous Next Advertisements ”;
WebGL – Drawing a Model
WebGL – Drawing a Model ”; Previous Next After associating the buffers with the shaders, the final step is to draw the required primitives. WebGL provides two methods namely, drawArrays() and drawElements() to draw models. drawArrays() drawArrays() is the method which is used to draw models using vertices. Here is its syntax − void drawArrays(enum mode, int first, long count) This method takes the following three parameters − mode − In WebGL, models are drawn using primitive types. Using mode, programmers have to choose one of the primitive types provided by WebGL. The possible values for this option are − gl.POINTS, gl.LINE_STRIP, gl.LINE_LOOP, gl.LINES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, and gl.TRIANGLES. first − This option specifies the starting element in the enabled arrays. It cannot be a negative value. count − This option specifies the number of elements to be rendered. If you draw a model using drawArrays() method, then WebGL, while rendering the shapes, creates the geometry in the order in which the vertex coordinates are defined. Example If you want to draw a single triangle using drawArray() method, then you have to pass three vertices and call the drawArrays() method, as shown below. var vertices = [-0.5,-0.5, -0.25,0.5, 0.0,-0.5,]; gl.drawArrays(gl.TRIANGLES, 0, 3); It will produce a triangle as shown below. Suppose you want to draw contiguous triangles, then you have to pass the next three vertices in order in the vertex buffer and mention the number of elements to be rendered as 6. var vertices = [-0.5,-0.5, -0.25,0.5, 0.0,-0.5, 0.0,-0.5, 0.25,0.5, 0.5,-0.5,]; gl.drawArrays(gl.TRIANGLES, 0, 6); It will produce a contiguous triangle as shown below. drawElements() drawElements() is the method that is used to draw models using vertices and indices. Its syntax is as follows − void drawElements(enum mode, long count, enum type, long offset) This method takes the following four parameters − mode − WebGL models are drawn using primitive types. Using mode, programmers have to choose one of the primitive types provided by WebGL. The list of possible values for this option are − gl.POINTS, gl.LINE_STRIP, gl.LINE_LOOP, gl.LINES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN, and gl.TRIANGLES. count − This option specifies the number of elements to be rendered. type − This option specifies the data type of the indices which must be UNSIGNED_BYTE or UNSIGNED_SHORT. offset − This option specifies the starting point for rendering. It is usually the first element (0). If you draw a model using drawElements() method, then index buffer object should also be created along with the vertex buffer object. If you use this method, the vertex data will be processed once and used as many times as mentioned in the indices. Example If you want to draw a single triangle using indices, you need to pass the indices along with vertices and call the drawElements() method as shown below. var vertices = [ -0.5,-0.5,0.0, -0.25,0.5,0.0, 0.0,-0.5,0.0 ]; var indices = [0,1,2]; gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0); It will produce the following output − If you want to draw contagious triangles using drawElements() method, simply add the other vertices and mention the indices for the remaining vertices. var vertices = [ -0.5,-0.5,0.0, -0.25,0.5,0.0, 0.0,-0.5,0.0, 0.25,0.5,0.0, 0.5,-0.5,0.0 ]; var indices = [0,1,2,2,3,4]; gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0); It will produce the following output − Required Operations Before drawing a primitive, you need to perform a few operations, which are explained below. Clear the Canvas First of all, you should clear the canvas, using clearColor() method. You can pass the RGBA values of a desired color as parameter to this method. Then WebGL clears the canvas and fills it with the specified color. Therefore, you can use this method for setting the background color. Take a look at the following example. Here we are passing the RGBA value of gray color. gl.clearColor(0.5, 0.5, .5, 1); Enable Depth Test Enable the depth test using the enable() method, as shown below. gl.enable(gl.DEPTH_TEST); Clear the Color Buffer Bit Clear the color as well as the depth buffer by using the clear() method, as shown below. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); Set the View Port The view port represents a rectangular viewable area that contains the rendering results of the drawing buffer. You can set the dimensions of the view port using viewport() method. In the following code, the view port dimensions are set to the canvas dimensions. gl.viewport(0,0,canvas.width,canvas.height); Print Page Previous Next Advertisements ”;
WebGL – Cube Rotation
WebGL – Cube Rotation ”; Previous Next In this chapter, we will take an example to demonstrate how to draw a rotating 3D cube using WebGL. Example – Draw a Rotating 3D Cube The following program shows how to draw a rotating 3D cube − Live Demo <!doctype html> <html> <body> <canvas width = “570” height = “570” 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 = [ -1,-1,-1, 1,-1,-1, 1, 1,-1, -1, 1,-1, -1,-1, 1, 1,-1, 1, 1, 1, 1, -1, 1, 1, -1,-1,-1, -1, 1,-1, -1, 1, 1, -1,-1, 1, 1,-1,-1, 1, 1,-1, 1, 1, 1, 1,-1, 1, -1,-1,-1, -1,-1, 1, 1,-1, 1, 1,-1,-1, -1, 1,-1, -1, 1, 1, 1, 1, 1, 1, 1,-1, ]; var colors = [ 5,3,7, 5,3,7, 5,3,7, 5,3,7, 1,1,3, 1,1,3, 1,1,3, 1,1,3, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0 ]; var indices = [ 0,1,2, 0,2,3, 4,5,6, 4,6,7, 8,9,10, 8,10,11, 12,13,14, 12,14,15, 16,17,18, 16,18,19, 20,21,22, 20,22,23 ]; // Create and store data into vertex buffer var vertex_buffer = gl.createBuffer (); gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); // Create and store data into color buffer var color_buffer = gl.createBuffer (); gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW); // Create and store data into index buffer 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); /*=================== Shaders =========================*/ var vertCode = ”attribute vec3 position;”+ ”uniform mat4 Pmatrix;”+ ”uniform mat4 Vmatrix;”+ ”uniform mat4 Mmatrix;”+ ”attribute vec3 color;”+//the color of the point ”varying vec3 vColor;”+ ”void main(void) { ”+//pre-built function ”gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(position, 1.);”+ ”vColor = color;”+ ”}”; var fragCode = ”precision mediump float;”+ ”varying vec3 vColor;”+ ”void main(void) {”+ ”gl_FragColor = vec4(vColor, 1.);”+ ”}”; var vertShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertShader, vertCode); gl.compileShader(vertShader); var fragShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragShader, fragCode); gl.compileShader(fragShader); var shaderProgram = gl.createProgram(); gl.attachShader(shaderProgram, vertShader); gl.attachShader(shaderProgram, fragShader); gl.linkProgram(shaderProgram); /* ====== Associating attributes to vertex shader =====*/ var Pmatrix = gl.getUniformLocation(shaderProgram, “Pmatrix”); var Vmatrix = gl.getUniformLocation(shaderProgram, “Vmatrix”); var Mmatrix = gl.getUniformLocation(shaderProgram, “Mmatrix”); gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer); var position = gl.getAttribLocation(shaderProgram, “position”); gl.vertexAttribPointer(position, 3, gl.FLOAT, false,0,0) ; // Position gl.enableVertexAttribArray(position); gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer); var color = gl.getAttribLocation(shaderProgram, “color”); gl.vertexAttribPointer(color, 3, gl.FLOAT, false,0,0) ; // Color gl.enableVertexAttribArray(color); gl.useProgram(shaderProgram); /*==================== MATRIX =====================*/ function get_projection(angle, a, zMin, zMax) { var ang = Math.tan((angle*.5)*Math.PI/180);//angle*.5 return [ 0.5/ang, 0 , 0, 0, 0, 0.5*a/ang, 0, 0, 0, 0, -(zMax+zMin)/(zMax-zMin), -1, 0, 0, (-2*zMax*zMin)/(zMax-zMin), 0 ]; } var proj_matrix = get_projection(40, canvas.width/canvas.height, 1, 100); var mov_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; var view_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]; // translating z view_matrix[14] = view_matrix[14]-6;//zoom /*==================== Rotation ====================*/ function rotateZ(m, angle) { var c = Math.cos(angle); var s = Math.sin(angle); var mv0 = m[0], mv4 = m[4], mv8 = m[8]; m[0] = c*m[0]-s*m[1]; m[4] = c*m[4]-s*m[5]; m[8] = c*m[8]-s*m[9]; m[1]=c*m[1]+s*mv0; m[5]=c*m[5]+s*mv4; m[9]=c*m[9]+s*mv8; } function rotateX(m, angle) { var c = Math.cos(angle); var s = Math.sin(angle); var mv1 = m[1], mv5 = m[5], mv9 = m[9]; m[1] = m[1]*c-m[2]*s; m[5] = m[5]*c-m[6]*s; m[9] = m[9]*c-m[10]*s; m[2] = m[2]*c+mv1*s; m[6] = m[6]*c+mv5*s; m[10] = m[10]*c+mv9*s; } function rotateY(m, angle) { var c = Math.cos(angle); var s = Math.sin(angle); var mv0 = m[0], mv4 = m[4], mv8 = m[8]; m[0] = c*m[0]+s*m[2]; m[4] = c*m[4]+s*m[6]; m[8] = c*m[8]+s*m[10]; m[2] = c*m[2]-s*mv0; m[6] = c*m[6]-s*mv4; m[10] = c*m[10]-s*mv8; } /*================= Drawing ===========================*/ var time_old = 0; var animate = function(time) { var dt = time-time_old; rotateZ(mov_matrix, dt*0.005);//time rotateY(mov_matrix, dt*0.002); rotateX(mov_matrix, dt*0.003); time_old = time; gl.enable(gl.DEPTH_TEST); gl.depthFunc(gl.LEQUAL); gl.clearColor(0.5, 0.5, 0.5, 0.9); gl.clearDepth(1.0); gl.viewport(0.0, 0.0, canvas.width, canvas.height); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.uniformMatrix4fv(Pmatrix, false, proj_matrix); gl.uniformMatrix4fv(Vmatrix, false, view_matrix); gl.uniformMatrix4fv(Mmatrix, false, mov_matrix); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer); gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); window.requestAnimationFrame(animate); } animate(0); </script> </body> </html> If you run this example, it will produce the following output − Print Page Previous Next Advertisements ”;
WebGL – Quick Guide
WebGL – Quick Guide ”; Previous Next WebGL – Introduction A few years back, Java applications – as a combination of applets and JOGL – were used to process 3D graphics on the Web by addressing the GPU (Graphical Processing Unit). As applets require a JVM to run, it became difficult to rely on Java applets. A few years later, people stopped using Java applets. The Stage3D APIs provided by Adobe (Flash, AIR) offered GPU hardware accelerated architecture. Using these technologies, programmers could develop applications with 2D and 3D capabilities on web browsers as well as on IOS and Android platforms. Since Flash was a proprietary software, it was not used as web standard. In March 2011, WebGL was released. It is an openware that can run without a JVM. It is completely controlled by the web browser. The new release of HTML 5 has several features to support 3D graphics such as 2D Canvas, WebGL, SVG, 3D CSS transforms, and SMIL. In this tutorial, we will be covering the basics of WebGL. What is OpenGL? OpenGL (Open Graphics Library) is a cross-language, cross-platform API for 2D and 3D graphics. It is a collection of commands. OpenGL4.5 is the latest version of OpenGL. The following table lists a set of technologies related to OpenGL. API Technology Used OpenGL ES It is the library for 2D and 3D graphics on embedded systems – including consoles, phones, appliances, and vehicles. OpenGL ES 3.1 is its latest version. It is maintained by the Khronos Group www.khronos.org JOGL It is the Java binding for OpenGL. JOGL 4.5 is its latest version and it is maintained by jogamp.org. WebGL It is the JavaScript binding for OpenGL. WebGL 1.0 is its latest version and it is maintained by the khronos group. OpenGLSL OpenGL Shading Language. It is a programming language which is a companion to OpenGL 2.0 and higher. It is a part of the core OpenGL 4.4 specification. It is an API specifically tailored for embedded systems such as those present on mobile phones and tablets. Note − In WebGL, we use GLSL to write shaders. What is WebGL? WebGL (Web Graphics Library) is the new standard for 3D graphics on the Web, It is designed for the purpose of rendering 2D graphics and interactive 3D graphics. It is derived from OpenGL”s ES 2.0 library which is a low-level 3D API for phones and other mobile devices. WebGL provides similar functionality of ES 2.0 (Embedded Systems) and performs well on modern 3D graphics hardware. It is a JavaScript API that can be used with HTML5. WebGL code is written within the <canvas> tag of HTML5. It is a specification that allows Internet browsers access to Graphic Processing Units (GPUs) on those computers where they were used. Who Developed WebGL An American-Serbian software engineer named Vladimir Vukicevic did the foundation work and led the creation of WebGL In 2007, Vladimir started working on an OpenGL prototype for Canvas element of the HTML document. In March 2011, Kronos Group created WebGL. Rendering Rendering is the process of generating an image from a model using computer programs. In graphics, a virtual scene is described using information like geometry, viewpoint, texture, lighting, and shading, which is passed through a render program. The output of this render program will be a digital image. There are two types of rendering − Software Rendering − All the rendering calculations are done with the help of CPU. Hardware Rendering − All the graphics computations are done by the GPU (Graphical processing unit). Rendering can be done locally or remotely. If the image to be rendered is way too complex, then rendering is done remotely on a dedicated server having enough of hardware resources required to render complex scenes. It is also called as server-based rendering. Rendering can also be done locally by the CPU. It is called as client-based rendering. WebGL follows a client-based rendering approach to render 3D scenes. All the processing required to obtain an image is performed locally using the client”s graphics hardware. GPU According to NVIDIA, a GPU is “a single chip processor with integrated transform, lighting, triangle setup/clipping, and rendering engines capable of processing a minimum of 10 million polygons per second.” Unlike multi-core processors with a few cores optimized for sequential processing, a GPU consists of thousands of smaller cores that process parallel workloads efficiently. Therefore, the GPU accelerates the creation of images in a frame buffer (a portion of ram which contains a complete frame data) intended for output to a display. GPU Accelerated Computing In GPU accelerated computing, the application is loaded into the CPU. Whenever it encounters a compute-intensive portion of the code, then that portion of code will be loaded and run on the GPU. It gives the system the ability to process graphics in an efficient way. GPU will have a separate memory and it runs multiple copies of a small portion of the code at a time. The GPU processes all the data which is in its local memory, not the central memory. Therefore, the data that is needed to be processed by the GPU should be loaded/copied to the GPU memory and then be processed. In the systems having the above architecture, the communication overhead between the CPU and GPU should be reduced to achieve faster processing of 3D programs. For this, we have to copy all the data and keep it on the GPU, instead of communicating with the GPU repeatedly. Browsers Supported The following tables show a list of browsers that support WebGL − Web Browsers Browser Name Version Support Internet Explorer 11 and above Complete support Google Chrome 39 and above Complete support Safari 8 Complete support Firefox 36 and above Partial support Opera 27 and above Partial support Mobile Browsers Browser Name Version Support Chrome for Android 42 Partial support Android browser 40 Partial support IOS Safari 8.3 Complete support Opera Mini 8 Does not support Blackberry Browser 10 Complete support IE
WebGL – Useful Resources
WebGL – Useful Resources ”; Previous Next The following resources contain additional information on WebGL. Please use them to get more in-depth knowledge on this topic. Useful Video Courses Three.js & WebGL 3D Programming Crash Course (VR, OpenGL) 11 Lectures 1 hours Frahaan Hussain More Detail WebGL 2D/3D Programming and Graphics Rendering For The Web 29 Lectures 4 hours Frahaan Hussain More Detail Unity Android : Build 3D ZigZag Racing Game with Unity & C# Most Popular 65 Lectures 11 hours Raja Biswas More Detail Three.js & WebGL 3D Programming Crash Course (VR, OpenGL) 9 Lectures 1 hours Frahaan Hussain More Detail Print Page Previous Next Advertisements ”;
WebGL – Shaders
WebGL – Shaders ”; Previous Next Shaders are the programs that run on GPU. Shaders are written in OpenGL ES Shader Language (known as ES SL). ES SL has variables of its own, data types, qualifiers, built-in inputs and outputs. Data Types The following table lists the basic data types provided by OpenGL ES SL. Sr.No. Type & Description 1 void Represents an empty value. 2 bool Accepts true or false. 3 int This is a signed integer data type. 4 float This is a floating scalar data type. 5 vec2, vec3, vec4 n-component floating point vector 6 bvec2, bvec3, bvec4 Boolean vector 7 ivec2, ivec3, ivec4 signed integer vector 8 mat2, mat3, mat4 2×2, 3×3, 4×4 float matrix 9 sampler2D Access a 2D texture 10 samplerCube Access cube mapped texture Qualifiers There are three main qualifiers in OpenGL ES SL − Sr.No. Qualifier & Description 1 attribute This qualifier acts as a link between a vertex shader and OpenGL ES for per-vertex data. The value of this attribute changes for every execution of the vertex shader. 2 uniform This qualifier links shader programs and the WebGL application. Unlike attribute qualifier, the values of uniforms do not change. Uniforms are read-only; you can use them with any basic data types, to declare a variable. Example − uniform vec4 lightPosition; 3 varying This qualifier forms a link between a vertex shader and fragment shader for interpolated data. It can be used with the following data types − float, vec2, vec3, vec4, mat2, mat3, mat4, or arrays. Example − varying vec3 normal; Vertex Shader Vertex shader is a program code, which is called on every vertex. It transforms (move) the geometry (ex: triangle) from one place to other. It handles the data of each vertex (per-vertex data) such as vertex coordinates, normals, colors, and texture coordinates. In the ES GL code of vertex shader, programmers have to define attributes to handle data. These attributes point to a Vertex Buffer Object written In JavaScript. The following tasks can be performed using vertex shaders along with vertex transformation − Vertex transformation Normal transformation and normalization Texture coordinate generation Texture coordinate transformation Lighting Color material application Predefined Variables OpenGL ES SL provides the following predefined variables for vertex shader − Sr.No. Variables & Description 1 highp vec4 gl_Position; Holds the position of the vertex. 2 mediump float gl_PointSize; Holds the transformed point size. The units for this variable are pixels. Sample Code Take a look at the following sample code of a vertex shader. It processes the vertices of a triangle. attribute vec2 coordinates; void main(void) { gl_Position = vec4(coordinates, 0.0, 1.0); }; If you observe the above code carefully, we have declared an attribute variable with the name coordinates. (This variable will be associated with the Vertex Buffer Object using the method getAttribLocation(). The attribute coordinates is passed as a parameter to this method along with the shader program object.) In the second step of the given vertex shader program, the gl_position variable is defined. gl_Position gl_Position is the predefined variable which is available only in the vertex shader program. It contains the vertex position. In the above code, the coordinates attribute is passed in the form of a vector. As vertex shader is a per-vertex operation, the gl_position value is calculated for each vertex. Later, the gl_position value is used by primitive assembly, clipping, culling, and other fixed functionality operations that operate on the primitives after the vertex processing is over. We can write vertex shader programs for all possible operations of vertex shader, which we will discuss individually in this tutorial. Fragment Shader A mesh is formed by multiple triangles, and the surface of the each triangle is known as a fragment. A fragment shader is the code that runs on every pixel on each fragment. This is written to calculate and fill the color on individual pixels. The following tasks can be performed using fragment shaders − Operations on interpolated values Texture access Texture application Fog Color sum Predefined Variables OpenGL ES SL provides the following predefined variables for fragment shader − Sr.No. Variables & Description 1 mediump vec4 gl_FragCoord; Holds the fragment position within the frame buffer. 2 bool gl_FrontFacing; Holds the fragment that belongs to a front-facing primitive. 3 mediump vec2 gl_PointCoord; Holds the fragment position within a point (point rasterization only). 4 mediump vec4 gl_FragColor; Holds the output fragment color value of the shader 5 mediump vec4 gl_FragData[n] Holds the fragment color for color attachment n. Sample Code The following sample code of a fragment shader shows how to apply color to every pixel in a triangle. void main(void) { gl_FragColor = vec4(0, 0.8, 0, 1); } In the above code, the color value is stored in the variable gl.FragColor. The fragment shader program passes the output to the pipeline using fixed function variables; FragColor is one of them. This variable holds the color value of the pixels of the model. Storing and Compiling the Shader Programs Since shaders are independent programs, we can write them as a separate script and use in the application. Or, you can store them directly in string format, as shown below. var vertCode = ”attribute vec2 coordinates;” + ”void main(void) {” + ” gl_Position = vec4(coordinates, 0.0, 1.0);” + ”}”; Compiling the Shader Compilation involves following three steps − Creating the shader object Attaching the source code to the created shader object Compiling the program Creating the Vertex Shader To create an empty shader, WebGL provides a method called createShader(). It creates and returns the shader object. Its syntax is as follows − Object createShader (enum type) As observed in the syntax, this method accepts a predefined enum value as parameter. We have two options for this − gl.VERTEX_SHADER for creating vertex shader gl.FRAGMENT_SHADER for creating fragment shader. Attaching the Source to the Shader You can attach the source code to the created shader object using the method shaderSource(). Its syntax is as follows − void shaderSource(Object shader,