在前面的所有示例中,我们通过为 gl_FragColor 变量指定所需的颜色值,将颜色应用于对象.除此之外,我们可以为每个顶点定义颜色和减号;就像顶点坐标和索引一样.本章举例说明如何使用WebGL将颜色应用于四边形.
要应用颜色,您必须定义颜色JavaScript数组中使用RGB值的每个顶点的颜色.您可以为所有顶点指定相同的值,以使对象具有唯一的颜色.定义颜色后,您必须创建一个颜色缓冲区并将这些值存储在其中,并将其与顶点着色器属性相关联.
在顶点着色器中,以及coordinates属性(保持顶点的位置),我们定义属性和变化来处理颜色.
颜色属性保存每个顶点的颜色值,变化是作为片段着色器输入传递的变量.因此,我们必须将颜色值分配给变化.
在片段着色器中,变化保持颜色值分配给 gl_FragColor ,它保存对象的最终颜色.
创建一个WebGL应用程序以绘制Quad并为其应用颜色需要执行以下步骤.
步骤1 : 号;准备画布并获取WebGL渲染上下文
在此步骤中,我们使用 getContext()获取WebGL渲染上下文对象.
第2步和第2步;定义几何并将其存储在缓冲对象中
可以使用两个三角形绘制正方形.因此,在此示例中,我们提供两个三角形(具有一个公共边)和索引的顶点.由于我们想要为其应用颜色,因此还定义了一个包含颜色值的变量,并为每个颜色值分配了颜色值(红色,蓝色,绿色和粉红色).
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,0,0,0,0,1,0,1,0,1,]; indices = [3,2,1,3,1,0];
第3步和第3步;创建和编译着色器程序
在此步骤中,您需要编写顶点着色器和片段着色器程序,编译它们,并通过链接这两个程序来创建组合程序.
顶点着色器 : 在程序的顶点着色器中,我们定义了矢量属性来存储3D坐标(位置)和每个顶点的颜色.声明 varing 变量将颜色值从顶点着色器传递到片段着色器.最后,存储在color属性中的值被分配给 vary .
var vertCode = 'attribute vec3 coordinates;'+ 'attribute vec3 color;'+ 'varying vec3 vColor;'+ 'void main(void) {' + ' gl_Position = vec4(coordinates, 1.0);' + 'vColor = color;'+ '}';
片段着色器 : 在片段着色器中,我们将变化分配给 gl_FragColor 变量.
var fragCode = 'precision mediump float;'+ 'varying vec3 vColor;'+ 'void main(void) {'+ 'gl_FragColor = vec4(vColor, 1.);'+ '}';
步骤4 : 将着色器程序与缓冲区对象相关联
在此步骤中,我们将缓冲区对象与着色器程序相关联.
第5步 : 绘制所需对象
由于我们使用索引绘制两个将形成四边形的三角形,因此我们将使用方法 drawElements().对于这种方法,我们必须传递索引的数量. indices.length 的值表示索引的数量.
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
以下程序演示了如何使用WebGL应用程序绘制四边形并为其应用颜色.
<!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>