WebGL绘制圆柱体无渲染输出问题排查求助
WebGL圆柱体无渲染结果问题排查
我正尝试用WebGL绘制圆柱体,已经接近实现,但目前没有任何渲染结果,也未发现明显问题。着色器代码中最初的矩阵乘法顺序错误会导致图形显示异常,但调整顺序后反而完全无法渲染。
代码片段
JavaScript代码
var gl; var gl; var vertices = []; var indices = []; var r = 0.5; var height = 1.0; var numSegs = 30; var modelMatrix; var projectionMatrix; var program; var viewMatrix; window.onload = function init() { var canvas = document.getElementById("gl-canvas"); gl = WebGLUtils.setupWebGL(canvas); if (!gl) { alert("WebGL isn't available"); } gl.enable(gl.DEPTH_TEST); for (let i = 0; i < numSegs; i++) { var theta = (i / numSegs) * 2 * Math.PI; var x = r * Math.cos(theta); var y = r * Math.sin(theta); vertices.push(x, y, -height / 2); vertices.push(x, y, height / 2); } for (let i = 0; i < numSegs; i++) { indices.push(2 * i, (2 * i + 1) % (2 * numSegs), (2 * i + 2) % (2 * numSegs)); indices.push((2 * i + 1) % (2 * numSegs), (2 * i + 3) % (2 * numSegs), (2 * i + 2) % (2 * numSegs)); } vertices.push(0, 0, -height / 2); vertices.push(0, 0, height / 2); for (let i = 0; i < numSegs; i++) { indices.push(vertices.length / 3 - 2, (2 * i) % (2 * numSegs), (2 * (i + 1)) % (2 * numSegs)); indices.push(vertices.length / 3 - 1, (2 * i + 1) % (2 * numSegs), (2 * (i + 1) + 1) % (2 * numSegs)); } // Configure WebGL gl.viewport(0, 0, canvas.width, canvas.height); gl.clearColor(1.0, 1.0, 1.0, 1.0); // Load shaders and initialize attribute buffers program = initShaders(gl, "vertex-shader", "fragment-shader"); // Assign to program variable gl.useProgram(program); // Load the data into the GPU var bufferId = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, bufferId); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); var indexBuffer = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); var vPosition = gl.getAttribLocation(program, "vPosition"); gl.vertexAttribPointer(vPosition, 3, gl.FLOAT, false, 0, 0); gl.enableVertexAttribArray(vPosition); projectionMatrix = mat4.create(); modelMatrix = mat4.create(); viewMatrix = mat4.create(); render(); }; function render() { gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); var fov = 45 * Math.PI / 180; var aspect = gl.canvas.width / gl.canvas.height; var zNear = 0.1; var zFar = 100.0; mat4.translate(modelMatrix, modelMatrix, [0.0, 0.0, -5.0]); mat4.perspective(projectionMatrix, fov, aspect, zNear, zFar); mat4.lookAt(viewMatrix, [0, 0, 0], [1, 0, 0], [0, 1, 0]); gl.uniformMatrix4fv(gl.getUniformLocation(program, "projectionMatrix"), false, projectionMatrix); gl.uniformMatrix4fv(gl.getUniformLocation(program, "modelMatrix"), false, modelMatrix); gl.uniformMatrix4fv(gl.getUniformLocation(program, "viewMatrix"), false, viewMatrix); gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0); }
HTML代码
<!DOCTYPE html> <html> <head> <script id="vertex-shader" type="x-shader/x-vertex"> attribute vec4 vPosition; uniform mat4 modelMatrix; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; void main() { //gl_Position = vPosition*projectionMatrix*modelMatrix*viewMatrix; mat4 matrix = viewMatrix * modelMatrix; gl_Position = projectionMatrix * matrix * vPosition; } </script> <script id="fragment-shader" type="x-shader/x-fragment"> precision mediump float; void main() { gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); } </script> <script type="text/javascript" src="webgl-utils.js"></script> <script type="text/javascript" src="initShaders.js"></script> <script type="text/javascript" src="cylinder.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script> </head> <body> <canvas id="gl-canvas" width="512" height="512"> Oops ... your browser doesn't support the HTML5 canvas element </canvas> </body> </html>
问题分析与修复方案
1. 视图方向错误导致物体不可见
当前mat4.lookAt设置的相机看向[1,0,0](x轴正方向),但圆柱体被平移到了z=-5的位置,相机完全看不到它。这是核心问题。
修复:修改lookAt参数,让相机看向z轴负方向,对准圆柱体所在位置:
mat4.lookAt(viewMatrix, [0, 0, 0], [0, 0, -1], [0, 1, 0]);
2. 模型矩阵重复平移导致物体被裁剪
render函数每次执行都会调用mat4.translate(modelMatrix, modelMatrix, [0.0, 0.0, -5.0]);,这会让圆柱体持续向z轴负方向移动,最终超出zFar范围被裁剪掉。
修复:把模型矩阵的平移操作移到init函数中,只执行一次:
// 在init函数中,创建modelMatrix之后添加 mat4.translate(modelMatrix, modelMatrix, [0.0, 0.0, -5.0]);
同时删除render函数中的重复平移代码。
3. 矩阵乘法顺序确认
你调整后的着色器矩阵顺序是正确的:projectionMatrix * viewMatrix * modelMatrix * vPosition,符合WebGL列向量的乘法规则,不需要再修改。
额外检查项
- 确认
webgl-utils.js和initShaders.js文件正确加载,无404错误 - 打开浏览器控制台(F12)查看是否有WebGL报错,比如着色器编译失败、uniform变量未找到等
内容的提问来源于stack exchange,提问作者daCornchipe
相关产品推荐
相关产品推荐

