Trying to write basic WebGL program, which draws a triangle to the screen. Without any projection matrix it works just right, as well as with identity matrix. But when it comes to perspective projection matrix it just shows nothing. Here is my code:
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>
I have also tried this solution, but id didn`t work either.