在 WebGL 2 中,shaderSource()
是一个非常重要的方法,用于向 WebGL 程序的着色器对象中加载着色器代码。以下是关于 shaderSource()
的详细说明:
1. 方法定义
shaderSource()
是 WebGL 2 API 的一部分,用于将着色器代码(通常是用 GLSL 编写的)加载到着色器对象中。它是一个 WebGLRenderingContext 的方法。
2. 语法
void gl.shaderSource(shader, source);
参数
-
shader
- 类型:
WebGLShader
- 指定要加载着色器代码的着色器对象。着色器对象可以通过
gl.createShader()
创建。
- 类型:
-
source
- 类型:
string
- 包含着色器代码的字符串。着色器代码是用 GLSL(OpenGL Shading Language)编写的,用于定义顶点着色器或片段着色器的逻辑。
- 类型:
3. 使用场景
在 WebGL 中,渲染管线分为两个主要阶段:顶点着色器(Vertex Shader)和片段着色器(Fragment Shader)。每个着色器都需要一段 GLSL 代码来定义其行为。shaderSource()
的作用就是将这些代码加载到对应的着色器对象中。
4. 示例代码
以下是一个完整的示例,展示如何使用 shaderSource()
加载着色器代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL2 - Render a Triangle</title>
<style>
canvas {
display: block;
margin: 0 auto;
border: 1px solid black;
}
</style>
</head>
<body>
<canvas id="glCanvas" width="640" height="480"></canvas>
<script>
// 获取 canvas 元素
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl2');
if (!gl) {
alert('WebGL2 不被支持');
throw new Error('WebGL2 不被支持');
}
// 顶点着色器代码
const vertexShaderSource = `#version 300 es
in vec4 a_position;
void main() {
gl_Position = a_position;
}
`;
// 片段着色器代码
const fragmentShaderSource = `#version 300 es
precision highp float;
out vec4 outColor;
void main() {
outColor = vec4(1.0, 0.5, 0.2, 1.0); // 橙色
}
`;
// 创建着色器
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('着色器编译失败:', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
// 创建程序
function createProgram(gl, 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('程序链接失败:', gl.getProgramInfoLog(program));
gl.deleteProgram(program);
return null;
}
return program;
}
// 创建顶点着色器和片段着色器
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
// 创建程序并使用
const program = createProgram(gl, vertexShader, fragmentShader);
gl.useProgram(program);
// 顶点数据
const vertices = new Float32Array([
-0.5, -0.5, 0.0, // 顶点1
0.5, -0.5, 0.0, // 顶点2
0.0, 0.5, 0.0 // 顶点3
]);
// 创建缓冲区对象
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); // 绑定缓冲区对象到 ARRAY_BUFFER
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); // 传输顶点数据到缓冲区
// 获取顶点属性位置并启用
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
// 设置顶点属性指针
gl.vertexAttribPointer(
positionAttributeLocation, // 属性位置
3, // 每个顶点的分量数量
gl.FLOAT, // 数据类型
false, // 是否归一化
0, // 每个顶点的字节偏移量
0 // 数据起始偏移量
);
// 设置视口大小
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// 清空画布
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 设置背景颜色为黑色
gl.clear(gl.COLOR_BUFFER_BIT);
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>
</body>
</html>
5. 注意事项
- 着色器代码格式:
shaderSource()
的第二个参数是一个字符串,因此需要确保 GLSL 代码格式正确,且没有语法错误。 - 编译错误处理:加载着色器代码后,需要调用
gl.compileShader()
编译着色器,并通过gl.getShaderParameter()
和gl.getShaderInfoLog()
检查编译是否成功。 - 着色器类型:
shaderSource()
的第一个参数必须是一个有效的 WebGLShader 对象,且其类型(顶点着色器或片段着色器)必须与代码匹配。