설명 없음
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MainLightShadowCasterPass.cs 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479
  1. using System;
  2. using UnityEngine.Experimental.Rendering;
  3. using UnityEngine.Rendering.RenderGraphModule;
  4. using System.Collections.Generic;
  5. namespace UnityEngine.Rendering.Universal.Internal
  6. {
  7. /// <summary>
  8. /// Renders a shadow map for the main Light.
  9. /// </summary>
  10. public class MainLightShadowCasterPass : ScriptableRenderPass
  11. {
  12. private static class MainLightShadowConstantBuffer
  13. {
  14. public static int _WorldToShadow;
  15. public static int _ShadowParams;
  16. public static int _CascadeShadowSplitSpheres0;
  17. public static int _CascadeShadowSplitSpheres1;
  18. public static int _CascadeShadowSplitSpheres2;
  19. public static int _CascadeShadowSplitSpheres3;
  20. public static int _CascadeShadowSplitSphereRadii;
  21. public static int _ShadowOffset0;
  22. public static int _ShadowOffset1;
  23. public static int _ShadowmapSize;
  24. }
  25. const int k_MaxCascades = 4;
  26. const int k_ShadowmapBufferBits = 16;
  27. float m_CascadeBorder;
  28. float m_MaxShadowDistanceSq;
  29. int m_ShadowCasterCascadesCount;
  30. int m_MainLightShadowmapID;
  31. internal RTHandle m_MainLightShadowmapTexture;
  32. private RTHandle m_EmptyMainLightShadowmapTexture;
  33. private const int k_EmptyShadowMapDimensions = 1;
  34. private const string k_MainLightShadowMapTextureName = "_MainLightShadowmapTexture";
  35. private const string k_EmptyMainLightShadowMapTextureName = "_EmptyMainLightShadowmapTexture";
  36. private static readonly Vector4 s_EmptyShadowParams = new Vector4(1, 0, 1, 0);
  37. private static readonly Vector4 s_EmptyShadowmapSize = s_EmptyShadowmapSize = new Vector4(k_EmptyShadowMapDimensions, 1f / k_EmptyShadowMapDimensions, k_EmptyShadowMapDimensions, k_EmptyShadowMapDimensions);
  38. Matrix4x4[] m_MainLightShadowMatrices;
  39. ShadowSliceData[] m_CascadeSlices;
  40. Vector4[] m_CascadeSplitDistances;
  41. bool m_CreateEmptyShadowmap;
  42. bool m_EmptyShadowmapNeedsClear = false;
  43. int renderTargetWidth;
  44. int renderTargetHeight;
  45. ProfilingSampler m_ProfilingSetupSampler = new ProfilingSampler("Setup Main Shadowmap");
  46. private PassData m_PassData;
  47. /// <summary>
  48. /// Creates a new <c>MainLightShadowCasterPass</c> instance.
  49. /// </summary>
  50. /// <param name="evt">The <c>RenderPassEvent</c> to use.</param>
  51. /// <seealso cref="RenderPassEvent"/>
  52. public MainLightShadowCasterPass(RenderPassEvent evt)
  53. {
  54. base.profilingSampler = new ProfilingSampler(nameof(MainLightShadowCasterPass));
  55. renderPassEvent = evt;
  56. m_PassData = new PassData();
  57. m_MainLightShadowMatrices = new Matrix4x4[k_MaxCascades + 1];
  58. m_CascadeSlices = new ShadowSliceData[k_MaxCascades];
  59. m_CascadeSplitDistances = new Vector4[k_MaxCascades];
  60. MainLightShadowConstantBuffer._WorldToShadow = Shader.PropertyToID("_MainLightWorldToShadow");
  61. MainLightShadowConstantBuffer._ShadowParams = Shader.PropertyToID("_MainLightShadowParams");
  62. MainLightShadowConstantBuffer._CascadeShadowSplitSpheres0 = Shader.PropertyToID("_CascadeShadowSplitSpheres0");
  63. MainLightShadowConstantBuffer._CascadeShadowSplitSpheres1 = Shader.PropertyToID("_CascadeShadowSplitSpheres1");
  64. MainLightShadowConstantBuffer._CascadeShadowSplitSpheres2 = Shader.PropertyToID("_CascadeShadowSplitSpheres2");
  65. MainLightShadowConstantBuffer._CascadeShadowSplitSpheres3 = Shader.PropertyToID("_CascadeShadowSplitSpheres3");
  66. MainLightShadowConstantBuffer._CascadeShadowSplitSphereRadii = Shader.PropertyToID("_CascadeShadowSplitSphereRadii");
  67. MainLightShadowConstantBuffer._ShadowOffset0 = Shader.PropertyToID("_MainLightShadowOffset0");
  68. MainLightShadowConstantBuffer._ShadowOffset1 = Shader.PropertyToID("_MainLightShadowOffset1");
  69. MainLightShadowConstantBuffer._ShadowmapSize = Shader.PropertyToID("_MainLightShadowmapSize");
  70. m_MainLightShadowmapID = Shader.PropertyToID(k_MainLightShadowMapTextureName);
  71. m_EmptyShadowmapNeedsClear = true;
  72. }
  73. /// <summary>
  74. /// Cleans up resources used by the pass.
  75. /// </summary>
  76. public void Dispose()
  77. {
  78. m_MainLightShadowmapTexture?.Release();
  79. m_EmptyMainLightShadowmapTexture?.Release();
  80. }
  81. /// <summary>
  82. /// Sets up the pass.
  83. /// </summary>
  84. /// <param name="renderingData"></param>
  85. /// <returns>True if the pass should be enqueued, otherwise false.</returns>
  86. /// <seealso cref="RenderingData"/>
  87. public bool Setup(ref RenderingData renderingData)
  88. {
  89. ContextContainer frameData = renderingData.frameData;
  90. UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
  91. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  92. UniversalLightData lightData = frameData.Get<UniversalLightData>();
  93. UniversalShadowData shadowData = frameData.Get<UniversalShadowData>();
  94. return Setup(universalRenderingData, cameraData, lightData, shadowData);
  95. }
  96. /// <summary>
  97. /// Sets up the pass.
  98. /// </summary>
  99. /// <param name="renderingData">Data containing rendering settings.</param>
  100. /// <param name="cameraData">Data containing camera settings.</param>
  101. /// <param name="lightData">Data containing light settings.</param>
  102. /// <param name="shadowData">Data containing shadow settings.</param>
  103. /// <returns>True if the pass should be enqueued, otherwise false.</returns>
  104. /// <seealso cref="RenderingData"/>
  105. public bool Setup(UniversalRenderingData renderingData, UniversalCameraData cameraData, UniversalLightData lightData, UniversalShadowData shadowData)
  106. {
  107. if (!shadowData.mainLightShadowsEnabled)
  108. return false;
  109. using var profScope = new ProfilingScope(m_ProfilingSetupSampler);
  110. if (!shadowData.supportsMainLightShadows)
  111. return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
  112. Clear();
  113. int shadowLightIndex = lightData.mainLightIndex;
  114. if (shadowLightIndex == -1)
  115. return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
  116. VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
  117. Light light = shadowLight.light;
  118. if (light.shadows == LightShadows.None)
  119. return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
  120. if (shadowLight.lightType != LightType.Directional)
  121. {
  122. Debug.LogWarning("Only directional lights are supported as main light.");
  123. }
  124. if (!renderingData.cullResults.GetShadowCasterBounds(shadowLightIndex, out Bounds _))
  125. return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
  126. m_ShadowCasterCascadesCount = shadowData.mainLightShadowCascadesCount;
  127. renderTargetWidth = shadowData.mainLightRenderTargetWidth;
  128. renderTargetHeight = shadowData.mainLightRenderTargetHeight;
  129. ref readonly URPLightShadowCullingInfos shadowCullingInfos = ref shadowData.visibleLightsShadowCullingInfos.UnsafeElementAt(shadowLightIndex);
  130. for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
  131. {
  132. ref readonly ShadowSliceData sliceData = ref shadowCullingInfos.slices.UnsafeElementAt(cascadeIndex);
  133. m_CascadeSplitDistances[cascadeIndex] = sliceData.splitData.cullingSphere;
  134. m_CascadeSlices[cascadeIndex] = sliceData;
  135. if (!shadowCullingInfos.IsSliceValid(cascadeIndex))
  136. return SetupForEmptyRendering(cameraData.renderer.stripShadowsOffVariants);
  137. }
  138. ShadowUtils.ShadowRTReAllocateIfNeeded(ref m_MainLightShadowmapTexture, renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits, name: k_MainLightShadowMapTextureName);
  139. m_MaxShadowDistanceSq = cameraData.maxShadowDistance * cameraData.maxShadowDistance;
  140. m_CascadeBorder = shadowData.mainLightShadowCascadeBorder;
  141. m_CreateEmptyShadowmap = false;
  142. useNativeRenderPass = true;
  143. return true;
  144. }
  145. bool SetupForEmptyRendering(bool stripShadowsOffVariants)
  146. {
  147. if (!stripShadowsOffVariants)
  148. return false;
  149. m_CreateEmptyShadowmap = true;
  150. useNativeRenderPass = false;
  151. // Required for scene view camera(URP renderer not initialized)
  152. if(ShadowUtils.ShadowRTReAllocateIfNeeded(ref m_EmptyMainLightShadowmapTexture, k_EmptyShadowMapDimensions, k_EmptyShadowMapDimensions, k_ShadowmapBufferBits, name: k_EmptyMainLightShadowMapTextureName))
  153. m_EmptyShadowmapNeedsClear = true;
  154. return true;
  155. }
  156. /// <inheritdoc />
  157. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  158. public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
  159. {
  160. if (m_CreateEmptyShadowmap && !m_EmptyShadowmapNeedsClear)
  161. return;
  162. // Disable obsolete warning for internal usage
  163. #pragma warning disable CS0618
  164. if (m_CreateEmptyShadowmap)
  165. {
  166. ConfigureTarget(m_EmptyMainLightShadowmapTexture);
  167. m_EmptyShadowmapNeedsClear = false;
  168. }
  169. else
  170. ConfigureTarget(m_MainLightShadowmapTexture);
  171. ConfigureClear(ClearFlag.All, Color.black);
  172. #pragma warning restore CS0618
  173. }
  174. /// <inheritdoc/>
  175. [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
  176. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  177. {
  178. ContextContainer frameData = renderingData.frameData;
  179. UniversalRenderingData universalRenderingData = frameData.Get<UniversalRenderingData>();
  180. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  181. UniversalLightData lightData = frameData.Get<UniversalLightData>();
  182. UniversalShadowData shadowData = frameData.Get<UniversalShadowData>();
  183. if (m_CreateEmptyShadowmap)
  184. {
  185. SetEmptyMainLightCascadeShadowmap(CommandBufferHelpers.GetRasterCommandBuffer(universalRenderingData.commandBuffer));
  186. universalRenderingData.commandBuffer.SetGlobalTexture(m_MainLightShadowmapID, m_EmptyMainLightShadowmapTexture.nameID);
  187. return;
  188. }
  189. InitPassData(ref m_PassData, universalRenderingData, cameraData, lightData, shadowData);
  190. InitRendererLists(ref m_PassData, context, default(RenderGraph), false);
  191. RenderMainLightCascadeShadowmap(CommandBufferHelpers.GetRasterCommandBuffer(universalRenderingData.commandBuffer), ref m_PassData, false);
  192. universalRenderingData.commandBuffer.SetGlobalTexture(m_MainLightShadowmapID, m_MainLightShadowmapTexture.nameID);
  193. }
  194. void Clear()
  195. {
  196. for (int i = 0; i < m_MainLightShadowMatrices.Length; ++i)
  197. m_MainLightShadowMatrices[i] = Matrix4x4.identity;
  198. for (int i = 0; i < m_CascadeSplitDistances.Length; ++i)
  199. m_CascadeSplitDistances[i] = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
  200. for (int i = 0; i < m_CascadeSlices.Length; ++i)
  201. m_CascadeSlices[i].Clear();
  202. }
  203. void SetEmptyMainLightCascadeShadowmap(RasterCommandBuffer cmd)
  204. {
  205. cmd.EnableKeyword(ShaderGlobalKeywords.MainLightShadows);
  206. SetEmptyMainLightShadowParams(cmd);
  207. }
  208. internal static void SetEmptyMainLightShadowParams(RasterCommandBuffer cmd)
  209. {
  210. cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowParams, s_EmptyShadowParams);
  211. cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, s_EmptyShadowmapSize);
  212. }
  213. void RenderMainLightCascadeShadowmap(RasterCommandBuffer cmd, ref PassData data, bool isRenderGraph)
  214. {
  215. var lightData = data.lightData;
  216. int shadowLightIndex = lightData.mainLightIndex;
  217. if (shadowLightIndex == -1)
  218. return;
  219. VisibleLight shadowLight = lightData.visibleLights[shadowLightIndex];
  220. using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.MainLightShadow)))
  221. {
  222. // Need to start by setting the Camera position and worldToCamera Matrix as that is not set for passes executed before normal rendering
  223. ShadowUtils.SetCameraPosition(cmd, data.cameraData.worldSpaceCameraPos);
  224. // For non-RG, need set the worldToCamera Matrix as that is not set for passes executed before normal rendering,
  225. // otherwise shadows will behave incorrectly when Scene and Game windows are open at the same time (UUM-63267).
  226. if (!isRenderGraph)
  227. ShadowUtils.SetWorldToCameraMatrix(cmd, data.cameraData.GetViewMatrix());
  228. for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
  229. {
  230. Vector4 shadowBias = ShadowUtils.GetShadowBias(ref shadowLight, shadowLightIndex, data.shadowData, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].resolution);
  231. ShadowUtils.SetupShadowCasterConstantBuffer(cmd, ref shadowLight, shadowBias);
  232. cmd.SetKeyword(ShaderGlobalKeywords.CastingPunctualLightShadow, false);
  233. RendererList shadowRendererList = isRenderGraph? data.shadowRendererListsHandle[cascadeIndex] : data.shadowRendererLists[cascadeIndex];
  234. ShadowUtils.RenderShadowSlice(cmd, ref m_CascadeSlices[cascadeIndex], ref shadowRendererList, m_CascadeSlices[cascadeIndex].projectionMatrix, m_CascadeSlices[cascadeIndex].viewMatrix);
  235. }
  236. data.shadowData.isKeywordSoftShadowsEnabled = shadowLight.light.shadows == LightShadows.Soft && data.shadowData.supportsSoftShadows;
  237. cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadows, data.shadowData.mainLightShadowCascadesCount == 1);
  238. cmd.SetKeyword(ShaderGlobalKeywords.MainLightShadowCascades, data.shadowData.mainLightShadowCascadesCount > 1);
  239. ShadowUtils.SetSoftShadowQualityShaderKeywords(cmd, data.shadowData);
  240. SetupMainLightShadowReceiverConstants(cmd, ref shadowLight, data.shadowData);
  241. }
  242. }
  243. void SetupMainLightShadowReceiverConstants(RasterCommandBuffer cmd, ref VisibleLight shadowLight, UniversalShadowData shadowData)
  244. {
  245. Light light = shadowLight.light;
  246. bool softShadows = shadowLight.light.shadows == LightShadows.Soft && shadowData.supportsSoftShadows;
  247. int cascadeCount = m_ShadowCasterCascadesCount;
  248. for (int i = 0; i < cascadeCount; ++i)
  249. m_MainLightShadowMatrices[i] = m_CascadeSlices[i].shadowTransform;
  250. // We setup and additional a no-op WorldToShadow matrix in the last index
  251. // because the ComputeCascadeIndex function in Shadows.hlsl can return an index
  252. // out of bounds. (position not inside any cascade) and we want to avoid branching
  253. Matrix4x4 noOpShadowMatrix = Matrix4x4.zero;
  254. noOpShadowMatrix.m22 = (SystemInfo.usesReversedZBuffer) ? 1.0f : 0.0f;
  255. for (int i = cascadeCount; i <= k_MaxCascades; ++i)
  256. m_MainLightShadowMatrices[i] = noOpShadowMatrix;
  257. float invShadowAtlasWidth = 1.0f / renderTargetWidth;
  258. float invShadowAtlasHeight = 1.0f / renderTargetHeight;
  259. float invHalfShadowAtlasWidth = 0.5f * invShadowAtlasWidth;
  260. float invHalfShadowAtlasHeight = 0.5f * invShadowAtlasHeight;
  261. float softShadowsProp = ShadowUtils.SoftShadowQualityToShaderProperty(light, softShadows);
  262. ShadowUtils.GetScaleAndBiasForLinearDistanceFade(m_MaxShadowDistanceSq, m_CascadeBorder, out float shadowFadeScale, out float shadowFadeBias);
  263. cmd.SetGlobalMatrixArray(MainLightShadowConstantBuffer._WorldToShadow, m_MainLightShadowMatrices);
  264. cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowParams,
  265. new Vector4(light.shadowStrength, softShadowsProp, shadowFadeScale, shadowFadeBias));
  266. if (m_ShadowCasterCascadesCount > 1)
  267. {
  268. cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres0,
  269. m_CascadeSplitDistances[0]);
  270. cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres1,
  271. m_CascadeSplitDistances[1]);
  272. cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres2,
  273. m_CascadeSplitDistances[2]);
  274. cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSpheres3,
  275. m_CascadeSplitDistances[3]);
  276. cmd.SetGlobalVector(MainLightShadowConstantBuffer._CascadeShadowSplitSphereRadii, new Vector4(
  277. m_CascadeSplitDistances[0].w * m_CascadeSplitDistances[0].w,
  278. m_CascadeSplitDistances[1].w * m_CascadeSplitDistances[1].w,
  279. m_CascadeSplitDistances[2].w * m_CascadeSplitDistances[2].w,
  280. m_CascadeSplitDistances[3].w * m_CascadeSplitDistances[3].w));
  281. }
  282. // Inside shader soft shadows are controlled through global keyword.
  283. // If any additional light has soft shadows it will force soft shadows on main light too.
  284. // As it is not trivial finding out which additional light has soft shadows, we will pass main light properties if soft shadows are supported.
  285. // This workaround will be removed once we will support soft shadows per light.
  286. if (shadowData.supportsSoftShadows)
  287. {
  288. cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset0,
  289. new Vector4(-invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight,
  290. invHalfShadowAtlasWidth, -invHalfShadowAtlasHeight));
  291. cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowOffset1,
  292. new Vector4(-invHalfShadowAtlasWidth, invHalfShadowAtlasHeight,
  293. invHalfShadowAtlasWidth, invHalfShadowAtlasHeight));
  294. cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowAtlasWidth,
  295. invShadowAtlasHeight,
  296. renderTargetWidth, renderTargetHeight));
  297. }
  298. }
  299. private class PassData
  300. {
  301. internal UniversalRenderingData renderingData;
  302. internal UniversalCameraData cameraData;
  303. internal UniversalLightData lightData;
  304. internal UniversalShadowData shadowData;
  305. internal MainLightShadowCasterPass pass;
  306. internal TextureHandle shadowmapTexture;
  307. internal int shadowmapID;
  308. internal bool emptyShadowmap;
  309. internal RendererListHandle[] shadowRendererListsHandle = new RendererListHandle[k_MaxCascades];
  310. internal RendererList[] shadowRendererLists = new RendererList[k_MaxCascades];
  311. }
  312. private void InitPassData(
  313. ref PassData passData,
  314. UniversalRenderingData renderingData,
  315. UniversalCameraData cameraData,
  316. UniversalLightData lightData,
  317. UniversalShadowData shadowData)
  318. {
  319. passData.pass = this;
  320. passData.emptyShadowmap = m_CreateEmptyShadowmap;
  321. passData.shadowmapID = m_MainLightShadowmapID;
  322. passData.renderingData = renderingData;
  323. passData.cameraData = cameraData;
  324. passData.lightData = lightData;
  325. passData.shadowData = shadowData;
  326. }
  327. void InitEmptyPassData(
  328. ref PassData passData,
  329. UniversalRenderingData renderingData,
  330. UniversalCameraData cameraData,
  331. UniversalLightData lightData,
  332. UniversalShadowData shadowData)
  333. {
  334. passData.pass = this;
  335. passData.emptyShadowmap = m_CreateEmptyShadowmap;
  336. passData.shadowmapID = m_MainLightShadowmapID;
  337. passData.renderingData = renderingData;
  338. passData.cameraData = cameraData;
  339. passData.lightData = lightData;
  340. passData.shadowData = shadowData;
  341. }
  342. private void InitRendererLists(ref PassData passData, ScriptableRenderContext context, RenderGraph renderGraph, bool useRenderGraph)
  343. {
  344. int shadowLightIndex = passData.lightData.mainLightIndex;
  345. if (!m_CreateEmptyShadowmap && shadowLightIndex != -1)
  346. {
  347. var settings = new ShadowDrawingSettings(passData.renderingData.cullResults, shadowLightIndex);
  348. settings.useRenderingLayerMaskTest = UniversalRenderPipeline.asset.useRenderingLayers;
  349. for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
  350. {
  351. if (useRenderGraph)
  352. passData.shadowRendererListsHandle[cascadeIndex] = renderGraph.CreateShadowRendererList(ref settings);
  353. else
  354. passData.shadowRendererLists[cascadeIndex] = context.CreateShadowRendererList(ref settings);
  355. }
  356. }
  357. }
  358. internal TextureHandle Render(RenderGraph graph, ContextContainer frameData)
  359. {
  360. UniversalRenderingData renderingData = frameData.Get<UniversalRenderingData>();
  361. UniversalCameraData cameraData = frameData.Get<UniversalCameraData>();
  362. UniversalLightData lightData = frameData.Get<UniversalLightData>();
  363. UniversalShadowData shadowData = frameData.Get<UniversalShadowData>();
  364. TextureHandle shadowTexture;
  365. using (var builder = graph.AddRasterRenderPass<PassData>("Draw Main Light Shadowmap", out var passData, base.profilingSampler))
  366. {
  367. InitPassData(ref passData, renderingData, cameraData, lightData, shadowData);
  368. InitRendererLists(ref passData, default(ScriptableRenderContext), graph, true);
  369. if (!m_CreateEmptyShadowmap)
  370. {
  371. for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
  372. {
  373. builder.UseRendererList(passData.shadowRendererListsHandle[cascadeIndex]);
  374. }
  375. shadowTexture = UniversalRenderer.CreateRenderGraphTexture(graph, m_MainLightShadowmapTexture.rt.descriptor, "_MainLightShadowmapTexture", true, ShadowUtils.m_ForceShadowPointSampling ? FilterMode.Point : FilterMode.Bilinear);
  376. builder.SetRenderAttachmentDepth(shadowTexture, AccessFlags.Write);
  377. }
  378. else
  379. {
  380. shadowTexture = graph.defaultResources.defaultShadowTexture;
  381. }
  382. // Need this as shadowmap is only used as Global Texture and not a buffer, so would get culled by RG
  383. builder.AllowPassCulling(false);
  384. builder.AllowGlobalStateModification(true);
  385. if (shadowTexture.IsValid())
  386. builder.SetGlobalTextureAfterPass(shadowTexture, m_MainLightShadowmapID);
  387. builder.SetRenderFunc((PassData data, RasterGraphContext context) =>
  388. {
  389. if (!data.emptyShadowmap)
  390. {
  391. data.pass.RenderMainLightCascadeShadowmap(context.cmd, ref data, true);
  392. }
  393. else
  394. {
  395. data.pass.SetEmptyMainLightCascadeShadowmap(context.cmd);
  396. }
  397. });
  398. }
  399. return shadowTexture;
  400. }
  401. };
  402. }