【URP】Unity[視差貼圖]原理剖析實踐
【從UnityURP開始探索游戲渲染】專欄-直達
Unity URP 視差貼圖介紹與分類
視差貼圖(Parallax Mapping)是一種通過動態偏移紋理坐標來模擬表面凹凸效果的渲染技術,主要用于增強低多邊形模型的細節表現。在Unity URP(Universal Render Pipeline)中,它通過高度圖(Height Map)和視角方向計算UV偏移,實現更真實的深度感,而無需增加模型頂點數量?。
?視差貼圖的核心分類?
?標準視差貼圖(Parallax Mapping)
- ?原理?:基于單次高度采樣計算UV偏移,性能消耗低但效果有限,適合移動端或性能敏感場景?。
- ?實現?:通過高度圖的灰度值(黑色為低點,白色為高點)和視角方向,在切線空間內偏移UV坐標,模擬遮擋效果?。
- ?示例?:URP中通過
ParallaxOffset1Step函數實現單步偏移計算?。-
?關鍵參數?
_HeightMap:存儲高度信息的紋理(R通道)_Parallax:控制凹凸強度的縮放系數(建議0.02-0.05)
-
?切線空間轉換?
- 使用URP內置函數
GetVertexNormalInputs構建TBN矩陣,將視角方向轉換到切線空間
- 使用URP內置函數
-
?性能優化?
- 單步偏移計算(
ParallaxOffset)相比多步光線步進(如POM)性能更高,適合移動端
- 單步偏移計算(
-
ParallaxLit.shader
Shader "Universal Render Pipeline/ParallaxLit" { Properties { _MainTex("Albedo", 2D) = "white" {} _NormalMap("Normal Map", 2D) = "bump" {} _HeightMap("Height Map", 2D) = "white" {} _Parallax("Height Scale", Range(0, 0.1)) = 0.02 } SubShader { Tags { "RenderPipeline"="UniversalPipeline" } HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); TEXTURE2D(_NormalMap); SAMPLER(sampler_NormalMap); TEXTURE2D(_HeightMap); SAMPLER(sampler_HeightMap); float _Parallax; float2 ParallaxOffset(float3 viewDirTS, float height) { height = height * _Parallax - _Parallax * 0.5; return height * (viewDirTS.xy / (viewDirTS.z + 0.42)); } ENDHLSL Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag struct Attributes { float4 positionOS : POSITION; float2 uv : TEXCOORD0; float3 normalOS : NORMAL; float4 tangentOS : TANGENT; }; struct Varyings { float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float3 viewDirTS : TEXCOORD1; }; Varyings vert(Attributes IN) { Varyings OUT; VertexPositionInputs posInput = GetVertexPositionInputs(IN.positionOS.xyz); OUT.positionCS = posInput.positionCS; // 計算切線空間視角方向 VertexNormalInputs normInput = GetVertexNormalInputs(IN.normalOS, IN.tangentOS); float3 viewDirWS = GetWorldSpaceViewDir(posInput.positionWS); OUT.viewDirTS = TransformWorldToTangent(viewDirWS, normInput.tangentWS, normInput.bitangentWS, normInput.normalWS); OUT.uv = IN.uv; return OUT; } half4 frag(Varyings IN) : SV_Target { // 采樣高度圖并計算UV偏移 float height = SAMPLE_TEXTURE2D(_HeightMap, sampler_HeightMap, IN.uv).r; float2 offset = ParallaxOffset(normalize(IN.viewDirTS), height); // 應用偏移后采樣紋理 float2 parallaxUV = IN.uv + offset; half4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, parallaxUV); half3 normalTS = UnpackNormal(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, parallaxUV)); return half4(albedo.rgb, 1); } ENDHLSL } } }
-
?陡峭視差貼圖(Steep Parallax Mapping)
- ?特點?:針對陡峭地形優化,通過多次采樣(如二分法)減少失真,適合高落差表面(如巖石、冰縫)?。
- ?實現?:在URP中結合光線步進(Raymarching)算法,逐層檢測高度圖以確定最終UV偏移?。
?視差遮擋貼圖(Parallax Occlusion Mapping, POM)
- ?優勢?:在標準視差基礎上增加遮擋計算,通過多次采樣模擬更精確的深度感,但性能開銷較高?。
- ?應用?:常用于風格化材質(如風化巖石、冰面裂縫),需配合高度圖和法線貼圖使用?。
?技術實現細節?
核心原理
- ?高度圖采樣?
- 使用灰度圖(通常存儲在法線貼圖的Alpha通道)表示表面深度,黑色(0)為最低點,白色(1)為最高點。
- ?切線空間轉換?
- 將視角方向從世界空間轉換到切線空間(通過TBN矩陣),確保偏移方向與模型表面法線對齊。
- ?UV偏移計算
- 根據高度值和視角方向動態調整UV坐標,核心公式為? $offset=\frac{height \cdot viewDir_{xy}}{viewDir_z}$
- 其中
viewDir需歸一化,且需避免除零(通常添加小偏移量如viewDir.z + 0.42)
?URP中的Shader實現?
-
核心函數:
ParallaxOffset1Step(單步偏移)或自定義光線步進算法?。 -
示例代碼(HLSL):
hlsl float2 ParallaxOffset(half3 viewDirTS, half height, half scale) { return height * (viewDirTS.xy / viewDirTS.z) * scale; }
?性能優化?
- 使用
_Parallax參數控制強度,避免過度偏移導致穿幫?。 - 移動端建議采用標準視差貼圖,PC端可嘗試POM?。
?與其他貼圖技術的對比?
| 技術 | 原理差異 | 性能開銷 | 適用場景 | 優勢 | 局限性 |
|---|---|---|---|---|---|
| 法線貼圖 | 僅改變光照計算 | 低 | 通用細節增強 | 性能最優 | 平視視角易穿幫 |
| 視差貼圖 | 動態UV偏移模擬深度 | 中 | 風格化材質、地形 | 真實遮擋效果 | 陡峭邊緣可能失真 |
| 置換貼圖 | 實際修改頂點位置 | 高 | 高精度模型(如地形) | 幾何級精度 | 需要曲面細分支持 |
?總結?
視差貼圖在URP中通過動態UV偏移和高度圖采樣,有效平衡了性能與視覺效果。根據需求選擇標準、陡峭或POM變種,可適配不同場景的細節要求?
【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,??)

【UnityURP視差貼圖技術解析】文章摘要:視差貼圖是UnityURP中通過動態UV偏移模擬凹凸細節的渲染技術,分為標準/陡峭/POM三種實現方式。標準版通過單次高度采樣計算偏移,適合移動端;陡峭版優化高落差表面表現;POM增加遮擋計算但性能開銷較大。技術核心是高度圖采樣和切線空間轉換,需注意避免除零問題。相比法線貼圖和置換貼圖,視差貼圖在性能與效果間取得平衡,適合風格化材質表現。URP中可通過Shader代碼實現,關鍵參數包括_HeightMap和_Parallax強度控制。
浙公網安備 33010602011771號