MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

使用着色器将颜色应用于WebGL

之前的展示中我们已经创建好了一个正方形,接下来我们要做的就是给它添加一抹色彩。添加颜色可以通过修改着色器来实现。

给顶点着色

在GL中,物体是由一系列顶点组成的,每一个顶点都有位置和颜色信息。在默认情况下,所有像素的颜色(以及它所有的属性,包括位置)都由线性插值计算得来,自动形成平滑的渐变。我们以前的顶点着色器没有给顶点添加任何特定的颜色——在顶点着色器与片段着色器之间给每个像素着白色,于是整个正方形被渲染成纯白。

现在我们假设正方形的每个顶点使用不同的颜色:红,黄,绿,白,以此渲染一个渐变的色彩。第一步,要给这些顶点建立相应的颜色。首先我们要创建一个顶点颜色数组,然后将它们存在WebGL的缓冲区中。为实现这一功能,我们在 initBuffers() 函数中加入如下代码:

  var colors = [
    1.0,  1.0,  1.0,  1.0,    // 白色
    1.0,  0.0,  0.0,  1.0,    // 红色
    0.0,  1.0,  0.0,  1.0,    // 绿色
    0.0,  0.0,  1.0,  1.0     // 蓝色
  ];
  
  squareVerticesColorBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
}

这段代码首先建立了一个JavaScript的数组,此数组中包含四组四值向量,每一组向量代表一个顶点的颜色。然后,创建一个WebGL缓冲区用来存储这些颜色——将数组中的值转换成WebGL所规定的浮点型后,存储在该缓冲区中。

为了实际使用这些颜色,我们继续修改顶点着色器,使得着色器可以从颜色缓冲区中正确取出颜色:

    <script id="shader-vs" type="x-shader/x-vertex">
      attribute vec3 aVertexPosition;
      attribute vec4 aVertexColor;
    
      uniform mat4 uMVMatrix;
      uniform mat4 uPMatrix;
      
      varying lowp vec4 vColor;
    
      void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vColor = aVertexColor;
      }
    </script>

与之前相比,这段代码的关键不同点在于:每个顶点都与一个颜色数组中的数值相连接。

给片段着色

我们先来复习一下之前构造的片段着色器:

    <script id="shader-fs" type="x-shader/x-fragment">
      void main(void) {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
      }
    </script>

为使每个像素都得到插值后的颜色,我们只需要在此从 vColor 变量中获取这个颜色的值:

    <script id="shader-fs" type="x-shader/x-fragment">
    	varying lowp vec4 vColor;
    	
      void main(void) {
        gl_FragColor = vColor;
      }
    </script>

这是一个非常简单的改变,每个片段只是根据其相对于顶点的位置得到一个插值过的颜色,而不是一个指定的颜色值。

带颜色的绘制

接下来,我们要在 initShader() 中初始化颜色属性,以便着色器程序使用

  vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
  gl.enableVertexAttribArray(vertexColorAttribute);

然后,我们便可以修改 drawScene() 使之在绘制正方形时使用这些颜色:

  gl.bindBuffer(gl.ARRAY_BUFFER, squareVerticesColorBuffer);
  gl.vertexAttribPointer(vertexColorAttribute, 4, gl.FLOAT, false, 0, 0);

查看完整代码 | 在新页面中打开示例

文档标签和贡献者

标签: 
 此页面的贡献者: Sincoyw, FuZhenn, ZhangMenghe
 最后编辑者: Sincoyw,