You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:22:32