博客 / 詳情

返回

【URP】Unity[RendererFeatures]貼花Decal

【從UnityURP開始探索遊戲渲染】專欄-直達

Unity URP中的Decal(貼花)系統是一種用於將材質投射到場景幾何體表面的技術,主要用於實現血跡、彈孔、塗鴉等動態表面裝飾效果。以下是詳細解析:

核心功能與用途

  • 動態投影‌:通過Decal Projector組件將材質動態投射到任意表面,包括曲面和複雜幾何體
  • 光照交互‌:支持與場景光照系統交互,可模擬陰影、高光等物理效果
  • 典型應用場景‌:

    • 遊戲中的彈孔、血跡、塗鴉
    • 環境細節增強(如牆面裂縫、污漬)
    • 技能範圍指示器(如Dota2的地面標記)

技術演進

版本階段 實現方式 特性差異
傳統實現 基於面片Mesh 僅支持平面投影,無法適應複雜曲面
URP早期 Projector組件 存在深度衝突(Z-fighting)問題,性能開銷大
URP 12+ Decal Renderer Feature 支持PBR材質,與SRP深度集成,性能優化

原理

Unity URP中的Decal系統通過‌深度緩衝重建世界座標‌和‌材質投影技術‌實現動態貼花效果,其核心原理可分為以下技術層級:


底層渲染流程

  • 深度圖採樣

    Decal Renderer Feature在渲染管線中插入自定義Pass,通過_CameraDepthTexture獲取像素深度值,結合攝像機參數重建世界座標。關鍵公式:

    worldPos = _CameraToWorld矩陣 × (屏幕UV + 深度值 × 視錐向量)
  • 投影體積裁剪

    使用Decal Projector定義的立方體邊界(Size參數)進行空間裁剪,通過射線與AABB碰撞檢測判斷像素是否在投影範圍內。超出範圍的像素會被剔除。

  • 材質混合

    採用‌延遲渲染路徑‌的GBuffer修改策略,通過Blend指令將Decal的Albedo/Normal/Metallic等屬性與場景材質混合,支持PBR光照交互。


關鍵代碼實現示例

以下為簡化版Shader核心邏輯:

hlsl
// 深度重建世界座標
float3 ReconstructWorldPos(float2 uv, float depth) {
    float4 clipPos = float4(uv * 2 - 1, depth, 1);
    float4 worldPos = mul(_ClipToWorld, clipPos);
    return worldPos.xyz / worldPos.w;
}

// 投影體積判斷
bool IsInDecalVolume(float3 worldPos, float3 decalPos, float3 size) {
    float3 localPos = mul(_WorldToDecal, float4(worldPos, 1)).xyz;
    return all(abs(localPos) < 0.5);
}

技術演進對比

版本 技術方案 缺陷 改進點
傳統實現 基於Mesh面片投影 無法適應曲面 -
URP 10 屏幕空間深度採樣 透明物體不支持 減少Z-fighting
URP 12+ GBuffer混合+體積裁剪 性能開銷較高 支持PBR和動態光照

性能優化要點

  • 層級剔除‌:通過Decal Layer分類控制不同Decal的渲染層級
  • 距離淡出‌:Draw DistanceStart Fade參數動態減少遠處Decal計算
  • 批處理‌:相同材質的Decal Projector會自動合併繪製調用

典型問題解決方案

  • 透明物體支持‌:需自定義Shader重寫AlphaTest邏輯
  • 曲面變形‌:增加Normal Smoothing參數修正法線插值
  • 移動端適配‌:降低深度圖精度或使用Depth Prepass策略

完整實現流程

  • 創建URP Asset:

    • 菜單欄 Edit > Project Settings > Graphics
    • 指定URP Pipeline Asset
  • 添加Decal Renderer Feature:

    • 在URP Renderer Data中添加Decal Renderer Feature
    • 設置Priority控制渲染順序
  • 創建Decal材質:

    • Shader選擇"Universal Render Pipeline/Decal"
    • 配置Albedo、Normal等貼圖通道
  • 放置Decal Projector:

    • 創建空GameObject
    • 添加Decal Projector組件
    • 關聯步驟創建的材質

關鍵參數詳解

參數 類型 作用 典型值
Size Vector3 控制投影體積尺寸 (2,2,2)
Fade Factor Float [0-1] 邊緣漸變強度 0.8
Draw Distance Float 渲染距離閾值 20
Start Fade Float 開始淡出的距離 15
Angle Fade Vector2 基於表面角度的淡出 (0.5,0.8)
Affects Transparent Bool 是否影響透明表面 False

案例:彈孔效果

  • 材質準備‌:

    • 使用8K掃描的彈孔貼圖(Quixel Megascans)
    • 法線貼圖增強立體感
  • 動態生成‌:

    csharp
    void CreateBulletHole(Vector3 hitPoint, Vector3 normal) {
        var decal = new GameObject("BulletHole");
        var projector = decal.AddComponent<DecalProjector>();
        projector.material = bulletHoleMaterial;
        decal.transform.position = hitPoint + normal * 0.1f;
        decal.transform.rotation = Quaternion.LookRotation(-normal);
    }
  • 性能優化‌:

    • 使用對象池管理Decal實例
    • 設置合理的Draw Distance避免過度渲染

注意事項

  • 深度衝突‌:適當調整Projector的Offset參數(建議0.05-0.1)
  • 移動平台‌:需測試ES3.0設備兼容性,必要時降低貼圖分辨率
  • 透明表面‌:默認不支持透明物體接收Decal,需特殊Shader處理

【從UnityURP開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.