找回密码
 立即注册
首页 业界区 业界 【URP】什么是[深度偏移](Slope Scale Depth Bias)‌ ...

【URP】什么是[深度偏移](Slope Scale Depth Bias)‌

城徉汗 昨天 09:31
【从UnityURP开始探索游戏渲染】专栏-直达
深度偏移(Slope Scale Depth Bias)‌的作用


  • 几何体表面因浮点精度限制导致的深度冲突(Z-fighting)

    • 解决 Z-fighting 问题,调整片元深度值。

  • 阴影贴图中的深度精度问题
  • 透明物体渲染时的深度排序问题
  • 细小几何体(如电线、毛发)的渲染稳定性
深度冲突(Z-fighting)


  • 是当两个或多个几何表面在深度缓冲中具有极其接近的深度值时,GPU 无法可靠判断渲染顺序导致的视觉瑕疵,表现为表面像素闪烁或随机交替显示‌。这是由于透视投影下非线性深度分布及有限的深度缓冲精度(通常 24 位)所致,尤其远距离平面精度更差‌
  • 深度偏移(Slope Scale Depth Bias)是图形渲染中用于解决深度冲突(Z-fighting)问题的重要技术。在Unity URP中,它通过调整像素的深度值来避免几何体表面之间的深度测试冲突.
‌深度偏移(Slope Scale Depth Bias)解决原理

通过动态调整顶点深度值,人为制造深度间隙避免冲突。其核心参数组合为:
Units


  • 固定深度偏移量(常量),对所有表面施加相同偏移
Factor


  • 基于表面斜率的动态偏移量(变量),计算公式为:

    • 动态偏移量 = Factor × max(|∂z/∂x|, |∂z/∂y|)
    • 倾斜表面(如斜坡、墙壁)斜率大,自动获得更大偏移
    • 平坦表面偏移较小,避免过度分离‌

  • 最终深度修正公式:
    最终深度值 = 原始深度值 + (Units × 最小深度单位) + (动态偏移量)
  • ZFightingFix.shader
    1. Shader "URP/ZFightingFix" {
    2.     Properties {
    3.         _MainTex ("Texture", 2D) = "white" {}
    4.         _Units ("Units", Float) = 0     // 固定偏移
    5.         _Factor ("Slope Factor", Float) = 0 // 坡度系数
    6.     }
    7.     SubShader {
    8.         Tags { "RenderPipeline"="UniversalPipeline" }
    9.         Pass {
    10.             HLSLPROGRAM
    11.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    12.             
    13.             struct Attributes {
    14.                 float4 positionOS : POSITION;
    15.                 float3 normalOS : NORMAL;
    16.             };
    17.             struct Varyings {
    18.                 float4 positionCS : SV_POSITION;
    19.             };
    20.             
    21.             float _Units, _Factor;
    22.             Varyings vert(Attributes v) {
    23.                 Varyings o;
    24.                 // 转换到裁剪空间
    25.                 o.positionCS = TransformObjectToHClip(v.positionOS.xyz);
    26.                
    27.                 // 计算表面斜率(视图空间法线Z分量)
    28.                 float3 normalVS = normalize(TransformWorldToViewDir(
    29.                     TransformObjectToWorldNormal(v.normalOS)
    30.                 ));
    31.                 float slope = abs(normalVS.z); // Z越小表面越陡峭
    32.                
    33.                 // 应用深度偏移
    34.                 float bias = _Units * 0.0001 + _Factor * (1 - slope);
    35.                 o.positionCS.z -= bias * o.positionCS.w; // 按w缩放适配透视
    36.                 return o;
    37.             }
    38.             // ... 片元着色器省略
    39.             ENDHLSL
    40.         }
    41.     }
    42. }
    复制代码
具体使用方法

关键参数说明


  • _DepthBias: 固定深度偏移量,正值使物体看起来更近
  • _SlopeScale: 基于表面斜率的动态偏移量,解决陡峭表面的深度冲突
  • output.positionCS.z += ...: 在裁剪空间直接修改深度值
  • slope计算: 基于法线向量计算表面斜率
参数建议


  • 对于阴影渲染,建议使用较小的_DepthBias值(0.001-0.01)
  • 对于复杂地形,可增加_SlopeScale值(0.1-1.0)
  • 在URP管线下,也可通过Renderer组件的ShadowCastingMode设置全局深度偏移
  • 法线贴图会影响实际斜率计算,需在切线空间正确转换法线向量
  • DepthBiasExample.shader
    1. Shader "Custom/DepthBiasExample"
    2. {
    3.     Properties
    4.     {
    5.         _MainTex ("Texture", 2D) = "white" {}
    6.         _DepthBias ("Depth Bias", Float) = 0
    7.         _SlopeScale ("Slope Scale", Float) = 0
    8.     }
    9.    
    10.     SubShader
    11.     {
    12.         Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
    13.         
    14.         Pass
    15.         {
    16.             HLSLPROGRAM
    17.             #pragma vertex vert
    18.             #pragma fragment frag
    19.             
    20.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    21.             
    22.             struct Attributes
    23.             {
    24.                 float4 positionOS : POSITION;
    25.                 float2 uv : TEXCOORD0;
    26.             };
    27.             
    28.             struct Varyings
    29.             {
    30.                 float4 positionCS : SV_POSITION;
    31.                 float2 uv : TEXCOORD0;
    32.             };
    33.             
    34.             CBUFFER_START(UnityPerMaterial)
    35.             float _DepthBias;
    36.             float _SlopeScale;
    37.             CBUFFER_END
    38.             
    39.             TEXTURE2D(_MainTex);
    40.             SAMPLER(sampler_MainTex);
    41.             
    42.             Varyings vert(Attributes input)
    43.             {
    44.                 Varyings output;
    45.                 output.positionCS = TransformObjectToHClip(input.positionOS.xyz);
    46.                
    47.                 // 应用深度偏移
    48.                 output.positionCS.z += _DepthBias * output.positionCS.w;
    49.                
    50.                 // 基于斜率应用额外偏移
    51.                 float3 normalVS = TransformWorldToViewDir(float3(0,1,0)); // 示例法线
    52.                 float slope = 1.0 - abs(normalVS.z);
    53.                 output.positionCS.z += _SlopeScale * slope * output.positionCS.w;
    54.                
    55.                 output.uv = input.uv;
    56.                 return output;
    57.             }
    58.             
    59.             half4 frag(Varyings input) : SV_Target
    60.             {
    61.                 return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
    62.             }
    63.             ENDHLSL
    64.         }
    65.     }
    66. }
    复制代码
【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:豆瓜网用户自行投稿发布,如果侵权,请联系站长删除

相关推荐

您需要登录后才可以回帖 登录 | 立即注册