Unity Holodeck效果Shader异常:仅部分遮挡后方物体求解
Unity内置渲染管线Parallax Cubemap Shader遮挡问题求助
在Unity 2022内置渲染管线中编写可应用于任意几何体的Parallax Cubemap Shader,目标是实现类似Holodeck的效果,让空间看起来比实际更大。目前已实现基础的Parallax Cubemap效果,但后方物体的部分元素会穿透该Surface Shader被渲染出来,包括雾、环境光遮蔽(Ambient Occlusion)、*全局光照(Global Illumination)*以及依赖Z-buffer的“计算机视觉”Shader。
测试场景中:左侧是未被Parallax Cubemap表面遮挡的普通几何体,使用标准Shader并将Albedo设为黄色;右侧是同一物体被Parallax Cubemap表面遮挡的状态,Shader能正常渲染星空立方体贴图,但后方物体的上述元素仍会透出。经测试,这种“部分遮挡”现象适用于所有在Parallax Cubemap表面后方的物体,与Shader类型和渲染顺序无关。
以下是完整的Parallax Cubemap Shader代码:
Shader "Custom/ParallaxCubemap" { Properties { _FrontTex ("FrontTex", 2D) = "white" {} _BackTex ("BackTex", 2D) = "white" {} _LeftTex ("LeftTex", 2D) = "white" {} _RightTex ("RightTex", 2D) = "white" {} _UpTex ("UpTex", 2D) = "white" {} _DownTex ("DownTex", 2D) = "white" {} } SubShader { Tags {"Queue"="Geometry" "RenderType"="Opaque" "LightMode"="Always"} ZWrite On Lighting Off LOD 100 CGPROGRAM #pragma surface surf Unlit noambient noshadow novertexlights nolightmap nodynlightmap nodirlightmap nofog nometa nolppv noshadowmask noforwardadd #pragma target 3.0 sampler2D _FrontTex; sampler2D _BackTex; sampler2D _LeftTex; sampler2D _RightTex; sampler2D _UpTex; sampler2D _DownTex; struct Input { float3 worldPos; float3 worldNormal; float3 viewDir; }; void surf (Input IN, inout SurfaceOutput o) { float3 dir = normalize(IN.viewDir); float2 uv; fixed4 texcolor; float3 absDir = abs(dir); if (absDir.x >= absDir.y && absDir.x >= absDir.z) { uv = dir.yz / absDir.x; if (dir.x < 0) { uv.y *= -1; texcolor = tex2D(_RightTex, uv * 0.5f + 0.5f); } else { texcolor = tex2D(_LeftTex, uv * 0.5f + 0.5f); } } else if (absDir.y >= absDir.x && absDir.y >= absDir.z) { uv = dir.xz / absDir.y; if (dir.y < 0) { texcolor = tex2D(_UpTex, uv * 0.5f + 0.5f); } else { texcolor = tex2D(_DownTex, uv * 0.5f + 0.5f); } } else { uv = dir.xy / absDir.z; if (dir.z < 0) { texcolor = tex2D(_FrontTex, uv * -0.5f + 0.5f); } else { uv.x *= -1; texcolor = tex2D(_BackTex, uv * -0.5f + 0.5f); } } o.Albedo = texcolor.rgb; o.Normal = IN.worldNormal; o.Emission = fixed3(0,0,0); o.Specular = 0; o.Gloss = 0; o.Alpha = 1.0f; } half4 LightingUnlit(SurfaceOutput s, half3 lightDir, half atten) { return half4(s.Albedo, 1.0f); } ENDCG } }
编辑补充:切换为Lambert光照模型可解决“部分遮挡”问题,但会导致Parallax Cubemap表面受雾效影响,虽比穿透问题好,但并非理想方案,恳请提供解决思路。
内容的提问来源于stack exchange,提问作者Zoop
相关产品推荐
相关产品推荐

