【URP】Unity[置換貼圖]原理與實踐
專欄-直達
置換貼圖(Displacement Map)是一種(zhong)通(tong)過修改頂點位置來實現(xian)表面凹凸細節的(de)技術,與法(fa)線貼圖僅影(ying)響光(guang)照不(bu)同,它直接改變(bian)幾何形(xing)狀,適用(yong)于需要真實物理變(bian)形(xing)的(de)場景。
技術原理與解決的問題
?功能差異?:
- 置換貼圖通過灰度值控制頂點位移(白色凸起,黑色凹陷),相比法線貼圖能產生真實的輪廓陰影和遮擋效果,解決了低模表現高精度幾何細節的難題。
?性能權衡?:
- 需要細分曲面(Tessellation)支持,計算開銷大于法線貼圖,但視覺效果更真實。
歷史發展節點
?早期階段?:
- 傳統Shader Model 5.0引入硬件細分曲面,Unity通過自定義Shader實現置換效果。
?URP集成?:
- URP 7.0+原生支持Decal Projector組件,簡化了貼花(含置換效果)的投影流程。
?優化演進?:
- 結合SRP Batcher減少Draw Call,提升實例化渲染效率。
原理示意圖:
- 置換流程:貼圖采樣 → 頂點偏移 → 細分曲面 → 像素著色
- 優化鏈路:SRP Batcher合并材質 → GPU Instancing處理動態實例
URP實現步驟
?材質配置?:
- 創建URP Lit Shader Graph,添加
Tessellation和Displacement節點。 - 連接置換貼圖(R通道)到頂點偏移量,調整細分級。
?組件綁定?:
- 創建Decal Projector GameObject
- 分配置換材質
- 設置投影范圍(Size/Depth)和剔除層級
?腳本控制?(可選):
csharp
// 動態修改置換強度
void Update() {
decalProjector.material.SetFloat("_DisplacementScale", intensity);
}
彈孔效果實現
- 血跡/彈痕?:通過Decal Projector動態投射到場景物體,結合碰撞檢測確定UV坐標。
?貼圖生成?:
- 使用Substance Designer或Photoshop繪制灰度圖,白色區域表示彈孔凹陷深度。
?Shader Graph配置?:
- 添加
Parallax Occlusion Mapping節點模擬深度偏移。 - 混合置換與法線貼圖增強細節。
?性能優化?:
- 啟用GPU Instancing減少相同材質的Draw Call。
- 使用MaterialPropertyBlock動態修改實例屬性。
置換貼圖生成裂縫、巖石凸起
- ?地形細節?:與Terrain系統配合,在運行時置換頂點生成裂縫或巖石凸起。
- 通過置換貼圖動態修改地形頂點生成裂縫/巖石凸起的完整實現方案,結合Terrain系統與Shader Graph。
核心原理
- ?置換貼圖作用?:灰度圖控制頂點位移(白色凸起,黑色凹陷),需配合曲面細分(Tessellation)增加幾何精度
- ?URP適配?:通過Shader Graph的
Tessellation節點和Height節點實現硬件細分與頂點偏移 - ?地形融合?:將置換Shader作為Terrain Layer材質,動態影響局部頂點
完整實現步驟
置換貼圖生成
- ?工具選擇?:使用Substance Designer或Photoshop繪制灰度圖(巖石凸起區域為白色,裂縫為黑色)
- ?規范要求?:
- 分辨率:2048x2048(匹配地形尺寸)
格式:PNG無損壓縮
色彩空間:Linear
- 分辨率:2048x2048(匹配地形尺寸)
Shader Graph配置
- [Height Map] → [Sample Texture 2D] → [Remap(0-1 to -1-1)]
- [Tessellation]節點設置細分級別(Edge:16, Inside:8)
- [Parallax Occlusion]節點增強深度感知
- 混合法線貼圖與置換效果
Terrain系統集成
csharp
// C#腳本動態加載置換材質
void ApplyDisplacementToTerrain() {
TerrainLayer layer = new TerrainLayer();
layer.diffuseTexture = rockAlbedo;
layer.normalMapTexture = rockNormal;
layer.maskMapTexture = displacementMap;// 置換貼圖
Terrain.activeTerrain.terrainData.terrainLayers = new TerrainLayer[]{ layer };
}
性能優化
- ?動態細分?:根據攝像機距離調整細分因子(
UnityDistanceBasedTess) - ?LOD控制?:超過50米后禁用置換效果
- ?批次合并?:啟用SRP Batcher減少Draw Call
動態裂縫生成
-
?運行時修改貼圖?:
csharp // 通過RenderTexture實時繪制裂縫 void UpdateCrackTexture(Vector3 hitPoint) { Graphics.Blit(crackBrush, displacementRT, displacementMat); Shader.SetGlobalTexture("_DynamicDisplacement", displacementRT); } -
?Shader動態采樣?:
hlsl float height = tex2Dlod(_DynamicDisplacement, float4(uv,0,0)).r; v.vertex.y += height * _DisplacementScale;
技術對比
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 法線貼圖 | 性能開銷低 | 無真實幾何變形 | 小范圍表面細節 |
| 視差遮蔽映射 | 中等精度遮擋效果 | 高頻細節失真 | 磚墻/地板接縫 |
| ?置換貼圖? | 真實幾何變形 | 需硬件細分支持 | 地形/大規模結構變形 |
調試建議
- ?可視化模式?:啟用URP的
Depth NormalsPass檢查細分效果 - ?參數調優?:
- _TessellationEdgeLength:控制細分密度(建議值8-20)
_DisplacementScale:位移強度(建議值0.1-2.0)
- _TessellationEdgeLength:控制細分密度(建議值8-20)
專欄-直達
(歡迎點贊留言探(tan)討,更多(duo)人加入進來(lai)能更加完善這個探(tan)索的過程,??)

置換貼圖(Displacement Map)是一種通過修改頂點位置來實現表面凹凸細節的技術,與法線貼圖僅影響光照不同,它直接改變幾何形狀,適用于需要真實物理變形的場景。 技術原理與解決的問題 ?功能差