WebGL 3着色器和GLSL
我们之前提到过着色器和GLSL,但是没有涉及细节,你可能已经对此有所了解, 但以防万一,这里将详细讲解着色器和GLSL。
在工作原理中我们提到,WebGL每次绘制需要两个着色器, 一个顶点着色器和一个片段着色器,每一个着色器都是一个方法。
一个顶点着色器和一个片段着色器链接在一起放入一个着色程序中(或者只叫程序)。
一个典型的WebGL应用会有多个着色程序。
顶点着色器
一个顶点着色器的工作是生成裁剪空间坐标值,通常是以下的形式
void main() {gl_Position = doMathToMakeClipspaceCoordinates
}
每个顶点调用一次(顶点)着色器,每次调用都需要设置一个特殊的全局变量gl_Position
, 该变量的值就是裁剪空间坐标值。
顶点着色器需要的数据,可以通过以下三种方式获得。
- Attributes 属性 (从缓冲中获取的数据)
- Uniforms 全局变量 (在一次绘制中对所有顶点保持一致值)
- Textures 纹理 (从像素或纹理元素中获取的数据)
Attributes 属性
最常用的方法是缓冲和属性,在工作原理 中讲到了缓冲和属性,你可以创建缓冲
var buf = gl.createBuffer();
将数据存入缓冲
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, someData, gl.STATIC_DRAW);
然后初始化的时候,在你制作的(着色)程序中找到属性所在地址
var positionLoc = gl.getAttribLocation(someShaderProgram, "a_position");
在渲染的时候告诉WebGL怎么从缓冲中获取数据传递给属性
// 开启从缓冲中获取数据
gl.enableVertexAttribArray(positionLoc);var numComponents = 3; // (x, y, z)
var type = gl.FLOAT; // 32位浮点数据
var normalize = false; // 不标准化
var offset = 0; // 从缓冲起始位置开始获取
var stride = 0; // 到下一个数据跳多少位内存// 0 = 使用当前的单位个数和单位长度 ( 3 * Float32Array.BYTES_PER_ELEMENT )gl.vertexAttribPointer(positionLoc, numComponents, type, false, stride, offset);
参考:
WebGL 着色器和GLSL
18.WebGL渲染和执行流程 | 前端技术积累