123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479 |
- using System;
- using UnityEngine.Experimental.Rendering;
- using UnityEngine.Rendering.RenderGraphModule;
- using System.Collections.Generic;
-
- namespace UnityEngine.Rendering.Universal.Internal
- {
- /// <summary>
- /// Renders a shadow map for the main Light.
- /// </summary>
- public class MainLightShadowCasterPass : ScriptableRenderPass
- {
- private static class MainLightShadowConstantBuffer
- {
- public static int _WorldToShadow;
- public static int _ShadowParams;
- public static int _CascadeShadowSplitSpheres0;
- public static int _CascadeShadowSplitSpheres1;
- public static int _CascadeShadowSplitSpheres2;
- public static int _CascadeShadowSplitSpheres3;
- public static int _CascadeShadowSplitSphereRadii;
- public static int _ShadowOffset0;
- public static int _ShadowOffset1;
- public static int _ShadowmapSize;
- }
-
- const int k_MaxCascades = 4;
- const int k_ShadowmapBufferBits = 16;
- float m_CascadeBorder;
- float m_MaxShadowDistanceSq;
- int m_ShadowCasterCascadesCount;
-
- int m_MainLightShadowmapID;
- internal RTHandle m_MainLightShadowmapTexture;
- private RTHandle m_EmptyMainLightShadowmapTexture;
- private const int k_EmptyShadowMapDimensions = 1;
- private const string k_MainLightShadowMapTextureName = "_MainLightShadowmapTexture";
- private const string k_EmptyMainLightShadowMapTextureName = "_EmptyMainLightShadowmapTexture";
- private static readonly Vector4 s_EmptyShadowParams = new Vector4(1, 0, 1, 0);
- private static readonly Vector4 s_EmptyShadowmapSize = s_EmptyShadowmapSize = new Vector4(k_EmptyShadowMapDimensions, 1f / k_EmptyShadowMapDimensions, k_EmptyShadowMapDimensions, k_EmptyShadowMapDimensions);
-
- Matrix4x4[] m_MainLightShadowMatrices;
- ShadowSliceData[] m_CascadeSlices;
- Vector4[] m_CascadeSplitDistances;
-
- bool m_CreateEmptyShadowmap;
- bool m_EmptyShadowmapNeedsClear = false;
-
- int renderTargetWidth;
- int renderTargetHeight;
-
- ProfilingSampler m_ProfilingSetupSampler = new ProfilingSampler("Setup Main Shadowmap");
- private PassData m_PassData;
- /// <summary>
- /// Creates a new <c>MainLightShadowCasterPass</c> instance.
- /// </summary>
- /// <param name="evt">The <c>RenderPassEvent</c> to use.</param>
- /// <seealso cref="RenderPassEvent"/>
- public MainLightShadowCasterPass(RenderPassEvent evt)
- {
- base.profilingSampler = new ProfilingSampler(nameof(MainLightShadowCasterPass));
- renderPassEvent = evt;
-
- m_PassData = new PassData();
- m_MainLightShadowMatrices = new Matrix4x4[k_MaxCascades + 1];
- m_CascadeSlices = new ShadowSliceData[k_MaxCascades];
- m_CascadeSplitDistances = new Vector4[k_MaxCascades];
-
- MainLightShadowConstantBuffer._WorldToShadow = Shader.PropertyToID("_MainLightWorldToShadow");
- MainLightShadowConstantBuffer._ShadowParams = Shader.PropertyToID("_MainLightShadowParams");
- MainLightShadowConstantBuffer._CascadeShadowSplitSpheres0 = Shader.PropertyToID("_CascadeShadowSplitSpheres0");
- MainLightShadowConstantBuffer._CascadeShadowSplitSpheres1 = Shader.PropertyToID("_CascadeShadowSplitSpheres1");
- MainLightShadowConstantBuffer._CascadeShadowSplitSpheres2 = Shader.PropertyToID("_CascadeShadowSplitSpheres2");
- MainLightShadowConstantBuffer._CascadeShadowSplitSpheres3 = Shader.PropertyToID("_CascadeShadowSplitSpheres3");
- MainLightShadowConstantBuffer._CascadeShadowSplitSphereRadii = Shader.PropertyToID("_CascadeShadowSplitSphereRadii");
- MainLightShadowConstantBuffer._ShadowOffset0 = Shader.PropertyToID("_MainLightShadowOffset0");
- MainLightShadowConstantBuffer._ShadowOffset1 = Shader.PropertyToID("_MainLightShadowOffset1");
- MainLightShadowConstantBuffer._ShadowmapSize = Shader.PropertyToID("_MainLightShadowmapSize");
-
- m_MainLightShadowmapID = Shader.PropertyToID(k_MainLightShadowMapTextureName);
- m_EmptyShadowmapNeedsClear = true;
- }
-
- /// <summary>
- /// Cleans up resources used by the pass.
- /// </summary>
- public void Dispose()
- {
- m_MainLightShadowmapTexture?.Release();
- m_EmptyMainLightShadowmapTexture?.Release();
- }
-
- /// <summary>
- /// Sets up the pass.
- /// </summary>
- /// <param name="renderingData"></param>
- /// <returns>True if the pass should be enqueued, otherwise false.</returns>
- /// <seealso cref="RenderingData"/>
- public bool Setup(ref RenderingData renderingData)
- {
- ContextContainer frameData = renderingData.frameData;
- UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
- UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
- UniversalLightData lightData = frameData.Get<UniversalLightData>();
- UniversalShadowData shadowData = frameData.Get<UniversalShadowData>();
- return Setup(universalRenderingData, cameraData, lightData, shadowData);
- }
-
- /// <summary>
- /// Sets up the pass.
- /// </summary>
- /// <param name="renderingData">Data containing rendering settings.</param>
- /// <param name="cameraData">Data containing camera settings.</param>
- /// <param name="lightData">Data containing light settings.</param>
- /// <param name="shadowData">Data containing shadow settings.</param>
- /// <returns>True if the pass should be enqueued, otherwise false.</returns>
- /// <seealso cref="RenderingData"/>
- public bool Setup(UniversalRenderingData renderingData, UniversalCameraData cameraData, UniversalLightData lightData, UniversalShadowData shadowData)
- {
- if (!shadowData.mainLightShadowsEnabled)
- return false;
-
- using var profScope = new ProfilingScope(m_ProfilingSetupSampler);
-
- if (!shadowData.supportsMainLightShadows)
- return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
-
- Clear();
- int shadowLightIndex = lightData.mainLightIndex;
- if (shadowLightIndex == -1)
- return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
-
- VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
- Light light = shadowLight.light;
- if (light.shadows == LightShadows.None)
- return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
-
- if (shadowLight.lightType != LightType.Directional)
- {
- Debug.LogWarning("Only directional lights are supported as main light.");
- }
-
- if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out Bounds _))
- return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
-
- m_ShadowCasterCascadesCount = shadowData.mainLightShadowCascadesCount;
- renderTargetWidth = shadowData.mainLightRenderTargetWidth;
- renderTargetHeight = shadowData.mainLightRenderTargetHeight;
-
- ref readonly URPLightShadowCullingInfos shadowCullingInfos = ref shadowData.visibleLightsShadowCullingInfos.UnsafeElementAt(shadowLightIndex);
-
- for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
- {
- ref readonly ShadowSliceData sliceData = ref shadowCullingInfos.slices.UnsafeElementAt(cascadeIndex);
- m_CascadeSplitDistances[cascadeIndex] = sliceData.splitData.cullingSphere;
- m_CascadeSlices[cascadeIndex] = sliceData;
-
- if (!shadowCullingInfos.IsSliceValid(cascadeIndex))
- return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
- }
-
- ShadowUtils.ShadowRTReAllocateIfNeeded(ref m_MainLightShadowmapTexture, renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits, name: k_MainLightShadowMapTextureName);
-
- m_MaxShadowDistanceSq = cameraData.maxShadowDistance * cameraData.maxShadowDistance;
- m_CascadeBorder = shadowData.mainLightShadowCascadeBorder;
- m_CreateEmptyShadowmap = false;
- useNativeRenderPass = true;
-
- return true;
- }
-
- bool SetupForEmptyRendering(bool stripShadowsOffVariants)
- {
- if (!stripShadowsOffVariants)
- return false;
-
- m_CreateEmptyShadowmap = true;
- useNativeRenderPass = false;
-
- // Required for scene view camera(URP renderer not initialized)
- if(ShadowUtils.ShadowRTReAllocateIfNeeded(ref m_EmptyMainLightShadowmapTexture, k_EmptyShadowMapDimensions, k_EmptyShadowMapDimensions, k_ShadowmapBufferBits, name: k_EmptyMainLightShadowMapTextureName))
- m_EmptyShadowmapNeedsClear = true;
-
- return true;
- }
-
- /// <inheritdoc />
- [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
- public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
- {
- if (m_CreateEmptyShadowmap && !m_EmptyShadowmapNeedsClear)
- return;
-
- // Disable obsolete warning for internal usage
- #pragma warning disable CS0618
- if (m_CreateEmptyShadowmap)
- {
- ConfigureTarget(m_EmptyMainLightShadowmapTexture);
- m_EmptyShadowmapNeedsClear = false;
- }
- else
- ConfigureTarget(m_MainLightShadowmapTexture);
-
- ConfigureClear(ClearFlag.All, Color.black);
- #pragma warning restore CS0618
- }
-
- /// <inheritdoc/>
- [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
- public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
- {
- ContextContainer frameData = renderingData.frameData;
- UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
- UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
- UniversalLightData lightData = frameData.Get<UniversalLightData>();
- UniversalShadowData shadowData = frameData.Get<UniversalShadowData>();
-
- if (m_CreateEmptyShadowmap)
- {
- SetEmptyMainLightCascadeShadowmap(CommandBufferHelpers.GetRasterCommandBuffer(universalRenderingData.commandBuffer));
- universalRenderingData.commandBuffer.SetGlobalTexture(m_MainLightShadowmapID, m_EmptyMainLightShadowmapTexture.nameID);
- return;
- }
-
- InitPassData(ref m_PassData, universalRenderingData, cameraData, lightData, shadowData);
- InitRendererLists(ref m_PassData, context, default(RenderGraph), false);
-
- RenderMainLightCascadeShadowmap(CommandBufferHelpers.GetRasterCommandBuffer(universalRenderingData.commandBuffer), ref m_PassData, false);
- universalRenderingData.commandBuffer.SetGlobalTexture(m_MainLightShadowmapID, m_MainLightShadowmapTexture.nameID);
- }
-
- void Clear()
- {
- for (int i = 0; i < m_MainLightShadowMatrices.Length; ++i)
- m_MainLightShadowMatrices[i] = Matrix4x4.identity;
-
- for (int i = 0; i < m_CascadeSplitDistances.Length; ++i)
- m_CascadeSplitDistances[i] = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
-
- for (int i = 0; i < m_CascadeSlices.Length; ++i)
- m_CascadeSlices[i].Clear();
- }
-
- void SetEmptyMainLightCascadeShadowmap(RasterCommandBuffer cmd)
- {
- cmd.EnableKeyword(ShaderGlobalKeywords.MainLightShadows);
- SetEmptyMainLightShadowParams(cmd);
- }
-
- internal static void SetEmptyMainLightShadowParams(RasterCommandBuffer cmd)
- {
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowParams, s_EmptyShadowParams);
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, s_EmptyShadowmapSize);
- }
-
- void RenderMainLightCascadeShadowmap(RasterCommandBuffer cmd, ref PassData data, bool isRenderGraph)
- {
- var lightData = data.lightData;
-
- int shadowLightIndex = lightData.mainLightIndex;
- if (shadowLightIndex == -1)
- return;
-
- VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
-
- using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.MainLightShadow)))
- {
- // Need to start by setting the Camera position and worldToCamera Matrix as that is not set for passes executed before normal rendering
- ShadowUtils.SetCameraPosition(cmd, data.cameraData.worldSpaceCameraPos);
-
- // For non-RG, need set the worldToCamera Matrix as that is not set for passes executed before normal rendering,
- // otherwise shadows will behave incorrectly when Scene and Game windows are open at the same time (UUM-63267).
- if (!isRenderGraph)
- ShadowUtils.SetWorldToCameraMatrix(cmd, data.cameraData.GetViewMatrix());
-
- for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
- {
- Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, data.shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
- ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
- cmd.SetKeyword(ShaderGlobalKeywords.CastingPunctualLightShadow, false);
- RendererList shadowRendererList = isRenderGraph? data.shadowRendererListsHandle[cascadeIndex] : data.shadowRendererLists[cascadeIndex];
- ShadowUtils.RenderShadowSlice(cmd, ref m_CascadeSlices[cascadeIndex], ref shadowRendererList, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
- }
-
- data.shadowData.isKeywordSoftShadowsEnabled = shadowLight.light.shadows == LightShadows.Soft && data.shadowData.supportsSoftShadows;
- cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadows, data.shadowData.mainLightShadowCascadesCount == 1);
- cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadowCascades, data.shadowData.mainLightShadowCascadesCount > 1);
- ShadowUtils.SetSoftShadowQualityShaderKeywords(cmd, data.shadowData);
-
- SetupMainLightShadowReceiverConstants(cmd, ref shadowLight, data.shadowData);
- }
- }
-
- void SetupMainLightShadowReceiverConstants(RasterCommandBuffer cmd, ref VisibleLight shadowLight, UniversalShadowData shadowData)
- {
- Light light = shadowLight.light;
- bool softShadows = shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows;
-
- int cascadeCount = m_ShadowCasterCascadesCount;
- for (int i = 0; i < cascadeCount; ++i)
- m_MainLightShadowMatrices[i] = m_CascadeSlices[i].shadowTransform;
-
- // We setup and additional a no-op WorldToShadow matrix in the last index
- // because the ComputeCascadeIndex function in Shadows.hlsl can return an index
- // out of bounds. (position not inside any cascade) and we want to avoid branching
- Matrix4x4 noOpShadowMatrix = Matrix4x4.zero;
- noOpShadowMatrix.m22 = (SystemInfo.usesReversedZBuffer) ? 1.0f : 0.0f;
- for (int i = cascadeCount; i <= k_MaxCascades; ++i)
- m_MainLightShadowMatrices[i] = noOpShadowMatrix;
-
- float invShadowAtlasWidth = 1.0f / renderTargetWidth;
- float invShadowAtlasHeight = 1.0f / renderTargetHeight;
- float invHalfShadowAtlasWidth = 0.5f * invShadowAtlasWidth;
- float invHalfShadowAtlasHeight = 0.5f * invShadowAtlasHeight;
- float softShadowsProp = ShadowUtils.SoftShadowQualityToShaderProperty(light, softShadows);
-
- ShadowUtils.GetScaleAndBiasForLinearDistanceFade(m_MaxShadowDistanceSq, m_CascadeBorder, out float shadowFadeScale, out float shadowFadeBias);
-
- cmd.SetGlobalMatrixArray(MainLightShadowConstantBuffer._WorldToShadow, m_MainLightShadowMatrices);
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowParams,
- new Vector4(light.shadowStrength, softShadowsProp, shadowFadeScale, shadowFadeBias));
-
- if (m_ShadowCasterCascadesCount > 1)
- {
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres0,
- m_CascadeSplitDistances[0]);
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres1,
- m_CascadeSplitDistances[1]);
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres2,
- m_CascadeSplitDistances[2]);
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres3,
- m_CascadeSplitDistances[3]);
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSphereRadii, new Vector4(
- m_CascadeSplitDistances[0].w * m_CascadeSplitDistances[0].w,
- m_CascadeSplitDistances[1].w * m_CascadeSplitDistances[1].w,
- m_CascadeSplitDistances[2].w * m_CascadeSplitDistances[2].w,
- m_CascadeSplitDistances[3].w * m_CascadeSplitDistances[3].w));
- }
-
- // Inside shader soft shadows are controlled through global keyword.
- // If any additional light has soft shadows it will force soft shadows on main light too.
- // As it is not trivial finding out which additional light has soft shadows, we will pass main light properties if soft shadows are supported.
- // This workaround will be removed once we will support soft shadows per light.
- if (shadowData.supportsSoftShadows)
- {
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset0,
- new Vector4(-invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight,
- invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight));
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset1,
- new Vector4(-invHalfShadowAtlasWidth, invHalfShadowAtlasHeight,
- invHalfShadowAtlasWidth, invHalfShadowAtlasHeight));
-
- cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowAtlasWidth,
- invShadowAtlasHeight,
- renderTargetWidth, renderTargetHeight));
- }
- }
-
- private class PassData
- {
- internal UniversalRenderingData renderingData;
- internal UniversalCameraData cameraData;
- internal UniversalLightData lightData;
- internal UniversalShadowData shadowData;
-
- internal MainLightShadowCasterPass pass;
-
- internal TextureHandle shadowmapTexture;
- internal int shadowmapID;
- internal bool emptyShadowmap;
-
- internal RendererListHandle[] shadowRendererListsHandle = new RendererListHandle[k_MaxCascades];
- internal RendererList[] shadowRendererLists = new RendererList[k_MaxCascades];
- }
-
- private void InitPassData(
- ref PassData passData,
- UniversalRenderingData renderingData,
- UniversalCameraData cameraData,
- UniversalLightData lightData,
- UniversalShadowData shadowData)
- {
- passData.pass = this;
-
- passData.emptyShadowmap = m_CreateEmptyShadowmap;
- passData.shadowmapID = m_MainLightShadowmapID;
- passData.renderingData = renderingData;
- passData.cameraData = cameraData;
- passData.lightData = lightData;
- passData.shadowData = shadowData;
- }
-
- void InitEmptyPassData(
- ref PassData passData,
- UniversalRenderingData renderingData,
- UniversalCameraData cameraData,
- UniversalLightData lightData,
- UniversalShadowData shadowData)
- {
- passData.pass = this;
-
- passData.emptyShadowmap = m_CreateEmptyShadowmap;
- passData.shadowmapID = m_MainLightShadowmapID;
- passData.renderingData = renderingData;
- passData.cameraData = cameraData;
- passData.lightData = lightData;
- passData.shadowData = shadowData;
- }
-
- private void InitRendererLists(ref PassData passData, ScriptableRenderContext context, RenderGraph renderGraph, bool useRenderGraph)
- {
- int shadowLightIndex = passData.lightData.mainLightIndex;
- if (!m_CreateEmptyShadowmap && shadowLightIndex != -1)
- {
- var settings = new ShadowDrawingSettings(passData.renderingData.cullResults, shadowLightIndex);
- settings.useRenderingLayerMaskTest = UniversalRenderPipeline.asset.useRenderingLayers;
- for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
- {
- if (useRenderGraph)
- passData.shadowRendererListsHandle[cascadeIndex] = renderGraph.CreateShadowRendererList(ref settings);
- else
- passData.shadowRendererLists[cascadeIndex] = context.CreateShadowRendererList(ref settings);
- }
- }
- }
-
- internal TextureHandle Render(RenderGraph graph, ContextContainer frameData)
- {
- UniversalRenderingData renderingData = frameData.Get<UniversalRenderingData>();
- UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
- UniversalLightData lightData = frameData.Get<UniversalLightData>();
- UniversalShadowData shadowData = frameData.Get<UniversalShadowData>();
-
- TextureHandle shadowTexture;
-
- using (var builder = graph.AddRasterRenderPass<PassData>("Draw Main Light Shadowmap", out var passData, base.profilingSampler))
- {
- InitPassData(ref passData, renderingData, cameraData, lightData, shadowData);
- InitRendererLists(ref passData, default(ScriptableRenderContext), graph, true);
-
- if (!m_CreateEmptyShadowmap)
- {
- for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
- {
- builder.UseRendererList(passData.shadowRendererListsHandle[cascadeIndex]);
- }
-
- shadowTexture = UniversalRenderer.CreateRenderGraphTexture(graph, m_MainLightShadowmapTexture.rt.descriptor, "_MainLightShadowmapTexture", true, ShadowUtils.m_ForceShadowPointSampling ? FilterMode.Point : FilterMode.Bilinear);
- builder.SetRenderAttachmentDepth(shadowTexture, AccessFlags.Write);
- }
- else
- {
- shadowTexture = graph.defaultResources.defaultShadowTexture;
- }
-
- // Need this as shadowmap is only used as Global Texture and not a buffer, so would get culled by RG
- builder.AllowPassCulling(false);
- builder.AllowGlobalStateModification(true);
-
- if (shadowTexture.IsValid())
- builder.SetGlobalTextureAfterPass(shadowTexture, m_MainLightShadowmapID);
-
- builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
- {
- if (!data.emptyShadowmap)
- {
- data.pass.RenderMainLightCascadeShadowmap(context.cmd, ref data, true);
- }
- else
- {
- data.pass.SetEmptyMainLightCascadeShadowmap(context.cmd);
- }
- });
- }
-
- return shadowTexture;
- }
- };
- }
|