在 WebGL2 中,useProgram()
是一个非常重要的函数,用于指定当前的着色器程序(Shader Program)。以下是关于 useProgram()
的详细说明:
1. 函数定义
useProgram()
的作用是将一个着色器程序对象绑定到 WebGL 上下文的当前状态中,以便后续的渲染操作可以使用该着色器程序。
void gl.useProgram(program);
-
参数
program
:一个WebGLProgram
对象,表示要使用的着色器程序。如果传入null
,则会取消当前绑定的着色器程序。
2. 使用场景
在 WebGL2 的渲染流程中,着色器程序是核心组件之一,负责处理顶点数据和片元数据。useProgram()
用于在渲染过程中切换不同的着色器程序,以实现不同的渲染效果。
3. 示例代码
以下是一个可直接运行的示例,展示如何创建和使用着色器程序:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL2 Triangle</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; width: 600px; height: 400px; }
</style>
</head>
<body>
<canvas id="glCanvas"></canvas>
<script>
// 顶点着色器代码
const vertexShaderSource = `#version 300 es
layout(location = 0) in vec2 aPosition;
layout(location = 1) in vec3 aColor;
out vec3 vColor;
void main() {
gl_Position = vec4(aPosition, 0.0, 1.0);
vColor = aColor;
}
`;
// 片段着色器代码
const fragmentShaderSource = `#version 300 es
precision highp float;
in vec3 vColor;
out vec4 fragColor;
void main() {
fragColor = vec4(vColor, 1.0);
}
`;
// 初始化WebGL2上下文
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl2');
if (!gl) {
alert('WebGL2 not supported in your browser!');
throw new Error('WebGL2 not supported');
}
// 编译着色器
function compileShader(source, type) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('Shader compile error:', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
// 创建着色器程序
function createProgram(vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('Program link error:', gl.getProgramInfoLog(program));
gl.deleteProgram(program);
return null;
}
return program;
}
// 编译和链接着色器
const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);
const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);
const program = createProgram(vertexShader, fragmentShader);
// 顶点数据(位置和颜色)
const vertices = new Float32Array([
// 位置(x,y) 颜色(r,g,b)
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 // 顶点3:蓝色
]);
// 创建并绑定顶点缓冲区
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 配置顶点属性
const stride = 5 * Float32Array.BYTES_PER_ELEMENT; // 每个顶点5个浮点数(2位置 + 3颜色)
// 位置属性 (location = 0)
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, stride, 0);
gl.enableVertexAttribArray(0);
// 颜色属性 (location = 1)
gl.vertexAttribPointer(1, 3, gl.FLOAT, false, stride, 2 * Float32Array.BYTES_PER_ELEMENT);
gl.enableVertexAttribArray(1);
// 渲染函数
function render() {
gl.clearColor(0.1, 0.1, 0.1, 1.0); // 设置背景色
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.drawArrays(gl.TRIANGLES, 0, 3); // 绘制3个顶点
requestAnimationFrame(render);
}
// 开始渲染循环
render();
</script>
</body>
</html>
4. 注意事项
- 绑定顺序:在调用
useProgram()
之前,必须先创建并链接好着色器程序。 - 性能优化:如果在渲染过程中频繁切换着色器程序,可能会导致性能下降。尽量减少不必要的切换。
- 默认值:如果传入
null
,则当前的着色器程序会被取消绑定。