webgl 顶点、片元着色器传参,绘制彩色三角形
一:顶点着色器编码
顶点着色器需要接收的参数使用 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)
