Unity中UnityObjectToClipPos返回Z深度值异常,如何在顶点着色器模拟SV_Position的深度计算效果?
解决Unity顶点着色器中深度计算的异常问题
你遇到的问题其实是透视插值的特性和Unity裁剪空间/深度缓冲区的规则共同导致的,咱们一步步拆解并解决:
为什么原来的方法不对?
- 裁剪空间z的范围:Unity的
UnityObjectToClipPos返回的裁剪空间坐标,其z值范围是[-w, w](非反向Z)或[0, w](反向Z,Unity默认开启)。直接做clipPos.z / clipPos.w得到的NDC z值,在反向Z下是[0, 1],非反向Z是[-1, 1]——但你在顶点着色器计算这个值后再插值,会出问题! - 透视插值的非线性:GPU的插值是基于
1/w的透视校正插值,如果你在顶点计算z/w再插值,得到的结果和在片段着色器里对SV_Position做z/w的结果完全不一样,这就是你看到深度不单调、出现负值的核心原因。
正确的实现思路
要在顶点着色器计算可正确插值的深度,应该先获取视图空间的线性深度,然后在片段着色器里把这个线性深度转换成深度缓冲区的0-1值。这样插值的是线性的视图空间z,片段里的转换会保证结果和SV_Position计算的一致。
修改后的完整代码
Tags { "RenderType"="Opaque" } LOD 200 Cull off CGPROGRAM #pragma target 3.0 #pragma surface surf StandardSpecular alphatest:_Cutoff addshadow vertex:vert #pragma debug struct Input { float viewZ; // 传递视图空间的z值 }; void vert(inout appdata_full v, out Input o) { UNITY_INITIALIZE_OUTPUT(Input, o); // 获取视图空间位置,Unity中视图空间z为负值(相机看向-z方向) float3 viewPos = UnityObjectToViewPos(v.vertex); o.viewZ = viewPos.z; } void surf(Input IN, inout SurfaceOutputStandardSpecular o) { // 将视图空间z转换为深度缓冲区的0-1值 float depth; // _ProjectionParams.y是近裁剪面距离,_ProjectionParams.z是远裁剪面距离 #if defined(UNITY_REVERSED_Z) // 反向Z:深度缓冲区0=远,1=近 depth = (IN.viewZ + _ProjectionParams.z) / (_ProjectionParams.z - _ProjectionParams.y); #else // 非反向Z:深度缓冲区0=近,1=远 depth = (IN.viewZ + _ProjectionParams.z) / (_ProjectionParams.z - _ProjectionParams.y); depth = depth * 0.5 + 0.5; #endif // clamp确保值在0-1之间,赋值给Albedo的R通道可视化 o.Albedo.x = clamp(depth, 0.0, 1.0); o.Alpha = 1; } ENDCG
关键细节解释
- 视图空间z的意义:
UnityObjectToViewPos返回的视图空间位置,其z值是从相机位置到顶点的深度(Unity中相机看向-z方向,所以近裁剪面的z值是-_ProjectionParams.y,远裁剪面是-_ProjectionParams.z)。这个值是线性的,插值后不会出现透视校正的偏差。 - 深度转换公式:
- 反向Z模式(Unity默认):
(viewZ + far) / (far - near),转换后近裁剪面对应1,远裁剪面对应0。 - 非反向Z模式:先做线性转换到
[-1,1],再偏移到[0,1]。
- 反向Z模式(Unity默认):
- 插值效果:因为我们传递的是线性的视图空间z,GPU的透视校正插值会正确处理它,最终在片段着色器转换后的深度和直接用
SV_Position计算的结果完全一致,同时你也可以在顶点着色器里基于viewZ做任何自定义计算(比如调整、偏移等)。
验证结果
现在你会看到球体的深度着色和用SV_Position计算的效果完全一致:靠近相机的部分是白色(深度1),远离的部分是黑色(深度0,反向Z下),而且深度值是单调变化的,不会出现负值或异常恒定的情况。
内容的提问来源于stack exchange,提问作者IS4
相关产品推荐
相关产品推荐

