Unity3D引擎之渲染技术
作者简介
姜雪伟,泰课在线高级讲师 海洋
从裁剪操作到投影至屏幕空间
经过投影矩阵的变换后,便进入裁剪操作阶段。当所有裁剪工作完成,就需要进行真正的投影,即将视锥体投影到屏幕空间。屏幕空间是二维空间,所以必须把顶点从裁剪空间投影到屏幕空间,生成对应的 2D 坐标,此过程需分两步完成。
标准齐次除法(透视除法)
首先要进行标准齐次除法,也称作透视除法,即使用齐次坐标系的 w 分量分别去除 x、y、z 分量。在 OpenGL 中,这一步得到的坐标被称为归一化的设备坐标(NDC),在之前的博客中已有相关介绍,不理解的读者可翻阅以前的博文。通过这一步,可将坐标从齐次裁剪坐标空间转换到 NDC 中。
经过透视投影变换后的裁剪空间,在进行齐次除法后会变换到一个立方体内。按照 OpenGL 的传统,这个立方体的 x、y、z 分量的范围均为[-1,1]。然而在 DirectX 中,z 的分量范围是[0,1]。Unity 采用了类似 OpenGL 的齐次裁剪空间,具体情况如图所示(此处原文未给出图,可后续补充)。
对于正交投影而言,其裁剪空间实际上已经是一个立方体。并且由于经过正交投影矩阵变换后的顶点 w 分量是 1,所以齐次除法不会对顶点的 x、y、z 坐标产生影响,具体情况如图所示(此处原文未给出图,可后续补充)。
经过齐次除法后,透视投影和正交投影的视锥体都会变换到一个相同的立方体内。此时,我们就可以依据变换后的 x 和 y 坐标来映射输出窗口的对应像素坐标。
屏幕映射
在 Unity 中,屏幕空间左下角的像素坐标是(0,0),右上角的像素坐标是(pixelWidth, pixelHeight)。由于当前的 x 和 y 坐标范围都是[-1,1],所以映射过程本质上是一个缩放过程。
齐次除法和屏幕映射的过程可以用以下公式表示(此处原文未给出公式,可后续补充)。
在 Unity 中,从裁剪空间到屏幕空间的转换由 Unity 完成,我们的顶点着色器只需把顶点转换到裁剪空间即可。在前面的步骤中,我们已知裁剪空间中模型孩子的位置为(11.691,15.311,23.692,27.31)。接下来确定模型的孩子节点在屏幕上的像素位置。假设当前屏幕的像素宽度为 400,高度为 300。首先进行齐次除法,将裁剪空间中的坐标投影到 NDC 中,然后再映射到屏幕空间,具体过程如下(此处原文未给出过程,可后续补充)。
经过计算,就可以得到模型的孩子节点在屏幕空间的像素位置为(285.617,234.096)。
总结
以上内容阐述了一个顶点从模型空间变换到屏幕空间的过程,以及它们之间的矩阵变换。顶点着色器的最基本任务是把顶点坐标从模型空间转换到裁剪空间。而在片元着色器中,通常能够获取该片元在屏幕空间的像素位置。
这里仅为读者介绍了一些最重要的坐标空间,在实际开发中还会遇到其他坐标空间,例如切线空间,它通常用于法线映射。最后,为读者展示 Unity 的各个坐标空间(此处原文未给出展示内容,可后续补充)。