1.将webgl的可视空间设置为透视投影矩阵
2.什么是透视投影矩阵
它能实现一种效果,近大远小的效果。因为我们用人眼去观察世界的效果,也是近大远小。
使用cuon-matrix.js来创建一个透视投影矩阵。
const projMatrix = new Matrix4(); // 创建一个4*4的矩阵
projMatrix.setPerspective(30, canvas.width / canvas.height, 1, 1000); // 设置矩阵为透视投影矩阵
- 垂直视角,及可视空间顶面 和 底面之间的夹角。
- 指定近近裁剪面的宽高比(宽/高)。
- 近视点, 一般是视点。
- 远视点, 就是表示能看多远。
实例代码
- 顶点着色器声明 u_ProjMaterix
uniform mat4 u_ProjMaterix
- 获取 u_ProjMaterix变量存储地址,内存地址
const u_ProjMaterix = gl.getUniformLocation(gl.program, 'u_ProjMaterix');
- 创建一个透视投影矩阵
const projMatrix = new Matrix4();
projMatrix.setPerspective(30, canvas.width / canvas.height, 1, 1000);
- 写入
gl.uniformMatrix4fv(u_ProjMaterix, false, projMatrix.elements);
就ok了
具体代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#canvas {
height: 400px;
width: 400px;
background-color: black;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="../lib/cuon-matrix.js"></script>
<script>
const gl = canvas.getContext('webgl');
const VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute vec4 a_Color;\n' +
'varying vec4 c_Color;\n' +
'uniform mat4 u_ProjMaterix;\n' +
'uniform mat4 u_ViewMaterix;\n' +
'void main(){\n' +
' gl_Position = u_ProjMaterix * u_ViewMaterix * a_Position;\n' +
' c_Color = a_Color;\n' +
'}\n';
const FSHADER_SOURCE =
'#ifdef GL_ES\n' +
'precision mediump float;\n' +
'#endif\n' +
'varying vec4 c_Color;\n' +
'void main(){\n' +
' gl_FragColor = c_Color;\n' +
'}\n';
const createShader = (type, source) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
const info = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!info) {
const err = gl.getShaderInfoLog(shader);
console.log(`编译报错信息为:${err}`);
gl.deleteShader(shader);
return null;
}
return shader;
}
// const shader = createShader(gl.FRAGMENT_SHADER, FSHADER_SOURCE);
// console.log(shader)
const createProgram = (vshader, fshader) => {
const vertexShader = createShader(gl.VERTEX_SHADER, vshader);
const fragmentShader = createShader(gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
console.log('创建着色器失败');
}
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const linkState = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linkState) {
const err = gl.getProgramInfoLog(program);
console.log('链接报错信息为' + err);
gl.deleteShader(vertexShader);
gl.deleteShader(fragmentShader);
gl.deleteProgram(program);
return null
}
return program;
}
const program = createProgram(VSHADER_SOURCE, FSHADER_SOURCE);
gl.useProgram(program);
gl.program = program;
const initBuffers = () => {
var verticesColors = new Float32Array([
// Three triangles on the right side
0.75, 1.0, -4.0, 0.4, 1.0, 0.4, // The back green one
0.25, -1.0, -4.0, 0.4, 1.0, 0.4,
1.25, -1.0, -4.0, 1.0, 0.4, 0.4,
0.75, 1.0, -2.0, 1.0, 1.0, 0.4, // The middle yellow one
0.25, -1.0, -2.0, 1.0, 1.0, 0.4,
1.25, -1.0, -2.0, 1.0, 0.4, 0.4,
0.75, 1.0, 0.0, 0.4, 0.4, 1.0, // The front blue one
0.25, -1.0, 0.0, 0.4, 0.4, 1.0,
1.25, -1.0, 0.0, 1.0, 0.4, 0.4,
// Three triangles on the left side
-0.75, 1.0, -4.0, 0.4, 1.0, 0.4, // The back green one
-1.25, -1.0, -4.0, 0.4, 1.0, 0.4,
-0.25, -1.0, -4.0, 1.0, 0.4, 0.4,
-0.75, 1.0, -2.0, 1.0, 1.0, 0.4, // The middle yellow one
-1.25, -1.0, -2.0, 1.0, 1.0, 0.4,
-0.25, -1.0, -2.0, 1.0, 0.4, 0.4,
-0.75, 1.0, 0.0, 0.4, 0.4, 1.0, // The front blue one
-1.25, -1.0, 0.0, 0.4, 0.4, 1.0,
-0.25, -1.0, 0.0, 1.0, 0.4, 0.4,
]);
const size = verticesColors.BYTES_PER_ELEMENT;
const bufferData = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, bufferData);
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, size * 6, 0);
gl.enableVertexAttribArray(a_Position);
const a_Color = gl.getAttribLocation(gl.program, 'a_Color');
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, size * 6, size * 3);
gl.enableVertexAttribArray(a_Color);
const projMatrix = new Matrix4();
projMatrix.setPerspective(30, canvas.width / canvas.height, 1, 1000);
const u_ProjMaterix = gl.getUniformLocation(gl.program, 'u_ProjMaterix');
gl.uniformMatrix4fv(u_ProjMaterix, false, projMatrix.elements);
const u_ViewMaterix = gl.getUniformLocation(gl.program, 'u_ViewMaterix');
const viewMatrix = new Matrix4();
viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);
gl.uniformMatrix4fv(u_ViewMaterix, false, viewMatrix.elements);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIF);
gl.drawArrays(gl.TRIANGLES, 0, 18);
}
initBuffers();
</script>
</body>
</html>
效果图