Unity中Geometry队列Shader的ZWrite失效导致物体不可见问题
问题修复方案
核心问题分析
你的Shader存在两个关键问题导致Scene视图无法正常显示:
- 片段着色器中引用了未定义的
uv变量,引发编译错误导致Pass无法正常工作 - URP的Scene视图在编辑模式下默认使用
SRPDefaultUnlit的LightMode,而当前Shader仅包含UniversalForward的Pass,无法适配Scene视图的渲染流程
具体修复步骤
步骤1:修复片段着色器的变量错误
将片段着色器中的tex2D(_MainTex, uv);修改为tex2D(_MainTex, IN.uv);,确保使用正确的输入变量。
步骤2:添加适配Scene视图的Pass
在现有Pass之后添加一个兼容Scene视图的Pass,保证Game和Scene视图都能正常工作。
修改后的完整Shader代码如下:
Shader "Bump" { Properties { _MainTex("Main Texture", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" "Queue"="Geometry" } HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" CBUFFER_START(UnityPerMaterial) float4 _MainTex_ST; CBUFFER_END ENDHLSL // Game视图使用的Forward Pass Pass { Name "Example" Tags { "LightMode"="UniversalForward" } ZWrite On ZTest LEqual HLSLPROGRAM #pragma vertex vert #pragma fragment frag struct a2v{ float4 positionOS : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; float4 tangent : TANGENT; }; struct v2f{ float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; float4 t2w0 : TEXCOORD1; float4 t2w1 : TEXCOORD2; float4 t2w2 : TEXCOORD3; }; sampler2D _MainTex; v2f vert(a2v IN) { v2f OUT; VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz); VertexNormalInputs normal_inputs = GetVertexNormalInputs(IN.normal, IN.tangent); OUT.positionCS = positionInputs.positionCS; OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex); OUT.t2w0 = float4(normal_inputs.tangentWS.x, normal_inputs.bitangentWS.x, normal_inputs.normalWS.x, positionInputs.positionWS.x); OUT.t2w1 = float4(normal_inputs.tangentWS.y, normal_inputs.bitangentWS.y, normal_inputs.normalWS.y, positionInputs.positionWS.y); OUT.t2w2 = float4(normal_inputs.tangentWS.z, normal_inputs.bitangentWS.z, normal_inputs.normalWS.z, positionInputs.positionWS.z); return OUT; } half4 frag(v2f IN) : SV_Target { float3 posWS = float3(IN.t2w0.w, IN.t2w1.w, IN.t2w2.w); float3x3 t2wMatrix = float3x3(IN.t2w0.xyz, IN.t2w1.xyz, IN.t2w2.xyz); Light light = GetMainLight(); half3 lightDirWS = normalize(light.direction); half3 viewDirWs = normalize(_WorldSpaceCameraPos.xyz - posWS); half3 halfDirWs = normalize(lightDirWS + viewDirWs); half4 baseMap = tex2D(_MainTex, IN.uv); // 修复此处的uv变量 half3 finalColor = baseMap.rgb; return half4(finalColor, 1); } ENDHLSL } // Scene视图适配Pass Pass { Name "SceneView" Tags { "LightMode"="SRPDefaultUnlit" } ZWrite On ZTest LEqual HLSLPROGRAM #pragma vertex vert #pragma fragment frag struct a2v{ float4 positionOS : POSITION; float2 uv : TEXCOORD0; }; struct v2f{ float4 positionCS : SV_POSITION; float2 uv : TEXCOORD0; }; sampler2D _MainTex; v2f vert(a2v IN) { v2f OUT; VertexPositionInputs positionInputs = GetVertexPositionInputs(IN.positionOS.xyz); OUT.positionCS = positionInputs.positionCS; OUT.uv = TRANSFORM_TEX(IN.uv, _MainTex); return OUT; } half4 frag(v2f IN) : SV_Target { half4 baseMap = tex2D(_MainTex, IN.uv); return half4(baseMap.rgb, 1); } ENDHLSL } } }
额外说明
- 添加的
SRPDefaultUnlitPass专门适配URP的Scene视图渲染,确保编辑模式下物体能正常显示 - 修复后的变量错误保证了原Forward Pass能正常编译运行,ZWrite设置会正确生效
- 若不需要保留复杂的光照计算,也可以直接将原Pass的
LightMode修改为SRPDefaultUnlit,但这样Game视图会失去光照效果
内容的提问来源于stack exchange,提问作者Gary Chi
相关产品推荐
相关产品推荐

