diff --git a/Assets/Materials/Hero Cutout Occluder.mat b/Assets/Materials/Hero Cutout Occluder.mat index ae6d770..4466773 100644 --- a/Assets/Materials/Hero Cutout Occluder.mat +++ b/Assets/Materials/Hero Cutout Occluder.mat @@ -16,7 +16,7 @@ Material: m_LightmapFlags: 4 m_EnableInstancingVariants: 0 m_DoubleSidedGI: 0 - m_CustomRenderQueue: -1 + m_CustomRenderQueue: 2000 stringTagMap: RenderType: Opaque disabledShaderPasses: [] diff --git a/Assets/Unused/HeroCutoutLit.shader b/Assets/Unused/HeroCutoutLit.shader index 94b65b3..6dd5164 100644 --- a/Assets/Unused/HeroCutoutLit.shader +++ b/Assets/Unused/HeroCutoutLit.shader @@ -4,7 +4,7 @@ // // It is a faithful copy of URP's Lit.shader - same properties, keywords and includes, so material // values transfer 1:1 and the inspector GUI keeps working. The ONLY change is in four passes -// (ForwardLit, ShadowCaster, DepthOnly, DepthNormals): the stock fragment entry point is replaced by +// (ForwardLit, GBuffer, DepthOnly, DepthNormals): the stock fragment entry point is replaced by // a thin wrapper that runs ApplyHeroCutout() and then delegates to URP's original fragment. All // shading is therefore URP's own - zero reimplementation, so it stays correct across URP updates. Shader "Custom/HeroCutoutLit" @@ -278,7 +278,7 @@ Shader "Custom/HeroCutoutLit" // ------------------------------------- // Shader Stages #pragma vertex LitGBufferPassVertex - #pragma fragment LitGBufferPassFragment + #pragma fragment HeroGBufferFragment // ------------------------------------- // Material Keywords @@ -337,6 +337,17 @@ Shader "Custom/HeroCutoutLit" // Includes #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" #include "Packages/com.unity.render-pipelines.universal/Shaders/LitGBufferPass.hlsl" + #include "HeroCutout.hlsl" + + // Radial cutout, then delegate to URP's stock GBuffer fragment. Without this, external + // GBuffer consumers (HTrace WSGI renders its own thin GBuffer via this LightMode and + // composites GI after post-processing) still see solid occluder geometry inside the hole + // and stomp the visible skybox/background there with surface GI -> black disc. + GBufferFragOutput HeroGBufferFragment(Varyings input) + { + ApplyHeroCutout(input.positionCS); + return LitGBufferPassFragment(input); + } ENDHLSL } @@ -540,12 +551,36 @@ Shader "Custom/HeroCutoutLit" ColorMask RG HLSLPROGRAM + // The cutout MUST also apply here: this pass has ZWrite On (default) and external + // consumers draw it against the LIVE camera depth attachment BEFORE the skybox + // (HTrace WSGI's object-motion-vectors pass at AfterRenderingOpaques). Without the + // clip it re-fills the hole with occluder depth -> the skybox fails ZTest inside the + // hole -> black disc, and the corrupted depth leaks into _CameraDepthTexture (SSAO/GI). + // + // ObjectMotionVectors.hlsl hardcodes "#pragma fragment frag" via include_with_pragmas, + // so we declare the pragmas ourselves and plain-#include it (plain includes contribute + // no pragmas), then wrap its frag(). + #pragma target 3.5 + #pragma vertex vert + #pragma fragment HeroMotionVectorsFragment + #pragma shader_feature_local _ALPHATEST_ON #pragma multi_compile _ LOD_FADE_CROSSFADE #pragma shader_feature_local_vertex _ADD_PRECOMPUTED_VELOCITY + #pragma multi_compile_instancing + #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DOTS.hlsl" + #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl" + #include "Packages/com.unity.render-pipelines.universal/Shaders/LitInput.hlsl" - #include_with_pragmas "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ObjectMotionVectors.hlsl" + #include "HeroCutout.hlsl" + + float4 HeroMotionVectorsFragment(Varyings input) : SV_Target + { + ApplyHeroCutout(input.positionCS); + return frag(input); + } ENDHLSL }