1.什么是视图矩阵?
视图矩阵: 简单理解就是观察者从哪里(位置)观察这个物体,有三个参数决定这个视图矩阵。
- 视点,就是用户的位置,观察者的位置。
- 观察目标,即被观察目标所在的位置。
- 上方向,因为视点,观察目标决定了视线。但是观察者在视点处的位置,会是绕着视线旋转一定的角度,观察到的目标也会不一样。
2.上方向的意义
我们改变观察物体的角度
1.要么是改变物体在三维场景中的位置
2.要么是改变观察者的位置
但是我们是改不了观察者的位置,所以我们就改变三维场景中的物体的位置。
顶点着色器代码
const VSHADHER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute vec4 a_Color;\n' +
'varying vec4 c_Color;\n' +
'uniform mat4 u_ViewMaterix;\n' +
'void main(){' +
' gl_Position = u_ViewMaterix * a_Position;\n' +
' c_Color = a_Color;\n' +
'}\n';
gl_Position = u_ViewMaterix * a_Position;
我们是将 a_Position顶点坐标,乘一个矩阵(u_ViewMaterix),得到的是一个变化的向量(矢量);
gl_Position = 视图矩阵 * 原始顶点坐标;
gl_Position = 视图矩阵 * 原始顶点坐标;
3.u_ViewMaterix
如何设置这个视图矩阵
1.使用cuon-matrix.js来生成这个视图矩阵。
2.将这个视图矩阵,传递给u_ViewMaterix。就行了
var viewMatrix = new Matrix4(); // 初始化一个4*4矩阵
viewMatrix.setLookAt(0.20, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) // 设置视图矩阵
const u_ViewMaterix = gl.getUniformLocation(gl.program, 'u_ViewMaterix'); // 获取u_ViewMaterix变量的内存地址
gl.uniformMatrix4fv(u_ViewMaterix, false, viewMatrix.elements); // 传递数据
4.实例代码
<!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;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="../lib/cuon-matrix.js"></script>
<script>
const gl = canvas.getContext('webgl')
// console.log(gl, 'gl')
const VSHADHER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute vec4 a_Color;\n' +
'varying vec4 c_Color;\n' +
'uniform mat4 u_ViewMaterix;\n' +
'void main(){' +
' gl_Position = 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';
// var FSHADER_SOURCE =
// '#ifdef GL_ES\n' +
// 'precision mediump float;\n' +
// '#endif\n' +
// 'varying vec4 v_Color;\n' +
// 'void main() {\n' +
// ' gl_FragColor = v_Color;\n' +
// '}\n';
const createShader = (type, souce) => {
const shader = gl.createShader(type);
gl.shaderSource(shader, souce);
gl.compileShader(shader);
const info = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!info) {
const err = gl.getShaderInfoLog(shader);
// alert(err === '');
gl.deleteShader(shader)
console.log('编译报错信息为' + err);
return null;
}
return shader;
}
// console.log(createShader(gl.VERTEX_SHADER, VSHADHER_SOURCE))
// console.log(createShader(gl.FRAGMENT_SHADER, FSHADER_SOURCE));
const createProgram = (vshader, fshader) => {
const vertexshader = createShader(gl.VERTEX_SHADER, vshader); //创建顶点着色器
const fragmentShader = createShader(gl.FRAGMENT_SHADER, fshader); // 创建片着色器
if (!vertexshader || !fragmentShader) {
console.log('创建着色器失败');
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexshader);
return null;
}
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(fragmentShader)
gl.deleteShader(vertexshader)
gl.deleteProgram(program);
return null
}
return program;
}
const program = createProgram(VSHADHER_SOURCE, FSHADER_SOURCE)
// console.log(program, 'program')
gl.useProgram(program)
gl.program = program;
var viewMatrix = new Matrix4();
viewMatrix.setLookAt(0.20, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
const u_ViewMaterix = gl.getUniformLocation(gl.program, 'u_ViewMaterix');
console.log(u_ViewMaterix, 'u_ViewMaterix')
gl.uniformMatrix4fv(u_ViewMaterix, false, viewMatrix.elements);
const initBuffers = () => {
var verticesColors = new Float32Array([
// Vertex coordinates and color(RGBA)
0.0, 0.5, -0.4, 0.4, 1.0, 0.4, // The back green one
-0.5, -0.5, -0.4, 0.4, 1.0, 0.4,
0.5, -0.5, -0.4, 1.0, 0.4, 0.4,
0.5, 0.4, -0.2, 1.0, 0.4, 0.4, // The middle yellow one
-0.5, 0.4, -0.2, 1.0, 1.0, 0.4,
0.0, -0.6, -0.2, 1.0, 1.0, 0.4,
0.0, 0.5, 0.0, 0.4, 0.4, 1.0, // The front blue one
-0.5, -0.5, 0.0, 0.4, 0.4, 1.0,
0.5, -0.5, 0.0, 1.0, 0.4, 0.4,
]);
const size = verticesColors.BYTES_PER_ELEMENT;
const n = 9;
const vertexColorbuffer = gl.createBuffer();
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
console.log(a_Position, 'a_Position')
const a_Color = gl.getAttribLocation(gl.program, 'a_Color');
console.log(a_Color, 'a_Color')
gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, size * 6, 0);
gl.enableVertexAttribArray(a_Position);
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, size * 6, size * 3)
gl.enableVertexAttribArray(a_Color);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, n)
}
initBuffers();
</script>
</body>
</html>
效果图