今天遇到一个奇怪的问题,屏幕后处理时使用_CameraDepthTexture还原世界坐标的时候出问题了,多番调试发现_CameraDepthTexture中保存的深度值 depth = 1 - Zn (Zn指NDC的z分量,即透视除法后的坐标z)(假设NDC坐标取[0, 1]),至于为什么要这样可以看看下面的文章
Reversed-Z详解-幽玄
Nvidia的关于Reverse-Z的文章
我的理解:
当相机是透视投影模式的时候Zn是非线性的,Zn和相机空间下Z轴的关系如下:
从图中可以看出,近裁剪平面的少数Z占用了[0, 1]区间中0附近大范围的值,然后Y轴改成1-Zn如下图
上面的图乍一看然并卵啊,不还是近裁剪平面的少数Z占用了[0, 1]区间中1附近大范围的值,其实非也,因为0值附近的符点数拥有更好的精度,为什么这么说呢,因为计算机保存浮点数有个特点,以float类型为例
0.000101011在计算机中会被保存为1.01011*2^-4,而1.000101011则还是1.000101011
所以上图 中看似近裁剪平面占用了1附近大范围的区间,但是0附近的区间精度是高于1附近的区间的,由此正好弥补了分布规律的缺陷。