WebGL 透视投影矩阵不起作用

WebGL perspective projection matrix not working

正在尝试编写基本的 WebGL 程序,在屏幕上绘制一个三角形。没有任何投影矩阵它工作得很好,以及单位矩阵。但是当涉及到透视投影矩阵时,它什么也没有显示。这是我的代码:

const canvas = document.getElementById("viewport");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const gl = canvas.getContext("webgl2");
gl.viewport(0, 0, window.innerWidth, window.innerHeight);

const vs = gl.createShader(gl.VERTEX_SHADER);
const fs = gl.createShader(gl.FRAGMENT_SHADER);

gl.shaderSource(vs, document.getElementById("vs").innerText);
gl.shaderSource(fs, document.getElementById("fs").innerText);

gl.compileShader(vs);
gl.compileShader(fs);

if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)){
    const info = gl.getShaderInfoLog(vs);
    throw new Error("Error compiling vertex shader:\n\n" + info);
}

if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)){
    const info = gl.getShaderInfoLog(fs);
    throw new Error("Error compiling fragment shader:\n\n" + info);
}

const program = gl.createProgram();

gl.attachShader(program, vs);
gl.attachShader(program, fs);

gl.linkProgram(program);
gl.validateProgram(program);

gl.useProgram(program);

const position = [
    -0.5, -0.5, 0.0,
     0.0,  0.5, 0.0,
     0.5, -0.5, 0.0,
];

const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(position), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, null);

const projectionMatrix = [
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1,
];

const FOV = 70;
const NEAR_PLANE = .1;
const FAR_PLANE = 1000;

const aspectRatio = canvas.width / canvas.height;
const yScale = (1.0 / Math.tan((FOV / 2.0) * (Math.PI / 180.0))) * aspectRatio;
const xScale = yScale / aspectRatio;
const frustumLength = FAR_PLANE - NEAR_PLANE;

projectionMatrix[0] = xScale;
projectionMatrix[5] = yScale;
projectionMatrix[10] = ((FAR_PLANE + NEAR_PLANE) / frustumLength) * -1.0;
projectionMatrix[11] = -1.0;
projectionMatrix[14] = ((2.0 * NEAR_PLANE * FAR_PLANE) / frustumLength) * -1;
projectionMatrix[15] = 0;

gl.uniformMatrix4fv(gl.getUniformLocation(program, "u_Projection"), false, projectionMatrix)

const loop = () => {
    gl.clearColor(0.0, 0.0, 0.0, 0.8);
    gl.clear(gl.DEPTH_BUFFER_BIT | gl.COLOR_BUFFER_BIT);

    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.drawArrays(gl.TRIANGLES, 0, 3);

    requestAnimationFrame(loop);
}

loop();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        html, body {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
</head>
<body>
    <script id="vs" type="x-shader/x-vertex">#version 300 es
        precision highp float;
        precision highp int;

        layout(location=0) in vec3 a_Position;

        out vec4 v_Position;

        uniform mat4 u_Projection;

        void main()
        {
            gl_Position = u_Projection * vec4(a_Position, 1.0);
            v_Position = gl_Position;
        }
    </script>

    <script id="fs" type="x-shader/x-fragment">#version 300 es
        precision highp float;
        precision highp int;

        in vec4 v_Position;

        out vec4 out_Color;

        void main()
        {
            out_Color = v_Position;
        }
    </script>
    <canvas id="viewport"></canvas>
    <script src="main.js"></script>
</body>
</html>

我也试过this解决方案,但是id也没用。

你试过把三角形往后移一点吗?根据您的 NEAR_PLAIN,三角形太近了。尝试:

    const position = [
        -0.5, -0.5, -1.0,
         0.0,  0.5, -1.0,
         0.5, -0.5, -1.0,
    ];

顺便说一句,我不确定我是否同意您用来创建投影矩阵的数学。我认为值得与 https://glmatrix.net/docs/mat4.js.html#line1508 进行比较,我认为后者会给出不同的结果。