WebGL 和 glMatrix 最小示例,带有 lookAt 和透视转换
WebGL and glMatrix minimal example with lookAt and perspective transformations
我是 3d 图形的新手,我正在尝试弄清楚如何使用 glMatrix 数学库中的 lookAt 和透视矩阵。
此时并不想做任何花哨的事情,但我相信我遗漏了一些东西,这是我的代码的相关部分:
var lookAtMatrix=mat4.create();
var perspectiveMatrix=mat4.create();
var uniformMatrix=mat4.create();
let eye=vec3.fromValues(0,0,1);
let center=vec3.fromValues(0,0,0);
let up=vec3.fromValues(0,1,0);
mat4.lookAt(lookAtMatrix,eye,center,up);
mat4.perspective(perspectiveMatrix,.4*Math.PI,1,-1,10);
mat4.multiply(uniformMatrix,lookAtMatrix,uniformMatrix);
mat4.multiply(uniformMatrix,perspectiveMatrix,uniformMatrix);
gl.uniformMatrix4fv(matrixLocation,false,uniformMatrix);
当我 运行 这样做时,我相信我应该得到一些东西来展示,但没有任何东西出现。我期待看到两个红色三角形(如果我不使用 lookAt 和透视矩阵,我可以看到它们)。我确定我遗漏了一些简单的东西,因此我们将不胜感激。我在下面附上了完整的代码片段,这里是 fiddle:
https://jsfiddle.net/mh9q7ouw/1/
const vertexSource = `
attribute vec4 a_position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix*a_position;
}`;
const fragmentSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(255,0,0,1);
}`;
function load() {
var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl");
if(!gl){return;}
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader,vertexSource);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader,fragmentSource);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
matrixLocation=gl.getUniformLocation(program,"u_matrix");
positionLocation=gl.getAttribLocation(program,"a_position");
positionBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(
[0,0,0, .5,.5,0, .5,0,0,
0,.1,0, .5,.6,0, 0,.6,-1]
),gl.STATIC_DRAW);
let bufferLength=6;
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.enable(gl.CULL_FACE);
// gl.cullFace(gl.BACK);
gl.enable(gl.BLEND);
gl.blendEquation( gl.FUNC_ADD );
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.useProgram(program);
var lookAtMatrix=mat4.create();
var perspectiveMatrix=mat4.create();
var uniformMatrix=mat4.create();
let eye=vec3.fromValues(0,0,1);
let center=vec3.fromValues(0,0,0);
let up=vec3.fromValues(0,1,0);
mat4.lookAt(lookAtMatrix,eye,center,up);
mat4.perspective(perspectiveMatrix,.4*Math.PI,1,-1,10);
mat4.multiply(uniformMatrix,lookAtMatrix,uniformMatrix);
mat4.multiply(uniformMatrix,perspectiveMatrix,uniformMatrix);
gl.uniformMatrix4fv(matrixLocation,false,uniformMatrix);
gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);
gl.vertexAttribPointer(positionLocation,3,gl.FLOAT,false,0,0);
gl.drawArrays(gl.TRIANGLES,0,bufferLength);
}
load();
body {
margin: 0;
background-color: wheat;
}
#html{
background-color: wheat;
}
canvas {
margin: 0;
position: absolute;
width: 90vw;
height: 90vh;
left: 5vw;
top: 5vh;
display: block;
background-color: rgba(0,0,0,.1);
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="animation.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="animation.js"></script>
</body>
</html>
看起来我以负值开始视锥体(在相机后面 -1),当我改为 .001 时它似乎起作用了。
更正后的代码如下所示:
var lookAtMatrix=mat4.create();
var perspectiveMatrix=mat4.create();
var uniformMatrix=mat4.create();
let eye=vec3.fromValues(0,0,1);
let center=vec3.fromValues(0,0,0);
let up=vec3.fromValues(0,1,0);
mat4.lookAt(lookAtMatrix,eye,center,up);
mat4.perspective(perspectiveMatrix,.6*Math.PI,1,.001,10);
mat4.multiply(uniformMatrix,lookAtMatrix,uniformMatrix);
mat4.multiply(uniformMatrix,perspectiveMatrix,uniformMatrix);
gl.uniformMatrix4fv(matrixLocation,false,uniformMatrix);
我是 3d 图形的新手,我正在尝试弄清楚如何使用 glMatrix 数学库中的 lookAt 和透视矩阵。
此时并不想做任何花哨的事情,但我相信我遗漏了一些东西,这是我的代码的相关部分:
var lookAtMatrix=mat4.create();
var perspectiveMatrix=mat4.create();
var uniformMatrix=mat4.create();
let eye=vec3.fromValues(0,0,1);
let center=vec3.fromValues(0,0,0);
let up=vec3.fromValues(0,1,0);
mat4.lookAt(lookAtMatrix,eye,center,up);
mat4.perspective(perspectiveMatrix,.4*Math.PI,1,-1,10);
mat4.multiply(uniformMatrix,lookAtMatrix,uniformMatrix);
mat4.multiply(uniformMatrix,perspectiveMatrix,uniformMatrix);
gl.uniformMatrix4fv(matrixLocation,false,uniformMatrix);
当我 运行 这样做时,我相信我应该得到一些东西来展示,但没有任何东西出现。我期待看到两个红色三角形(如果我不使用 lookAt 和透视矩阵,我可以看到它们)。我确定我遗漏了一些简单的东西,因此我们将不胜感激。我在下面附上了完整的代码片段,这里是 fiddle:
https://jsfiddle.net/mh9q7ouw/1/
const vertexSource = `
attribute vec4 a_position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix*a_position;
}`;
const fragmentSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(255,0,0,1);
}`;
function load() {
var canvas = document.querySelector("#canvas");
var gl = canvas.getContext("webgl");
if(!gl){return;}
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader,vertexSource);
gl.compileShader(vertexShader);
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader,fragmentSource);
gl.compileShader(fragmentShader);
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
matrixLocation=gl.getUniformLocation(program,"u_matrix");
positionLocation=gl.getAttribLocation(program,"a_position");
positionBuffer=gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(
[0,0,0, .5,.5,0, .5,0,0,
0,.1,0, .5,.6,0, 0,.6,-1]
),gl.STATIC_DRAW);
let bufferLength=6;
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.enable(gl.CULL_FACE);
// gl.cullFace(gl.BACK);
gl.enable(gl.BLEND);
gl.blendEquation( gl.FUNC_ADD );
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.useProgram(program);
var lookAtMatrix=mat4.create();
var perspectiveMatrix=mat4.create();
var uniformMatrix=mat4.create();
let eye=vec3.fromValues(0,0,1);
let center=vec3.fromValues(0,0,0);
let up=vec3.fromValues(0,1,0);
mat4.lookAt(lookAtMatrix,eye,center,up);
mat4.perspective(perspectiveMatrix,.4*Math.PI,1,-1,10);
mat4.multiply(uniformMatrix,lookAtMatrix,uniformMatrix);
mat4.multiply(uniformMatrix,perspectiveMatrix,uniformMatrix);
gl.uniformMatrix4fv(matrixLocation,false,uniformMatrix);
gl.enableVertexAttribArray(positionLocation);
gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);
gl.vertexAttribPointer(positionLocation,3,gl.FLOAT,false,0,0);
gl.drawArrays(gl.TRIANGLES,0,bufferLength);
}
load();
body {
margin: 0;
background-color: wheat;
}
#html{
background-color: wheat;
}
canvas {
margin: 0;
position: absolute;
width: 90vw;
height: 90vh;
left: 5vw;
top: 5vh;
display: block;
background-color: rgba(0,0,0,.1);
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="animation.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="animation.js"></script>
</body>
</html>
看起来我以负值开始视锥体(在相机后面 -1),当我改为 .001 时它似乎起作用了。
更正后的代码如下所示:
var lookAtMatrix=mat4.create();
var perspectiveMatrix=mat4.create();
var uniformMatrix=mat4.create();
let eye=vec3.fromValues(0,0,1);
let center=vec3.fromValues(0,0,0);
let up=vec3.fromValues(0,1,0);
mat4.lookAt(lookAtMatrix,eye,center,up);
mat4.perspective(perspectiveMatrix,.6*Math.PI,1,.001,10);
mat4.multiply(uniformMatrix,lookAtMatrix,uniformMatrix);
mat4.multiply(uniformMatrix,perspectiveMatrix,uniformMatrix);
gl.uniformMatrix4fv(matrixLocation,false,uniformMatrix);