目录

屏幕空间变换

屏幕空间变换

https://cdn.jsdelivr.net/gh/codingriver/cdn/texs/透视投影变换推导/20210424144836.png

屏幕坐标 (Screen Space)


通过投影变换后,坐标系变换到裁剪空间了,然后从裁剪空间变换到屏幕空间,这里分为两步完成:

  • 首先进行齐次除法(homegeneous division),也被称为透视除法(perspective division),这一步很简单,就是用齐次坐标系的w分量去除以x,y,z分量,在OpenGL中这一步得到的坐标也叫归一化的设备坐标(Normalized Device Coordinates,NDC)。经过这一步,从齐次裁剪坐标空间转换到NDC中。
  • 然后将NDC转换到屏幕空间。

在Unity中,屏幕空间左下角的像素坐标是(0,0),右上角的像素坐标是(pixelWidth,pixelHeight)。由于当前齐次坐标x和y都在[-1,1]范围内,因此映射过程就是一个缩放过程。

https://cdn.jsdelivr.net/gh/codingriver/cdn/texs/屏幕空间变换/20210423202316.png

z分量被用于深度缓冲,一个传统方式是把clipz/clipw的值直接存进深度缓冲中,但不是必须的。

视口坐标 (Viewport Space)


屏幕坐标系是左下角为原点,右上角为分辨率大小的坐标系,而视口坐标系是左下角为原点 (0,0),右上角是 (1,1)的坐标系。 我们将齐次除法和视口坐标映射的过程使用下面公式来完成:

https://cdn.jsdelivr.net/gh/codingriver/cdn/texs/屏幕空间变换/20210423203331.png

如果在定点着色器只是经过ComputeScreenPos(函数输入参数:经过MVP矩阵变换后在裁剪空间的顶点坐标)计算,实际输出的结果是:

https://cdn.jsdelivr.net/gh/codingriver/cdn/texs/屏幕空间变换/20210423203521.png

ComputeScreenPos在顶点着色器中没有做除以 clipw 的操作,需要在片元着色器进行除以 clipw 操作。

https://cdn.jsdelivr.net/gh/codingriver/cdn/texs/屏幕空间变换/20210423204322.png
https://cdn.jsdelivr.net/gh/codingriver/cdn/texs/屏幕空间变换/20210423204339.png

ComputeScreenPos 方法: https://cdn.jsdelivr.net/gh/codingriver/cdn/texs/屏幕空间变换/20210423204744.png