WebGL - 颜色

  • 简述

    在我们之前的所有示例中,我们通过将所需的颜色值分配给gl_FragColor变量来为对象应用颜色。除此之外,我们可以为每个顶点定义颜色——就像顶点坐标和索引一样。本章以一个例子来演示如何使用 WebGL 将颜色应用于四边形。
  • 应用颜色

    要应用颜色,您必须使用 JavaScript 数组中的 RGB 值为每个顶点定义颜色。您可以为所有顶点分配相同的值以使对象具有独特的颜色。定义颜色后,您必须创建一个颜色缓冲区并将这些值存储在其中,并将其关联到顶点着色器属性。
    在顶点着色器中,连同坐标属性(保存顶点的位置),我们定义了一个属性和一个变量来处理颜色。
    color属性保存每个顶点的颜色值,varying作为输入传递给片段着色器的变量。因此,我们必须将颜色值分配给varying
    在片段着色器中,保存颜色值的 varying 被分配给gl_FragColor 它保存对象的最终颜色。
  • 应用颜色的步骤

    需要以下步骤来创建 WebGL 应用程序来绘制四边形并为其应用颜色。
    第 1 步 - 准备画布并获取 WebGL 渲染上下文
    在此步骤中,我们使用getContext()获取 WebGL 渲染上下文对象。
    第 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, 1,0,0, 0,1,0, 1,0,1,];
    indices = [3,2,1,3,1,0]; 
    
    第 3 步 - 创建和编译着色器程序
    在这一步中,您需要编写顶点着色器和片段着色器程序,编译它们,并通过链接这两个程序来创建组合程序。
    • Vertex Shader - 在程序的顶点着色器中,我们定义矢量属性来存储 3D 坐标(位置)和每个顶点的颜色。声明了一个可变变量以将颜色值从顶点着色器传递到片段着色器。最后,将存储在 color 属性中的值分配给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 - 在片段着色器中,我们将varying分配给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>
    
    如果运行此示例,它将产生以下输出 -