在 WebGL2 中,gl.getShaderInfoLog() 是一个非常重要的函数,用于获取着色器编译过程中的日志信息。它通常用于调试着色器代码,帮助开发者了解着色器编译失败的原因。
1. 函数定义
gl.getShaderInfoLog(shader) 是 WebGL2 的一个方法,它的作用是返回一个字符串,其中包含了指定着色器的编译日志信息。
-
参数
shader:一个WebGLShader对象,表示要查询日志的着色器。
-
返回值
- 返回一个字符串,包含着色器编译过程中的日志信息。如果着色器编译成功,通常返回一个空字符串;如果编译失败,则返回错误信息。
2. 使用场景
当你尝试编译一个着色器时,可能会因为语法错误、变量未定义或其他问题导致编译失败。gl.getShaderInfoLog() 可以帮助你获取这些错误信息,从而快速定位问题。
3. 示例代码
以下是一个完整的示例, 可直接运行:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL2 getShaderInfoLog</title>
<style>
button {
margin: 10px;
padding: 10px;
font-size: 16px;
}
#glCanvas {
width: 800px;
height: 600px;
}
</style>
</head>
<body>
<h1>WebGL2 getShaderInfoLog Example</h1>
<div id="container">
<div id="buttons">
<button id="compileCorrectShader">shader代码编译正确</button>
<button id="compileErrorShader">shader代码编译错误</button>
</div>
<canvas id="glCanvas"></canvas>
</div>
<script>
// 创建 WebGL2 上下文
const canvas = document.getElementById('glCanvas');
const gl = canvas.getContext('webgl2');
if (!gl) {
throw new Error('WebGL2 is not supported');
}
// 正确的顶点着色器代码
const correctVertexShaderSource = `#version 300 es
in vec4 a_position;
void main() {
gl_Position = a_position;
}
`;
// 错误的顶点着色器代码(故意拼写错误)
const errorVertexShaderSource = `#version 300 es
in vec4 a_position;
void main() {
gl_Position = a_positoin; // 错误:变量名拼写错误
}
`;
const fragmentShaderSource = `#version 300 es
precision mediump float;
out vec4 fragColor;
void main() {
fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
// 编译着色器的函数
function compileShader(source, type) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
// 检查编译状态
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const log = gl.getShaderInfoLog(shader);
// alert('Shader compilation failed:', log);
throw new Error('Shader compilation failed:', log);
gl.deleteShader(shader);
return null;
}
return shader;
}
// 创建program
function compileProgram(vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 检查链接状态
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const infoLog = gl.getProgramInfoLog(program);
throw new Error('程序连接失败: ' + infoLog );
}
return program;
}
function render(vertexShaderSource) {
const vertexShader = compileShader(vertexShaderSource, gl.VERTEX_SHADER);
const fragmentShader = compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER);
const program = compileProgram(vertexShader, fragmentShader);
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// 使用程序
gl.useProgram(program);
// 获取并启用顶点属性
const positionAttribLoc = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttribLoc);
gl.vertexAttribPointer(positionAttribLoc, 3, gl.FLOAT, false, 0, 0);
// 清除并绘制
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
// 按钮事件处理
document.getElementById('compileCorrectShader').addEventListener('click', () => {
render(correctVertexShaderSource);
});
document.getElementById('compileErrorShader').addEventListener('click', () => {
render(errorVertexShaderSource);
});
</script>
</body>
</html>
4. 常见错误信息
- 语法错误:如果着色器代码中存在语法问题,比如拼写错误、缺少分号等,
gl.getShaderInfoLog()会返回具体的错误信息,指出错误的位置。 - 变量未定义:如果使用了未声明的变量,日志中会提示变量未定义。
- 类型不匹配:如果着色器代码中存在类型不匹配的问题,也会在日志中显示。
5. 注意事项
- 日志内容:
gl.getShaderInfoLog()返回的日志内容格式可能因浏览器或显卡驱动的不同而有所差异,但通常会包含错误的行号具体和描述。 - 性能影响:虽然获取日志信息对性能影响不大,但在生产环境中,建议在调试完成后移除相关代码,以避免不必要的开销。