3D矩阵变换
理论介绍
标准设备坐标
3D空间转换为2D图形的过程
模型变换
矩阵计算
齐次坐标
Vertex shader的裁剪空间又称为齐次空间
正交投影、透视投影
正视图、后视图
视锥
从前发散、从后发散
投影矩阵
显示一个完整的3D图形经过的步骤
-
以坐标为原点,建立整个图形的顶点坐标信息
-
利用矩阵变换,将一个图形在世界空间坐标中进行坐标变换
-
利用投影矩阵,用摄像机和视锥模拟不同视角
-
将裁剪空间进行统一的归一化处理,抛弃NDC空间之外的图形
-
把整个NDC空间通过内部的视图变换,得到二维平面结果
最后的两步是由GPU驱动自动完成,不需要开发者的参与。我们需要考虑的主要是(第三步)在Vertex Shader中返回裁剪空间的计算结果。前两步主要是在用户的逻辑代码中进行的。
注意:
-
世界空间的坐标系可以和裁剪空间不同。因为我们引入了摄像机和视锥的概念,所以可以自由安排视锥体对应的坐标系结构。可以将整个空间的方向和大小按照我们的需求自定义修改。不需要强行的规范坐标系的范围和坐标轴的方向。所以一般的场景中我们会使用一个独立的坐标系来构建整个世界。
-
具体的顶点数据的处理过程。不推荐改变原始顶点数据的方法变换图形(不高效:数据写入、管线切换)。推荐如果模型没有变化就不改变顶点坐标,再额外准备一个GPU的Buffer专门存储矩阵的数据。可以将需要变换的ModelView Matrix和Projection Matrix独立的相乘计算出结果,形成一个统一的ModelViewProjection矩阵,把它通过BindGroup作为全局参数传入到Vertex Shader中。然后可以在Vertex Shader中将顶点的坐标信息和MVP矩阵相乘得到最终的结果。好处是原始数据没有改变,可以复用一个模型的顶点数据。JS矩阵计算是用CPU,把矩阵放到Shader中利用GPU的并行计算效率会好很多。
Demo
http://github.com/Orillusion/orillusion-webgpu-samples
/src/rotatingCube.ts
注:在triangle.ts的基础上进行的教学
triangle.ts(实际上是cube.ts)
1个cube需要6个矩形面进行组合,1个矩形至少需要2个三角面进行组合,1个三角面如果不是strip模式或者用index来绘制,则需要3个独立的点来构成,1个cube至少需要36个点位信息。
const vertex = new Float32Array([
// float3 position, float2 uv
// face1
+1, -1, +1,
-1, -1, +1,
-1, -1, -1,
+1, -1, -1,
+1, -1, +1,
-1, -1, -1,
// face
+1, +1, +1,
+1, -1, +1,
+1, -1, -1,
+1, +1, -1,
+1, +1, +1,
+1, -1, -1,
// face
-1, +1, +1,
+1, +1, +1,
+1, +1, -1,
-1, +1, -1,
-1, +1, +1,
+1, +1, -1,
// face
-1, -1, +1,
-1, +1, +1,
-1, +1, -1,
-1, -1, -1,
-1, -1, +1,
-1, +1, -1,
// face
+1, +1, +1,
-1, +1, +1,
-1, -1, +1,
-1, -1, +1,
+1, -1, +1,
+1, +1, +1,