1.webgl图形变换
(1)2D 旋转
//计算2D旋转矩阵
function createRotateMatrix(angle=0.0) {
var radian = degToRad(angle);
var cosB = Math.cos(radian),
sinB = Math.sin(radian);
return flatArr([
[cosB, sinB, 0.0, 0.0],
[-sinB, cosB, 0.0, 0.0],
[0.0, 0.0, 1.0, 0.0],
[0.0, 0.0, 0.0, 1.0]
]);
}
(2)3D旋转
var settings = {
x: 1,
y: 1,
z: 1
};
var modelViewMatrix = mat4.create();
mat4.rotateX(modelViewMatrix, modelViewMatrix, settings.x);
mat4.rotateY(modelViewMatrix, modelViewMatrix, settings.y);
mat4.rotateZ(modelViewMatrix, modelViewMatrix, settings.z);
(3)缩放
function createScaleMatrix(sx=1.0, sy=1.0,sz=1.0) {
return flatArr([
[sx, 0, 0.0, 0.0],
[0, sy, 0.0, 0.0],
[0.0, 0.0, sz, 0.0],
[0.0, 0.0, 0.0, 1.0]
]);
}
//同理
var modelViewMatrix = mat4.create();
mat4.scale(modelViewMatrix, modelViewMatrix, [settings.scaleX, settings.scaleY, settings.scaleZ]);
(4)平移
- 顶点着色器
//vec3 aMovePos;平移的位置
vec3 pos=aPosition+aMovePos;
gl_Position =vec4(pos,1.0);
- 平移矩阵
var modelViewMatrix = mat4.create();
mat4.translate(modelViewMatrix, modelViewMatrix, [settings.x, settings.y, settings.z]);
2.wegl投影与摄像机
(1)正交投影:一个前后左右上下四个面形成的长方体空间,物体在里面才能显示,超过就不显示,不添加投影矩阵的情况下,默认是[-1.0,1.0]的立方体
function orthographic(left, right, bottom, top, near, far) {
return flatArr([
[2 / (right - left), 0, 0, 0],
[0, 2 / (top - bottom), 0, 0],
[0, 0, 2 / (near - far), 0],
[(left + right) / (left - right),
(bottom + top) / (bottom - top),
(near + far) / (near - far),
1],
]);
}
var depth = Math.max(gl.canvas.width, gl.canvas.height);
var left = -gl.canvas.width * 0.01;
var right = gl.canvas.width * 0.01;
var bottom = gl.canvas.height * 0.01;
var top = -gl.canvas.height * 0.01;
var near = depth * 0.1;
var far = -depth * 0.1;
var projectionMatrix = new Float32Array(orthographic(left, right, bottom, top, near, far));
注意:空间越大,物体就会显得越小,甚至看不到,空间设置要适当
glMatrix正交投影
var projectionMatrix = mat4.create();
mat4.ortho(projectionMatrix, left, right, bottom, top, near, far);
(2)透视投影:类似小孔成像,从一个点触发,放射出四棱锥,近点和远点分别切一个面,截取的这个范围内,物体就可以看到,其他就不能看见
function perspective(fieldOfViewInRadians, aspect, near, far) {
var f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewInRadians);
var rangeInv = 1.0 / (near - far);
return flatArr([
[f / aspect, 0, 0, 0],
[0, f, 0, 0],
[0, 0, (near + far) * rangeInv, -1],
[0, 0, near * far * rangeInv * 2, 0]
]);
}
- glMatrix透视投影
var projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, fieldOfView, aspect, zNear, zFar);
(3)摄像机:一句话就是你的眼睛,你的眼睛等同于一个透视投影,眼睛会移动位置,然后就会呈现不同的视图
var cameraMatrix = mat4.create();
//lookAt(out, eye, center, up)
mat4.lookAt(cameraMatrix, [settings.x, settings.y, settings.z], [0, 0, 0], [0, 1, 0]);
3.Github地址
https://github.com/xiaolidan00/my-webgl
4.需要使用到的库
- glMatrix 官方 API 文档:
https://glmatrix.net/docs/module-mat4.html
- dat.gui 官方 API 文档:
https://github.com/dataarts/dat.gui/blob/master/API.md
参考
https://webglfundamentals.org/
- 《WebGL编程指南》
- 《webGL 3D开发实战详解 第2版》