123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- using System;
- using System.Collections.Generic;
- using UnityEngine.Profiling;
- using UnityEngine.Experimental.Rendering;
-
- namespace UnityEngine.Rendering.Universal
- {
- internal class Render2DLightingPass : ScriptableRenderPass, IRenderPass2D
- {
- private static readonly int k_HDREmulationScaleID = Shader.PropertyToID("_HDREmulationScale");
- private static readonly int k_InverseHDREmulationScaleID = Shader.PropertyToID("_InverseHDREmulationScale");
- private static readonly int k_RendererColorID = Shader.PropertyToID("_RendererColor");
- private static readonly int k_LightLookupID = Shader.PropertyToID("_LightLookup");
- private static readonly int k_FalloffLookupID = Shader.PropertyToID("_FalloffLookup");
-
- private static readonly int[] k_ShapeLightTextureIDs =
- {
- Shader.PropertyToID("_ShapeLightTexture0"),
- Shader.PropertyToID("_ShapeLightTexture1"),
- Shader.PropertyToID("_ShapeLightTexture2"),
- Shader.PropertyToID("_ShapeLightTexture3")
- };
-
- private static readonly ShaderTagId k_CombinedRenderingPassName = new ShaderTagId("Universal2D");
- private static readonly ShaderTagId k_NormalsRenderingPassName = new ShaderTagId("NormalsRendering");
- private static readonly ShaderTagId k_LegacyPassName = new ShaderTagId("SRPDefaultUnlit");
- private static readonly List<ShaderTagId> k_ShaderTags = new List<ShaderTagId>() { k_LegacyPassName, k_CombinedRenderingPassName };
-
- private static readonly ProfilingSampler m_ProfilingDrawLights = new ProfilingSampler("Draw 2D Lights");
- private static readonly ProfilingSampler m_ProfilingDrawLightTextures = new ProfilingSampler("Draw 2D Lights Textures");
- private static readonly ProfilingSampler m_ProfilingDrawRenderers = new ProfilingSampler("Draw All Renderers");
- private static readonly ProfilingSampler m_ProfilingDrawLayerBatch = new ProfilingSampler("Draw Layer Batch");
- private static readonly ProfilingSampler m_ProfilingSamplerUnlit = new ProfilingSampler("Render Unlit");
-
- Material m_BlitMaterial;
- Material m_SamplingMaterial;
-
- private readonly Renderer2DData m_Renderer2DData;
- private readonly Texture2D m_FallOffLookup;
- private bool m_NeedsDepth;
- private short m_CameraSortingLayerBoundsIndex;
-
- public Render2DLightingPass(Renderer2DData rendererData, Material blitMaterial, Material samplingMaterial, Texture2D fallOffLookup)
- {
- m_Renderer2DData = rendererData;
- m_BlitMaterial = blitMaterial;
- m_SamplingMaterial = samplingMaterial;
- m_FallOffLookup = fallOffLookup;
-
- m_CameraSortingLayerBoundsIndex = GetCameraSortingLayerBoundsIndex(m_Renderer2DData);
- }
-
- internal void Setup(bool useDepth)
- {
- m_NeedsDepth = useDepth;
- }
-
- private void CopyCameraSortingLayerRenderTexture(ScriptableRenderContext context, RenderingData renderingData, RenderBufferStoreAction mainTargetStoreAction)
- {
- var cmd = renderingData.commandBuffer;
-
- this.CreateCameraSortingLayerRenderTexture(renderingData, cmd, m_Renderer2DData.cameraSortingLayerDownsamplingMethod);
-
- Material copyMaterial = m_SamplingMaterial;
- int passIndex = 0;
- if (m_Renderer2DData.cameraSortingLayerDownsamplingMethod != Downsampling._4xBox)
- {
- copyMaterial = m_BlitMaterial;
- passIndex = colorAttachmentHandle.rt.filterMode == FilterMode.Bilinear ? 1 : 0;
- }
-
- Blitter.BlitCameraTexture(cmd, colorAttachmentHandle, m_Renderer2DData.cameraSortingLayerRenderTarget, RenderBufferLoadAction.DontCare, RenderBufferStoreAction.Store, copyMaterial, passIndex);
- CoreUtils.SetRenderTarget(cmd,
- colorAttachmentHandle, RenderBufferLoadAction.Load, mainTargetStoreAction,
- depthAttachmentHandle, RenderBufferLoadAction.Load, mainTargetStoreAction,
- ClearFlag.None, Color.clear);
- cmd.SetGlobalTexture(m_Renderer2DData.cameraSortingLayerRenderTarget.name, m_Renderer2DData.cameraSortingLayerRenderTarget.nameID);
- context.ExecuteCommandBuffer(cmd);
- cmd.Clear();
- }
-
- public static short GetCameraSortingLayerBoundsIndex(Renderer2DData rendererData)
- {
- SortingLayer[] sortingLayers = Light2DManager.GetCachedSortingLayer();
- for (short i = 0; i < sortingLayers.Length; i++)
- {
- if (sortingLayers[i].id == rendererData.cameraSortingLayerTextureBound)
- return (short)sortingLayers[i].value;
- }
-
- return short.MinValue;
- }
-
- private void DetermineWhenToResolve(int startIndex, int batchesDrawn, int batchCount, LayerBatch[] layerBatches,
- out int resolveDuringBatch, out bool resolveIsAfterCopy)
- {
- bool anyLightWithVolumetricShadows = false;
- var lights = m_Renderer2DData.lightCullResult.visibleLights;
- for (int i = 0; i < lights.Count; i++)
- {
- anyLightWithVolumetricShadows = lights[i].renderVolumetricShadows;
- if (anyLightWithVolumetricShadows)
- break;
- }
-
- var lastVolumetricLightBatch = -1;
- if (anyLightWithVolumetricShadows)
- {
- for (int i = startIndex + batchesDrawn - 1; i >= startIndex; i--)
- {
- if (layerBatches[i].lightStats.totalVolumetricUsage > 0)
- {
- lastVolumetricLightBatch = i;
- break;
- }
- }
- }
-
- if (m_Renderer2DData.useCameraSortingLayerTexture)
- {
- var cameraSortingLayerBoundsIndex = GetCameraSortingLayerBoundsIndex(m_Renderer2DData);
- var copyBatch = -1;
- for (int i = startIndex; i < startIndex + batchesDrawn; i++)
- {
- var layerBatch = layerBatches[i];
- if (cameraSortingLayerBoundsIndex >= layerBatch.layerRange.lowerBound && cameraSortingLayerBoundsIndex <= layerBatch.layerRange.upperBound)
- {
- copyBatch = i;
- break;
- }
- }
-
- resolveIsAfterCopy = copyBatch > lastVolumetricLightBatch;
- resolveDuringBatch = resolveIsAfterCopy ? copyBatch : lastVolumetricLightBatch;
- }
- else
- {
- resolveDuringBatch = lastVolumetricLightBatch;
- resolveIsAfterCopy = false;
- }
- }
-
- private void Render(ScriptableRenderContext context, CommandBuffer cmd, ref RenderingData renderingData, ref FilteringSettings filterSettings, DrawingSettings drawSettings)
- {
- UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
- var activeDebugHandler = GetActiveDebugHandler(cameraData);
- if (activeDebugHandler != null)
- {
- UniversalRenderingData universalRenderingData = renderingData.universalRenderingData;
- RenderStateBlock renderStateBlock = new RenderStateBlock();
- var debugRendererLists = activeDebugHandler.CreateRendererListsWithDebugRenderState(context,
- ref universalRenderingData.cullResults, ref drawSettings, ref filterSettings, ref renderStateBlock);
- debugRendererLists.DrawWithRendererList(CommandBufferHelpers.GetRasterCommandBuffer(renderingData.commandBuffer));
- }
- else
- {
- var param = new RendererListParams(renderingData.cullResults, drawSettings, filterSettings);
- var rl = context.CreateRendererList(ref param);
- cmd.DrawRendererList(rl);
- }
- }
-
- private int DrawLayerBatches(
- LayerBatch[] layerBatches,
- int batchCount,
- int startIndex,
- CommandBuffer cmd,
- ScriptableRenderContext context,
- ref RenderingData renderingData,
- ref FilteringSettings filterSettings,
- ref DrawingSettings normalsDrawSettings,
- ref DrawingSettings drawSettings,
- ref RenderTextureDescriptor desc)
- {
- UniversalCameraData cameraData = renderingData.frameData.Get<UniversalCameraData>();
-
- var debugHandler = GetActiveDebugHandler(cameraData);
- bool drawLights = debugHandler?.IsLightingActive ?? true;
- var batchesDrawn = 0;
- var rtCount = 0U;
-
- // Account for Sprite Mask and normal map usage where the first and last layer has to render the stencil pass
- bool normalsFirstClear = true;
-
- // Draw lights
- using (new ProfilingScope(cmd, m_ProfilingDrawLights))
- {
- for (var i = startIndex; i < batchCount; ++i)
- {
- ref var layerBatch = ref layerBatches[i];
-
- var blendStyleMask = layerBatch.lightStats.blendStylesUsed;
- var blendStyleCount = 0U;
- while (blendStyleMask > 0)
- {
- blendStyleCount += blendStyleMask & 1;
- blendStyleMask >>= 1;
- }
-
- rtCount += blendStyleCount;
-
- if (rtCount > LayerUtility.maxTextureCount)
- break;
-
- batchesDrawn++;
-
- if (layerBatch.lightStats.totalNormalMapUsage > 0)
- {
- filterSettings.sortingLayerRange = layerBatch.layerRange;
- var depthTarget = m_NeedsDepth ? depthAttachmentHandle : null;
- this.RenderNormals(context, renderingData, normalsDrawSettings, filterSettings, depthTarget, ref normalsFirstClear);
- }
-
- using (new ProfilingScope(cmd, m_ProfilingDrawLightTextures))
- {
- this.RenderLights(renderingData, cmd, ref layerBatch, ref desc);
- }
- }
- }
-
- // Determine when to resolve in case we use MSAA
- var msaaEnabled = renderingData.cameraData.cameraTargetDescriptor.msaaSamples > 1;
- var isFinalBatchSet = startIndex + batchesDrawn >= batchCount;
- var resolveDuringBatch = -1;
- var resolveIsAfterCopy = false;
- if (msaaEnabled && isFinalBatchSet)
- DetermineWhenToResolve(startIndex, batchesDrawn, batchCount, layerBatches, out resolveDuringBatch, out resolveIsAfterCopy);
-
-
- // Draw renderers
- var blendStylesCount = m_Renderer2DData.lightBlendStyles.Length;
- using (new ProfilingScope(cmd, m_ProfilingDrawRenderers))
- {
- RenderBufferStoreAction initialStoreAction;
- if (msaaEnabled)
- initialStoreAction = resolveDuringBatch < startIndex ? RenderBufferStoreAction.Resolve : RenderBufferStoreAction.StoreAndResolve;
- else
- initialStoreAction = RenderBufferStoreAction.Store;
- CoreUtils.SetRenderTarget(cmd,
- colorAttachmentHandle, RenderBufferLoadAction.Load, initialStoreAction,
- depthAttachmentHandle, RenderBufferLoadAction.Load, initialStoreAction,
- ClearFlag.None, Color.clear);
-
- for (var i = startIndex; i < startIndex + batchesDrawn; i++)
- {
- using (new ProfilingScope(cmd, m_ProfilingDrawLayerBatch))
- {
- // This is a local copy of the array element (it's a struct). Remember to add a ref here if you need to modify the real thing.
- var layerBatch = layerBatches[i];
-
- if (layerBatch.lightStats.useAnyLights)
- {
- for (var blendStyleIndex = 0; blendStyleIndex < blendStylesCount; blendStyleIndex++)
- {
- var blendStyleMask = (uint)(1 << blendStyleIndex);
- var blendStyleUsed = (layerBatch.lightStats.blendStylesUsed & blendStyleMask) > 0;
-
- if (blendStyleUsed)
- {
- var identifier = layerBatch.GetRTId(cmd, desc, blendStyleIndex);
- cmd.SetGlobalTexture(k_ShapeLightTextureIDs[blendStyleIndex], identifier);
- }
-
- RendererLighting.EnableBlendStyle(CommandBufferHelpers.GetRasterCommandBuffer(cmd), blendStyleIndex, blendStyleUsed);
- }
- }
- else
- {
- for (var blendStyleIndex = 0; blendStyleIndex < k_ShapeLightTextureIDs.Length; blendStyleIndex++)
- {
- cmd.SetGlobalTexture(k_ShapeLightTextureIDs[blendStyleIndex], Texture2D.blackTexture);
- RendererLighting.EnableBlendStyle(CommandBufferHelpers.GetRasterCommandBuffer(cmd), blendStyleIndex, blendStyleIndex == 0);
- }
- }
-
- context.ExecuteCommandBuffer(cmd);
- cmd.Clear();
-
- short cameraSortingLayerBoundsIndex = GetCameraSortingLayerBoundsIndex(m_Renderer2DData);
-
- RenderBufferStoreAction copyStoreAction;
- if (msaaEnabled)
- copyStoreAction = resolveDuringBatch == i && resolveIsAfterCopy ? RenderBufferStoreAction.Resolve : RenderBufferStoreAction.StoreAndResolve;
- else
- copyStoreAction = RenderBufferStoreAction.Store;
- // If our camera sorting layer texture bound is inside our batch we need to break up the DrawRenderers into two batches
- if (cameraSortingLayerBoundsIndex >= layerBatch.layerRange.lowerBound && cameraSortingLayerBoundsIndex < layerBatch.layerRange.upperBound && m_Renderer2DData.useCameraSortingLayerTexture)
- {
- filterSettings.sortingLayerRange = new SortingLayerRange(layerBatch.layerRange.lowerBound, cameraSortingLayerBoundsIndex);
- Render(context, cmd, ref renderingData, ref filterSettings, drawSettings);
- CopyCameraSortingLayerRenderTexture(context, renderingData, copyStoreAction);
-
- filterSettings.sortingLayerRange = new SortingLayerRange((short)(cameraSortingLayerBoundsIndex + 1), layerBatch.layerRange.upperBound);
- Render(context, cmd, ref renderingData, ref filterSettings, drawSettings);
- }
- else
- {
- filterSettings.sortingLayerRange = new SortingLayerRange(layerBatch.layerRange.lowerBound, layerBatch.layerRange.upperBound);
- Render(context, cmd, ref renderingData, ref filterSettings, drawSettings);
-
- if (cameraSortingLayerBoundsIndex == layerBatch.layerRange.upperBound && m_Renderer2DData.useCameraSortingLayerTexture)
- CopyCameraSortingLayerRenderTexture(context, renderingData, copyStoreAction);
- }
-
- // Draw light volumes
- if (drawLights && (layerBatch.lightStats.totalVolumetricUsage > 0))
- {
- var sampleName = "Render 2D Light Volumes";
- cmd.BeginSample(sampleName);
-
- RenderBufferStoreAction storeAction;
- if (msaaEnabled)
- storeAction = resolveDuringBatch == i && !resolveIsAfterCopy ? RenderBufferStoreAction.Resolve : RenderBufferStoreAction.StoreAndResolve;
- else
- storeAction = RenderBufferStoreAction.Store;
- this.RenderLightVolumes(renderingData, cmd, ref layerBatch, colorAttachmentHandle.nameID, depthAttachmentHandle.nameID,
- RenderBufferStoreAction.Store, storeAction, false, m_Renderer2DData.lightCullResult.visibleLights);
-
- cmd.EndSample(sampleName);
- }
- }
- }
- }
-
- for (var i = startIndex; i < startIndex + batchesDrawn; ++i)
- {
- ref var layerBatch = ref layerBatches[i];
- layerBatch.ReleaseRT(cmd);
- }
-
- return batchesDrawn;
- }
-
- [Obsolete(DeprecationMessage.CompatibilityScriptingAPIObsolete, false)]
- public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
- {
- var isLitView = true;
-
- #if UNITY_EDITOR
- if (renderingData.cameraData.isSceneViewCamera)
- isLitView = UnityEditor.SceneView.currentDrawingSceneView.sceneLighting;
-
- if (renderingData.cameraData.camera.cameraType == CameraType.Preview)
- isLitView = false;
- #endif
- var camera = renderingData.cameraData.camera;
- var filterSettings = FilteringSettings.defaultValue;
- filterSettings.renderQueueRange = RenderQueueRange.all;
- filterSettings.layerMask = -1;
- filterSettings.renderingLayerMask = 0xFFFFFFFF;
- filterSettings.sortingLayerRange = SortingLayerRange.all;
-
- LayerUtility.InitializeBudget(m_Renderer2DData.lightRenderTextureMemoryBudget);
- ShadowRendering.InitializeBudget(m_Renderer2DData.shadowRenderTextureMemoryBudget);
- RendererLighting.lightBatch.Reset();
-
- var isSceneLit = m_Renderer2DData.lightCullResult.IsSceneLit();
- if (isSceneLit && isLitView)
- {
- var combinedDrawSettings = CreateDrawingSettings(k_ShaderTags, ref renderingData, SortingCriteria.CommonTransparent);
- var normalsDrawSettings = CreateDrawingSettings(k_NormalsRenderingPassName, ref renderingData, SortingCriteria.CommonTransparent);
-
- var sortSettings = combinedDrawSettings.sortingSettings;
- RendererLighting.GetTransparencySortingMode(m_Renderer2DData, camera, ref sortSettings);
- combinedDrawSettings.sortingSettings = sortSettings;
- normalsDrawSettings.sortingSettings = sortSettings;
-
- var cmd = renderingData.commandBuffer;
- cmd.SetGlobalFloat(k_HDREmulationScaleID, m_Renderer2DData.hdrEmulationScale);
- cmd.SetGlobalFloat(k_InverseHDREmulationScaleID, 1.0f / m_Renderer2DData.hdrEmulationScale);
- cmd.SetGlobalColor(k_RendererColorID, Color.white);
- cmd.SetGlobalTexture(k_FalloffLookupID, m_FallOffLookup);
- cmd.SetGlobalTexture(k_LightLookupID, Light2DLookupTexture.GetLightLookupTexture());
- RendererLighting.SetLightShaderGlobals(m_Renderer2DData, CommandBufferHelpers.GetRasterCommandBuffer(cmd));
-
- var desc = this.GetBlendStyleRenderTextureDesc(renderingData);
-
- ShadowRendering.CallOnBeforeRender(renderingData.cameraData.camera, m_Renderer2DData.lightCullResult);
-
- var layerBatches = LayerUtility.CalculateBatches(m_Renderer2DData.lightCullResult, out var batchCount);
- var batchesDrawn = 0;
-
- for (var i = 0; i < batchCount; i += batchesDrawn)
- batchesDrawn = DrawLayerBatches(layerBatches, batchCount, i, cmd, context, ref renderingData, ref filterSettings, ref normalsDrawSettings, ref combinedDrawSettings, ref desc);
-
- RendererLighting.DisableAllKeywords(CommandBufferHelpers.GetRasterCommandBuffer(cmd));
- context.ExecuteCommandBuffer(cmd);
- cmd.Clear();
- }
- else
- {
- var unlitDrawSettings = CreateDrawingSettings(k_ShaderTags, ref renderingData, SortingCriteria.CommonTransparent);
- var msaaEnabled = renderingData.cameraData.cameraTargetDescriptor.msaaSamples > 1;
- var storeAction = msaaEnabled ? RenderBufferStoreAction.Resolve : RenderBufferStoreAction.Store;
-
- var sortSettings = unlitDrawSettings.sortingSettings;
- RendererLighting.GetTransparencySortingMode(m_Renderer2DData, camera, ref sortSettings);
- unlitDrawSettings.sortingSettings = sortSettings;
-
- var cmd = renderingData.commandBuffer;
- using (new ProfilingScope(cmd, m_ProfilingSamplerUnlit))
- {
- CoreUtils.SetRenderTarget(cmd,
- colorAttachmentHandle, RenderBufferLoadAction.Load, storeAction,
- depthAttachmentHandle, RenderBufferLoadAction.Load, storeAction,
- ClearFlag.None, Color.clear);
-
- cmd.SetGlobalColor(k_RendererColorID, Color.white);
-
- for (var blendStyleIndex = 0; blendStyleIndex < k_ShapeLightTextureIDs.Length; blendStyleIndex++)
- {
- if (blendStyleIndex == 0)
- cmd.SetGlobalTexture(k_ShapeLightTextureIDs[blendStyleIndex], Texture2D.blackTexture);
-
- RendererLighting.EnableBlendStyle(CommandBufferHelpers.GetRasterCommandBuffer(cmd), blendStyleIndex, blendStyleIndex == 0);
- }
- }
-
- RendererLighting.DisableAllKeywords(CommandBufferHelpers.GetRasterCommandBuffer(cmd));
- context.ExecuteCommandBuffer(cmd);
- cmd.Clear();
-
- Profiler.BeginSample("Render Sprites Unlit");
- if (m_Renderer2DData.useCameraSortingLayerTexture)
- {
- filterSettings.sortingLayerRange = new SortingLayerRange(short.MinValue, m_CameraSortingLayerBoundsIndex);
- Render(context, cmd, ref renderingData, ref filterSettings, unlitDrawSettings);
-
- CopyCameraSortingLayerRenderTexture(context, renderingData, storeAction);
-
- filterSettings.sortingLayerRange = new SortingLayerRange((short)(m_CameraSortingLayerBoundsIndex + 1), short.MaxValue);
- Render(context, cmd, ref renderingData, ref filterSettings, unlitDrawSettings);
- }
- else
- {
- Render(context, cmd, ref renderingData, ref filterSettings, unlitDrawSettings);
- }
- Profiler.EndSample();
- }
-
- filterSettings.sortingLayerRange = SortingLayerRange.all;
-
- RendererList objectsWithErrorRendererList = RendererList.nullRendererList;
- RenderingUtils.CreateRendererListObjectsWithError(context, ref renderingData.cullResults, camera, filterSettings, SortingCriteria.None, ref objectsWithErrorRendererList);
- RenderingUtils.DrawRendererListObjectsWithError(CommandBufferHelpers.GetRasterCommandBuffer(renderingData.commandBuffer), ref objectsWithErrorRendererList);
- }
-
- Renderer2DData IRenderPass2D.rendererData
- {
- get { return m_Renderer2DData; }
- }
-
- public void Dispose()
- {
- m_Renderer2DData.normalsRenderTarget?.Release();
- m_Renderer2DData.normalsRenderTarget = null;
- m_Renderer2DData.cameraSortingLayerRenderTarget?.Release();
- m_Renderer2DData.cameraSortingLayerRenderTarget = null;
- }
- }
- }
|