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 进行比较,我认为后者会给出不同的结果。
正在尝试编写基本的 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 进行比较,我认为后者会给出不同的结果。