一:顶点着色器编码

顶点着色器需要接收的参数使用 attribute 关键字声明。a_Position 点的位置。a_Color 颜色

varying 关键字声明变量,需要传递给片元着色器的变量。

// 顶点着色器
const VSHADER_SOURCE = `
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
  void main() {
    v_Color = a_Color;
    gl_Position = a_Position;
  }
`;

二:片元着色器编码

片元着色器使用 varying 关键字声明从顶点着色器获取的变量 v_Color

// 片元着色器
const FSHADER_SOURCE = `
  precision mediump float;
  varying vec4 v_Color;
  void main() {
    gl_FragColor = v_Color;
  }
`;

三:交错组织顶点-颜色数组

为了优化程序,使用一个数组组织点位和颜色两个参数,这样只需要创建一个缓冲区即可。

每 5 个数字代表一个顶点,前 2 个代表顶点的位置,后 3 个代表顶点的颜色。 

 // 创建顶点
  const vertices = new Float32Array([
    0.0, 0.5, 1.0,0.0,0.0,   // 顶点1的坐标
    -0.5, -0.5, 0.0,1.0,0.0, // 顶点2的坐标
    0.5, -0.5, 0.0,0.0,1.0,  // 顶点4的坐标
  ])

四:使用缓冲区向顶点着色器传参

回顾一下使用缓冲区为顶点着色器传递参数的步骤

1,创建缓冲区对象

 // 创建缓冲区对象
  const vertexBuffer = gl.createBuffer();

2,将缓冲区对象绑定到 target 对象上

  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

3,将顶点坐标数据写入缓冲区对象

  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

4,将缓冲区对象分配给对应的 attribute 变量

 const FSIZE = vertices.BYTES_PER_ELEMENT;

  const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  // 将缓冲区对象分配给 a_Position 变量
  gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE*5, 0);

 const a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  // 将缓冲区对象分配给 a_Position 变量
  gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE*5, FSIZE*2);

5,开启 attribute 变量

  gl.enableVertexAttribArray(a_Position);
  gl.enableVertexAttribArray(a_Color);

五:gl.vertexAttribPointer() 的步进与偏移量

gl.vertexAttribPointer()

第四个参数: 相邻两个顶点之间的字节数,

最后一个参数:指定相邻两个顶点间的字节数,即 attribute 变量从指定缓冲区中的何处开始存储,如果是从起始位置开始,该参数应设为0。

第四步时将 vertices 数组中每个元素的大小(字节数)存储到 FISIZE 中。

所以4.4 中 gl.vertexAttribPointer() 第四个参数都是 FSIZE * 5,

由于前两个数字代表顶点,所以顶点参数是从 0 开始,则将缓冲区对象分配给 a_Position 变量时

最后一个参数是0

gl.vertexAttribPointer( a_Position, 2, gl.FLOAT, false, FSIZE*5, 0)

后三个数代表颜色,是从第三个数开始的,所以要偏移两个数字。最后一个参数是 FSIZE * 2

gl.vertexAttribPointer( a_Color,  3,  gl.FLOAT,  false,  FSIZE * 5,  FSIZE * 2)

更多推荐