diff --git a/com.unity.render-pipelines.universal/CHANGELOG.md b/com.unity.render-pipelines.universal/CHANGELOG.md index 7147c9fc47a..e703331f6bd 100644 --- a/com.unity.render-pipelines.universal/CHANGELOG.md +++ b/com.unity.render-pipelines.universal/CHANGELOG.md @@ -6,8 +6,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [12.1.0] - 2021-09-23 +### Added +- URP global setting for stripping post processing shader variants. +- URP global setting for stripping off shader variants. + ### Changed - URP will no longer render via an intermediate texture unless actively required by a Renderer Feature. See the upgrade guide for compatibility options and how assets are upgraded. +- Main light shadow, additional light shadow and additional light keywords are now enabled based on urp setting instead of existence in scene. This allows better variant stripping. + ### Fixed - Fixed a Universal Targets in ShaderGraph not rendering correctly in game view [1352225] diff --git a/com.unity.render-pipelines.universal/Editor/ShaderPreprocessor.cs b/com.unity.render-pipelines.universal/Editor/ShaderPreprocessor.cs index 281ff34c047..e87cb5fa551 100644 --- a/com.unity.render-pipelines.universal/Editor/ShaderPreprocessor.cs +++ b/com.unity.render-pipelines.universal/Editor/ShaderPreprocessor.cs @@ -48,6 +48,8 @@ enum ShaderFeatures MainLightShadowsCascade = (1 << 26), DrawProcedural = (1 << 27), ScreenSpaceOcclusionAfterOpaque = (1 << 28), + AdditionalLightsKeepOffVariants = (1 << 29), + ShadowsKeepOffVariants = (1 << 30), } [Flags] @@ -358,12 +360,22 @@ bool StripUnusedFeatures(ShaderFeatures features, Shader shader, ShaderSnippetDa var stripTool = new StripTool(features, shader, snippetData, compilerData.shaderKeywordSet, stripUnusedVariants); // strip main light shadows, cascade and screen variants - // TODO: Strip disabled keyword once no light will re-use same variant - if (stripTool.StripMultiCompileKeepOffVariant( - m_MainLightShadows, ShaderFeatures.MainLightShadows, - m_MainLightShadowsCascades, ShaderFeatures.MainLightShadowsCascade, - m_MainLightShadowsScreen, ShaderFeatures.ScreenSpaceShadows)) - return true; + if (IsFeatureEnabled(ShaderFeatures.ShadowsKeepOffVariants, features)) + { + if (stripTool.StripMultiCompileKeepOffVariant( + m_MainLightShadows, ShaderFeatures.MainLightShadows, + m_MainLightShadowsCascades, ShaderFeatures.MainLightShadowsCascade, + m_MainLightShadowsScreen, ShaderFeatures.ScreenSpaceShadows)) + return true; + } + else + { + if (stripTool.StripMultiCompile( + m_MainLightShadows, ShaderFeatures.MainLightShadows, + m_MainLightShadowsCascades, ShaderFeatures.MainLightShadowsCascade, + m_MainLightShadowsScreen, ShaderFeatures.ScreenSpaceShadows)) + return true; + } // TODO: Strip off variants once we have global soft shadows option for forcing instead as support if (stripTool.StripMultiCompileKeepOffVariant(m_SoftShadows, ShaderFeatures.SoftShadows)) @@ -400,9 +412,16 @@ bool StripUnusedFeatures(ShaderFeatures features, Shader shader, ShaderSnippetDa return true; // No additional light shadows - // TODO: Strip off variants once we support no shadow lights re-use same variant - if (stripTool.StripMultiCompileKeepOffVariant(m_AdditionalLightShadows, ShaderFeatures.AdditionalLightShadows)) - return true; + if (IsFeatureEnabled(ShaderFeatures.ShadowsKeepOffVariants, features)) + { + if (stripTool.StripMultiCompileKeepOffVariant(m_AdditionalLightShadows, ShaderFeatures.AdditionalLightShadows)) + return true; + } + else + { + if (stripTool.StripMultiCompile(m_AdditionalLightShadows, ShaderFeatures.AdditionalLightShadows)) + return true; + } if (stripTool.StripMultiCompile(m_ReflectionProbeBlending, ShaderFeatures.ReflectionProbeBlending)) return true; @@ -425,10 +444,18 @@ bool StripUnusedFeatures(ShaderFeatures features, Shader shader, ShaderSnippetDa } // Additional light are shaded per-vertex or per-pixel. - // TODO: Strip off variants once we support no additional lights re-used variants - if (stripTool.StripMultiCompileKeepOffVariant(m_AdditionalLightsVertex, ShaderFeatures.VertexLighting, - m_AdditionalLightsPixel, ShaderFeatures.AdditionalLights)) - return true; + if (IsFeatureEnabled(ShaderFeatures.AdditionalLightsKeepOffVariants, features)) + { + if (stripTool.StripMultiCompileKeepOffVariant(m_AdditionalLightsVertex, ShaderFeatures.VertexLighting, + m_AdditionalLightsPixel, ShaderFeatures.AdditionalLights)) + return true; + } + else + { + if (stripTool.StripMultiCompile(m_AdditionalLightsVertex, ShaderFeatures.VertexLighting, + m_AdditionalLightsPixel, ShaderFeatures.AdditionalLights)) + return true; + } if (stripTool.StripMultiCompile(m_ClusteredRendering, ShaderFeatures.ClusteredRendering)) return true; @@ -921,6 +948,12 @@ private static ShaderFeatures GetSupportedShaderFeatures(UniversalRenderPipeline } } + if (!renderer.stripShadowsOffVariants) + shaderFeatures |= ShaderFeatures.ShadowsKeepOffVariants; + + if (!renderer.stripAdditionalLightOffVariants) + shaderFeatures |= ShaderFeatures.AdditionalLightsKeepOffVariants; + var rendererClustered = false; ScriptableRendererData rendererData = pipelineAsset.m_RendererDataList[rendererIndex]; diff --git a/com.unity.render-pipelines.universal/Runtime/ForwardLights.cs b/com.unity.render-pipelines.universal/Runtime/ForwardLights.cs index 1dc4a6cd8ba..7a4f6ecb50c 100644 --- a/com.unity.render-pipelines.universal/Runtime/ForwardLights.cs +++ b/com.unity.render-pipelines.universal/Runtime/ForwardLights.cs @@ -353,10 +353,11 @@ public void Setup(ScriptableRenderContext context, ref RenderingData renderingDa SetupShaderLightConstants(cmd, ref renderingData); + bool lightCountCheck = (renderingData.cameraData.renderer.stripAdditionalLightOffVariants && renderingData.lightData.supportsAdditionalLights) || additionalLightsCount > 0; CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightsVertex, - additionalLightsCount > 0 && additionalLightsPerVertex && !useClusteredRendering); + lightCountCheck && additionalLightsPerVertex && !useClusteredRendering); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightsPixel, - additionalLightsCount > 0 && !additionalLightsPerVertex && !useClusteredRendering); + lightCountCheck && !additionalLightsPerVertex && !useClusteredRendering); CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.ClusteredRendering, useClusteredRendering); diff --git a/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs b/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs index 0d7b638fd26..c7050766841 100644 --- a/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs +++ b/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs @@ -48,6 +48,12 @@ public ShadowResolutionRequest(int _visibleLightIndex, int _perLightShadowSliceI } } + /// + /// x is used in RenderAdditionalShadowMapAtlas to skip shadow map rendering for non-shadow-casting lights. + /// w is perLightFirstShadowSliceIndex, used in Lighting shader to find if Additional light casts shadows. + /// + readonly static Vector4 c_DefaultShadowParams = new Vector4(0, 0, 0, -1); + static int m_AdditionalLightsWorldToShadow_SSBO; static int m_AdditionalShadowParams_SSBO; bool m_UseStructuredBuffer; @@ -76,6 +82,8 @@ public ShadowResolutionRequest(int _visibleLightIndex, int _perLightShadowSliceI int[] m_VisibleLightIndexToSortedShadowResolutionRequestsFirstSliceIndex = null; // for each visible light, store the index of its first shadow slice in m_SortedShadowResolutionRequests (for quicker access) List m_UnusedAtlasSquareAreas = new List(); // this list tracks space available in the atlas + bool m_CreateEmptyShadowmap; + bool m_SupportsBoxFilterForShadows; ProfilingSampler m_ProfilingSetupSampler = new ProfilingSampler("Setup Additional Shadows"); @@ -608,11 +616,8 @@ public bool Setup(ref RenderingData renderingData) m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix = new Matrix4x4[totalShadowSlicesCount]; // initialize _AdditionalShadowParams - Vector4 defaultShadowParams = new Vector4(0 /*shadowStrength*/, 0, 0, -1 /*perLightFirstShadowSliceIndex*/); - // shadowParams.x is used in RenderAdditionalShadowMapAtlas to skip shadow map rendering for non-shadow-casting lights - // shadowParams.w is used in Lighting shader to find if Additional light casts shadows for (int i = 0; i < maxAdditionalLightShadowParams; ++i) - m_AdditionalLightIndexToShadowParams[i] = defaultShadowParams; + m_AdditionalLightIndexToShadowParams[i] = c_DefaultShadowParams; int validShadowCastingLightsCount = 0; bool supportsSoftShadows = renderingData.shadowData.supportsSoftShadows; @@ -731,7 +736,7 @@ public bool Setup(ref RenderingData renderingData) // Lights that need to be rendered in the shadow map atlas if (validShadowCastingLightsCount == 0) - return false; + return SetupForEmptyRendering(ref renderingData); int shadowCastingLightsBufferCount = m_ShadowSliceToAdditionalLightIndex.Count; @@ -786,6 +791,24 @@ public bool Setup(ref RenderingData renderingData) m_AdditionalLightsShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits); m_MaxShadowDistanceSq = renderingData.cameraData.maxShadowDistance * renderingData.cameraData.maxShadowDistance; m_CascadeBorder = renderingData.shadowData.mainLightShadowCascadeBorder; + m_CreateEmptyShadowmap = false; + useNativeRenderPass = true; + + return true; + } + + bool SetupForEmptyRendering(ref RenderingData renderingData) + { + if (!renderingData.cameraData.renderer.stripShadowsOffVariants) + return false; + + m_AdditionalLightsShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(1, 1, k_ShadowmapBufferBits); + m_CreateEmptyShadowmap = true; + useNativeRenderPass = false; + + // initialize _AdditionalShadowParams + for (int i = 0; i < m_AdditionalLightIndexToShadowParams.Length; ++i) + m_AdditionalLightIndexToShadowParams[i] = c_DefaultShadowParams; return true; } @@ -799,6 +822,12 @@ public override void Configure(CommandBuffer cmd, RenderTextureDescriptor camera /// public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { + if (m_CreateEmptyShadowmap) + { + SetEmptyAdditionalShadowmapAtlas(ref context); + return; + } + if (renderingData.shadowData.supportsAdditionalLightShadows) RenderAdditionalShadowmapAtlas(ref context, ref renderingData.cullResults, ref renderingData.lightData, ref renderingData.shadowData); } @@ -832,6 +861,24 @@ void Clear() m_AdditionalLightsShadowmapTexture = null; } + void SetEmptyAdditionalShadowmapAtlas(ref ScriptableRenderContext context) + { + CommandBuffer cmd = CommandBufferPool.Get(); + CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.AdditionalLightShadows, true); + if (RenderingUtils.useStructuredBuffer) + { + var shadowParamsBuffer = ShaderData.instance.GetAdditionalLightShadowParamsStructuredBuffer(m_AdditionalLightIndexToShadowParams.Length); + shadowParamsBuffer.SetData(m_AdditionalLightIndexToShadowParams); + cmd.SetGlobalBuffer(m_AdditionalShadowParams_SSBO, shadowParamsBuffer); + } + else + { + cmd.SetGlobalVectorArray(AdditionalShadowsConstantBuffer._AdditionalShadowParams, m_AdditionalLightIndexToShadowParams); + } + context.ExecuteCommandBuffer(cmd); + CommandBufferPool.Release(cmd); + } + void RenderAdditionalShadowmapAtlas(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData) { NativeArray visibleLights = lightData.visibleLights; diff --git a/com.unity.render-pipelines.universal/Runtime/Passes/MainLightShadowCasterPass.cs b/com.unity.render-pipelines.universal/Runtime/Passes/MainLightShadowCasterPass.cs index 93f653a3846..5afe3b6a859 100644 --- a/com.unity.render-pipelines.universal/Runtime/Passes/MainLightShadowCasterPass.cs +++ b/com.unity.render-pipelines.universal/Runtime/Passes/MainLightShadowCasterPass.cs @@ -38,6 +38,8 @@ private static class MainLightShadowConstantBuffer ShadowSliceData[] m_CascadeSlices; Vector4[] m_CascadeSplitDistances; + bool m_CreateEmptyShadowmap; + ProfilingSampler m_ProfilingSetupSampler = new ProfilingSampler("Setup Main Shadowmap"); public MainLightShadowCasterPass(RenderPassEvent evt) @@ -71,17 +73,17 @@ public bool Setup(ref RenderingData renderingData) using var profScope = new ProfilingScope(null, m_ProfilingSetupSampler); if (!renderingData.shadowData.supportsMainLightShadows) - return false; + return SetupForEmptyRendering(ref renderingData); Clear(); int shadowLightIndex = renderingData.lightData.mainLightIndex; if (shadowLightIndex == -1) - return false; + return SetupForEmptyRendering(ref renderingData); VisibleLight shadowLight = renderingData.lightData.visibleLights[shadowLightIndex]; Light light = shadowLight.light; if (light.shadows == LightShadows.None) - return false; + return SetupForEmptyRendering(ref renderingData); if (shadowLight.lightType != LightType.Directional) { @@ -90,7 +92,7 @@ public bool Setup(ref RenderingData renderingData) Bounds bounds; if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out bounds)) - return false; + return SetupForEmptyRendering(ref renderingData); m_ShadowCasterCascadesCount = renderingData.shadowData.mainLightShadowCascadesCount; @@ -108,12 +110,26 @@ public bool Setup(ref RenderingData renderingData) out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex]); if (!success) - return false; + return SetupForEmptyRendering(ref renderingData); } m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits); m_MaxShadowDistanceSq = renderingData.cameraData.maxShadowDistance * renderingData.cameraData.maxShadowDistance; m_CascadeBorder = renderingData.shadowData.mainLightShadowCascadeBorder; + m_CreateEmptyShadowmap = false; + useNativeRenderPass = true; + + return true; + } + + bool SetupForEmptyRendering(ref RenderingData renderingData) + { + if (!renderingData.cameraData.renderer.stripShadowsOffVariants) + return false; + + m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(1, 1, k_ShadowmapBufferBits); + m_CreateEmptyShadowmap = true; + useNativeRenderPass = false; return true; } @@ -127,6 +143,12 @@ public override void Configure(CommandBuffer cmd, RenderTextureDescriptor camera /// public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { + if (m_CreateEmptyShadowmap) + { + SetEmptyMainLightCascadeShadowmap(ref context); + return; + } + RenderMainLightCascadeShadowmap(ref context, ref renderingData.cullResults, ref renderingData.lightData, ref renderingData.shadowData); } @@ -157,6 +179,19 @@ void Clear() m_CascadeSlices[i].Clear(); } + void SetEmptyMainLightCascadeShadowmap(ref ScriptableRenderContext context) + { + CommandBuffer cmd = CommandBufferPool.Get(); + CoreUtils.SetKeyword(cmd, ShaderKeywordStrings.MainLightShadows, true); + cmd.SetGlobalTexture(m_MainLightShadowmap.id, m_MainLightShadowmapTexture); + cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowParams, + new Vector4(1, 0, 1, 0)); + cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, + new Vector4(1f / m_MainLightShadowmapTexture.width, 1f / m_MainLightShadowmapTexture.height, m_MainLightShadowmapTexture.width, m_MainLightShadowmapTexture.height)); + context.ExecuteCommandBuffer(cmd); + CommandBufferPool.Release(cmd); + } + void RenderMainLightCascadeShadowmap(ref ScriptableRenderContext context, ref CullingResults cullResults, ref LightData lightData, ref ShadowData shadowData) { int shadowLightIndex = lightData.mainLightIndex; diff --git a/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs b/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs index a6ed15da98b..50d9e94297e 100644 --- a/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs +++ b/com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs @@ -491,6 +491,10 @@ internal static void ConfigureActiveTarget(RenderTargetIdentifier colorAttachmen internal bool useDepthPriming { get; set; } = false; + internal bool stripShadowsOffVariants { get; set; } = false; + + internal bool stripAdditionalLightOffVariants { get; set; } = false; + public ScriptableRenderer(ScriptableRendererData data) { if (Debug.isDebugBuild) diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs index 66a9e9521dc..0108c9cbca4 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs @@ -1093,6 +1093,7 @@ static void InitializeLightData(UniversalRenderPipelineAsset settings, NativeArr lightData.maxPerObjectAdditionalLightsCount = 0; } + lightData.supportsAdditionalLights = settings.additionalLightsRenderingMode != LightRenderingMode.Disabled; lightData.shadeAdditionalLightsPerVertex = settings.additionalLightsRenderingMode == LightRenderingMode.PerVertex; lightData.visibleLights = visibleLights; lightData.supportsMixedLighting = settings.supportsMixedLighting; diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs index b92bf21219c..e5343993671 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderPipelineCore.cs @@ -43,6 +43,11 @@ public struct LightData public bool reflectionProbeBoxProjection; public bool reflectionProbeBlending; public bool supportsLightLayers; + + /// + /// True if additional lights enabled. + /// + public bool supportsAdditionalLights; } public struct CameraData diff --git a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs index f2965e86dbc..4b8be34c6c3 100644 --- a/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs +++ b/com.unity.render-pipelines.universal/Runtime/UniversalRenderer.cs @@ -166,6 +166,9 @@ public UniversalRenderer(UniversalRendererData data) : base(data) m_LightCookieManager = new LightCookieManager(ref settings); } + this.stripShadowsOffVariants = true; + this.stripAdditionalLightOffVariants = true; + ForwardLights.InitParams forwardInitParams; forwardInitParams.lightCookieManager = m_LightCookieManager; forwardInitParams.clusteredRendering = data.clusteredRendering; @@ -186,6 +189,7 @@ public UniversalRenderer(UniversalRendererData data) : base(data) // we inject the builtin passes in the before events. m_MainLightShadowCasterPass = new MainLightShadowCasterPass(RenderPassEvent.BeforeRenderingShadows); m_AdditionalLightsShadowCasterPass = new AdditionalLightsShadowCasterPass(RenderPassEvent.BeforeRenderingShadows); + #if ENABLE_VR && ENABLE_XR_MODULE m_XROcclusionMeshPass = new XROcclusionMeshPass(RenderPassEvent.BeforeRenderingOpaques); // Schedule XR copydepth right after m_FinalBlitPass(AfterRendering + 1) diff --git a/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader b/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader index 6873d0b9b0d..756c1c10d03 100644 --- a/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader +++ b/com.unity.render-pipelines.universal/Shaders/Particles/ParticlesSimpleLit.shader @@ -177,7 +177,7 @@ Shader "Universal Render Pipeline/Particles/Simple Lit" // Universal Pipeline keywords #pragma multi_compile _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN //#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS - #pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS + //#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS #pragma multi_compile_fragment _ _SHADOWS_SOFT #pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT #pragma multi_compile_fragment _ _RENDER_PASS_ENABLED diff --git a/com.unity.testing.urp/Scripts/Runtime/CustomRenderPipeline/CustomRenderer.cs b/com.unity.testing.urp/Scripts/Runtime/CustomRenderPipeline/CustomRenderer.cs index c31e61e99a9..363abb1bd00 100644 --- a/com.unity.testing.urp/Scripts/Runtime/CustomRenderPipeline/CustomRenderer.cs +++ b/com.unity.testing.urp/Scripts/Runtime/CustomRenderPipeline/CustomRenderer.cs @@ -4,14 +4,21 @@ namespace UnityEngine.Rendering.Universal { public class CustomRenderer : ScriptableRenderer { - private DrawObjectsPass m_RenderOpaqueForwardPass; - + DrawObjectsPass m_RenderOpaqueForwardPass; ForwardLights m_ForwardLights; + MainLightShadowCasterPass m_MainLightShadowCasterPass; + AdditionalLightsShadowCasterPass m_AdditionalLightsShadowCasterPass; public CustomRenderer(CustomRenderGraphData data) : base(data) { - m_RenderOpaqueForwardPass = new DrawObjectsPass("Render Opaques", true, RenderPassEvent.BeforeRenderingOpaques + 1, RenderQueueRange.opaque, -1, StencilState.defaultValue, 0); + stripShadowsOffVariants = true; + stripAdditionalLightOffVariants = true; + m_ForwardLights = new ForwardLights(); + + m_RenderOpaqueForwardPass = new DrawObjectsPass("Render Opaques", true, RenderPassEvent.BeforeRenderingOpaques + 1, RenderQueueRange.opaque, -1, StencilState.defaultValue, 0); + m_MainLightShadowCasterPass = new MainLightShadowCasterPass(RenderPassEvent.BeforeRenderingShadows); + m_AdditionalLightsShadowCasterPass = new AdditionalLightsShadowCasterPass(RenderPassEvent.BeforeRenderingShadows); } public override void Setup(ScriptableRenderContext context, ref RenderingData renderingData) @@ -21,6 +28,14 @@ public override void Setup(ScriptableRenderContext context, ref RenderingData re foreach (var feature in rendererFeatures) feature.AddRenderPasses(this, ref renderingData); EnqueuePass(m_RenderOpaqueForwardPass); + + bool mainLightShadows = m_MainLightShadowCasterPass.Setup(ref renderingData); + bool additionalLightShadows = m_AdditionalLightsShadowCasterPass.Setup(ref renderingData); + + if (mainLightShadows) + EnqueuePass(m_MainLightShadowCasterPass); + if (additionalLightShadows) + EnqueuePass(m_AdditionalLightsShadowCasterPass); } public override void SetupLights(ScriptableRenderContext context, ref RenderingData renderingData)