javascript - WebGL透视投影矩阵不起作用
问题描述
尝试编写基本的 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>
我也尝试过这个解决方案,但 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进行比较,我相信它会给出不同的结果。
推荐阅读
- go - 如何为多个环境和突变的组合生成配置
- python - Django 在 Django 模板中访问列表元素的属性
- android - 在 Flutter 中使用 android 10 活动缩放过渡
- microsoft-graph-api - 对于我的 Teams 应用在 App Studio 中收到的权限,我应该使用什么 API?
- java - 如何防止自定义视图覆盖自身?
- linux - 从命令行执行 Java Mission Control
- python - 我是 python 新手,我自己尝试将其作为个人项目。AttributeError:“NoneType”对象没有属性“get”
- python - 即使在 `try ... except` 中,asyncio.wait 也会返回异常
- xamarin - 如何在我的 xamarin 表单项目中使用 sqlite-net-pcl 设置外键
- opencv - 从 haarcascade 正面训练