Unity URP透视效果异常:物体B在A前方仍可见的解决问询
问题描述
使用Unity 2022.3.16f版本搭配URP,目标效果是透过物体A看到其后方的物体B,但当前出现异常:当物体B位于物体A前方时,仍能透过A看到B,不符合预期。
当前物体A使用的Shader代码如下:
Shader "Custom/Mask" { Properties{} SubShader{ Tags { "RenderType" = "Opaque" } Pass { ZWrite Off } } }
之前参考的英文教程核心思路(已翻译为中文):利用模板缓冲实现透视物体效果,核心逻辑是先渲染遮挡物并标记模板缓冲,再让透视物体仅在模板缓冲未标记的区域显示透视效果。
解决方案
问题核心在于当前Mask Shader未正确处理深度测试与模板缓冲逻辑,导致无论物体B在A前后,都能被穿透显示。以下是修正方案:
1. 修改物体A的Mask Shader
给Shader添加深度测试和模板缓冲逻辑,确保只有A未被遮挡的区域才会标记模板缓冲,同时让深度测试正常工作,避免前方物体被穿透。
修正后的Shader代码:
Shader "Custom/StencilMask" { Properties{} SubShader{ Tags { "RenderType" = "Opaque" "Queue" = "Geometry-100" // 确保在普通几何体之前渲染 } Pass { ZWrite On // 开启深度写入,保障深度测试有效性 ZTest LEqual // 仅渲染未被遮挡的像素(当前深度之前的区域) // 模板缓冲配置:标记未被遮挡的区域 Stencil { Ref 1 Comp Always Pass Replace ZFail Keep // 被遮挡的像素不修改模板缓冲 } ColorMask 0 // 不输出颜色,仅处理深度与模板缓冲 } } }
2. 适配物体B的透视Shader(若需特殊透视效果)
如果物体B需要在透过A时显示半透明/高亮等特殊效果,需在其Shader中添加模板缓冲读取逻辑,仅在A未被遮挡的区域后方显示透视效果:
示例透视Shader代码片段:
Shader "Custom/SeeThroughObject" { Properties{ _BaseColor("基础颜色", Color) = (1,1,1,1) _SeeThroughColor("透视颜色", Color) = (0,1,0,0.5) } SubShader{ Tags { "RenderType" = "Transparent" "Queue" = "Geometry+100" // 在Mask之后渲染 } // 正常渲染通道(非透视区域) Pass { ZWrite On ZTest LEqual Stencil { Ref 1 Comp NotEqual // 仅渲染模板值≠1的区域(不在A后方的部分) } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); return o; } fixed4 _BaseColor; fixed4 frag (v2f i) : SV_Target { return _BaseColor; } ENDCG } // 透视效果通道(透过A看到的区域) Pass { ZWrite Off Blend SrcAlpha OneMinusSrcAlpha // 开启半透明混合 Stencil { Ref 1 Comp Equal // 仅渲染模板值=1的区域(A后方的部分) } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; }; struct v2f { float4 pos : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); return o; } fixed4 _SeeThroughColor; fixed4 frag (v2f i) : SV_Target { return _SeeThroughColor; } ENDCG } } }
3. URP渲染管线设置检查
确保URP模板缓冲与深度纹理正常启用:
- 打开
UniversalRenderPipelineAsset设置面板 - 在Rendering选项卡中,确认Stencil Buffer Format设置为
8 bits - 确保相机的Depth Texture选项已勾选(若需更复杂的深度依赖逻辑)
关键逻辑说明
- 物体A的Mask Shader优先渲染,开启深度写入与测试,仅未被遮挡的像素会将模板缓冲设为1,被遮挡像素(ZFail)保持模板值不变
- 物体B的Shader分两个通道:正常通道渲染不在A后方的部分,透视通道仅渲染A后方的区域,从而实现「B在A前方时正常显示,B在A后方时透过A显示透视效果」的预期逻辑
内容的提问来源于stack exchange,提问作者QingYu Mu
相关产品推荐
相关产品推荐

