官方文档:https://docs.unity3d.com/cn/current/Manual/SL-PlatformDifferences.html
作用:把不同平台下的裁剪空间下的z值映射到[0, 1]的范围
用法:
float clipSpaceRange01 = UNITY_Z_0_FAR_FROM_CLIPSPACE(rawClipSpace);
源码:
#if defined(UNITY_REVERSED_Z)
#if UNITY_REVERSED_Z == 1
// D3d下当UNITY_REVERSED_Z的时候,裁剪空间的z范围是[near, 0],即越靠近近裁切面,z值越接近near,越靠近远裁切面,z值越靠近0,在这里映射到[0, 1]
//UNITY_REVERSED_Z解析:https://blog.csdn.net/acmhonor/article/details/106167261
// _ProjectionParams.y是near, _ProjectionParams.z是far
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(((1.0-(coord)/_ProjectionParams.y)*_ProjectionParams.z),0)
#else
//GL with reversed z => z clip range is [near, -far] -> should remap in theory but dont do it in practice to save some perf (range is close enough)
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) max(-(coord), 0)
#endif
#elif UNITY_UV_STARTS_AT_TOP
//D3d without reversed z => z clip range is [0, far] -> nothing to do
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
#else
//Opengl => z clip range is [-near, far] -> should remap in theory but dont do it in practice to save some perf (range is close enough)
#define UNITY_Z_0_FAR_FROM_CLIPSPACE(coord) (coord)
#endif
着色器中的深度 (Z) 方向
深度 (Z) 方向在不同的着色器平台上不同。
DirectX 11、DirectX 12、PS4、Xbox One、Metal:反转方向
-
深度 (Z) 缓冲区在近平面处为 1.0,在远平面处减小到 0.0。
-
裁剪空间范围是 [near,0](表示近平面处的值是near,在远平面处减小到 0.0)。
其他平台:传统方向
-
深度 (Z) 缓冲区值在近平面处为 0.0,在远平面处为 1.0。
- 裁剪空间取决于具体平台:
- 在 Direct3D 类平台上,范围是 [0,far](表示在近平面处为 0.0,在远平面处数值增加到far)。
- 在 OpenGL 类平台上,范围是 [-near,far](表示在近平面处为负的near,在远平面处增加到far)。
请注意,使反转方向深度 (Z) 与浮点深度缓冲区相结合,可显著提高相对于传统方向的深度缓冲区精度。这样做的优点是降低 Z 坐标的冲突并改善阴影,特别是在使用小的近平面和大的远平面时。
因此,在使用深度 (Z) 发生反转的平台上的着色器时:
- 定义了 UNITY_REVERSED_Z。
_CameraDepth
纹理的纹理范围是 1(近平面)到 0(远平面)。- 裁剪空间范围是“near”(近平面)到 0(远平面)。
但是,以下宏和函数会自动计算出深度 (Z) 方向的任何差异:
Linear01Depth(float z)
LinearEyeDepth(float z)
- UNITY_CALC_FOG_FACTOR(coord)