WebGL输出缓冲区异常:非原点无旋转对象显示乱三角而非立方体
问题分析与修复方案
核心问题定位
你的代码里存在两处关键错误,直接导致了渲染异常:
- 相机旋转矩阵未正确合并到视图矩阵中,后续视图矩阵仅包含平移操作,完全丢失了相机旋转信息
mat4.multiply调用不符合gl-matrix的API规范,传入多个矩阵参数会触发未定义行为
修复后的完整代码
const fieldOfView = (this.camera.FOV * Math.PI) / 180; // 角度转弧度 const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight; const zNear = 0.1; const zFar = this.camera.RENDER_DISTANCE; const projectionMatrix = mat4.perspective(mat4.create(), fieldOfView, aspect, zNear, zFar); const viewMatrix = mat4.create(); // 按Y→X→Z顺序应用相机旋转(可根据需求调整顺序) mat4.rotateY(viewMatrix, viewMatrix, this.camera.ry); mat4.rotateX(viewMatrix, viewMatrix, this.camera.rx); mat4.rotateZ(viewMatrix, viewMatrix, this.camera.rz); // 反向平移相机位置,模拟相机移动效果 mat4.translate(viewMatrix, viewMatrix, [-this.camera.x, -this.camera.y, -this.camera.z]); let buffers = { position: [], color: [], }; for (let object of this.objects) { if (this.camera.visible(object)) { const modelMatrix = mat4.create(); mat4.translate(modelMatrix, modelMatrix, [object.position.x, object.position.y, object.position.z]); mat4.rotateX(modelMatrix, modelMatrix, object.rotation.x); mat4.rotateY(modelMatrix, modelMatrix, object.rotation.y); mat4.rotateZ(modelMatrix, modelMatrix, object.rotation.z); mat4.scale(modelMatrix, modelMatrix, [object.size.x, object.size.y, object.size.z]); // 正确计算模型视图矩阵:视图矩阵 × 模型矩阵 const modelViewMatrix = mat4.create(); mat4.multiply(modelViewMatrix, viewMatrix, modelMatrix); const cubeVertices = this.cubev(1) for (let i = 0; i < cubeVertices.length; i += 3) { const vertex = vec3.transformMat4(vec3.create(), [cubeVertices[i], cubeVertices[i + 1], cubeVertices[i + 2]], modelViewMatrix); buffers.position.push(...vertex); } const color = object.material.color; for (let i = 0; i < cubeVertices.length / 3; i++) { buffers.color.push(...color); } } } return buffers;
关键修复说明
- 简化视图矩阵构建:直接在初始的单位矩阵上连续应用旋转、平移操作,无需额外创建单独的旋转矩阵变量,避免矩阵合并遗漏
- 修正矩阵乘法调用:gl-matrix的
mat4.multiply仅接受三个参数(目标矩阵、左操作数矩阵、右操作数矩阵),正确计算modelViewMatrix = 视图矩阵 × 模型矩阵 - 调整旋转顺序:默认使用Y→X→Z的旋转顺序(符合多数3D场景的相机控制逻辑),你可根据自身需求修改旋转顺序
修改后,模型视图矩阵的计算逻辑恢复正常,非原点位置的物体将正确渲染为立方体。
内容的提问来源于stack exchange,提问作者renderthegreat
相关产品推荐
相关产品推荐

