WebGL - 颜色

在前面的所有示例中,我们通过为 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>