using System.Collections.Generic; using UnityEngine.Rendering.RenderGraphModule; using UnityEngine.Rendering.Universal.U2D.Profiler; using CommonResourceData = UnityEngine.Rendering.Universal.UniversalResourceData; namespace UnityEngine.Rendering.Universal { internal class DrawRenderer2DPass : ScriptableRenderPass { private static readonly ShaderTagId k_CombinedRenderingPassName = new ShaderTagId("Universal2D"); private static readonly ShaderTagId k_LegacyPassName = new ShaderTagId("SRPDefaultUnlit"); internal static readonly List k_ShaderTags = new List() {k_LegacyPassName, k_CombinedRenderingPassName}; private static readonly int k_HDREmulationScaleID = Shader.PropertyToID("_HDREmulationScale"); private static readonly int k_RendererColorID = Shader.PropertyToID("_RendererColor"); private static void Execute(RasterGraphContext context, PassData passData) { var cmd = context.cmd; var blendStylesCount = passData.blendStyleIndices.Length; cmd.SetGlobalFloat(k_HDREmulationScaleID, passData.hdrEmulationScale); cmd.SetGlobalColor(k_RendererColorID, Color.white); RendererLighting.SetLightShaderGlobals(cmd, passData.lightBlendStyles, passData.blendStyleIndices); #if UNITY_EDITOR if (passData.isLightingActive) #endif { if (passData.layerUseLights) { for (var i = 0; i < blendStylesCount; i++) { var blendStyleIndex = passData.blendStyleIndices[i]; RendererLighting.EnableBlendStyle(cmd, blendStyleIndex, true); } } else if (passData.isSceneLit) { RendererLighting.EnableBlendStyle(cmd, 0, true); } } if (passData.activeDebugHandler) { passData.debugRendererLists.DrawWithRendererList(cmd); } else { // Draw all renderers in layer batch cmd.DrawRendererList(passData.rendererList); } RendererLighting.DisableAllKeywords(cmd); } class SetGlobalPassData { internal TextureHandle[] lightTextures; } class PassData { internal Light2DBlendStyle[] lightBlendStyles; internal int[] blendStyleIndices; internal float hdrEmulationScale; internal bool isSceneLit; internal bool layerUseLights; internal TextureHandle[] lightTextures; internal RendererListHandle rendererList; internal DebugRendererLists debugRendererLists; internal bool activeDebugHandler; #if UNITY_EDITOR internal bool isLightingActive; // Required for prefab view and preview camera #endif } public void Render(RenderGraph graph, ContextContainer frameData, int batchIndex, ref FilteringSettings filterSettings) { UniversalRenderingData renderingData = frameData.Get(); UniversalCameraData cameraData = frameData.Get(); UniversalLightData lightData = frameData.Get(); Universal2DResourceData universal2DResourceData = frameData.Get(); CommonResourceData commonResourceData = frameData.Get(); Universal2DRenderingData rendering2DData = frameData.Get(); Renderer2DData rendererData = rendering2DData.renderingData; var layerBatch = rendering2DData.layerBatches[batchIndex]; // Check for lighting in scene/prefab/preview camera var isLightingActive = Renderer2D.IsSceneViewOrPreviewLightingActive(cameraData); // Preset global light textures for first batch if (batchIndex == 0) { using (var builder = graph.AddRasterRenderPass(ProfilerMarkers.s_SetLightBlendTexture, out var passData, ProfilerMarkers.s_ProfilingSamplerSetLightBlendTexture)) { if (layerBatch.lightStats.useLights && isLightingActive) { passData.lightTextures = universal2DResourceData.lightTextures[batchIndex]; for (var i = 0; i < passData.lightTextures.Length; i++) builder.UseTexture(passData.lightTextures[i]); } SetGlobalLightTextures(graph, builder, frameData, batchIndex, isLightingActive); builder.AllowGlobalStateModification(true); builder.SetRenderFunc(static (SetGlobalPassData data, RasterGraphContext context) => { }); } } // Renderer Pass var passName = ProfilerMarkers.s_RenderPass; LayerDebug.FormatPassName(layerBatch, ref passName); using (var builder = graph.AddRasterRenderPass(passName, out var passData, LayerDebug.GetProfilingSampler(passName, ProfilerMarkers.s_ProfilingSamplerRenderPass))) { passData.lightBlendStyles = rendererData.lightBlendStyles; passData.blendStyleIndices = layerBatch.activeBlendStylesIndices; passData.hdrEmulationScale = rendererData.hdrEmulationScale; passData.isSceneLit = rendererData.lightCullResult.IsSceneLit(); passData.layerUseLights = layerBatch.lightStats.useLights; #if UNITY_EDITOR passData.isLightingActive = isLightingActive; #endif var drawSettings = CreateDrawingSettings(k_ShaderTags, renderingData, cameraData, lightData, SortingCriteria.CommonTransparent); var sortSettings = drawSettings.sortingSettings; RendererLighting.GetTransparencySortingMode(rendererData, cameraData.camera, ref sortSettings); drawSettings.sortingSettings = sortSettings; var activeDebugHandler = GetActiveDebugHandler(cameraData); passData.activeDebugHandler = activeDebugHandler != null; if (activeDebugHandler != null) { var renderStateBlock = new RenderStateBlock(RenderStateMask.Nothing); passData.debugRendererLists = activeDebugHandler.CreateRendererListsWithDebugRenderState(graph, ref renderingData.cullResults, ref drawSettings, ref filterSettings, ref renderStateBlock); passData.debugRendererLists.PrepareRendererListForRasterPass(builder); } else { var param = new RendererListParams(renderingData.cullResults, drawSettings, filterSettings); passData.rendererList = graph.CreateRendererList(param); builder.UseRendererList(passData.rendererList); } if (passData.layerUseLights && isLightingActive) { passData.lightTextures = universal2DResourceData.lightTextures[batchIndex]; for (var i = 0; i < passData.lightTextures.Length; i++) builder.UseTexture(passData.lightTextures[i]); } if (rendererData.useCameraSortingLayerTexture) builder.UseTexture(universal2DResourceData.cameraSortingLayerTexture); // Set color and depth attachments builder.SetRenderAttachment(commonResourceData.activeColorTexture, 0); if (commonResourceData.activeDepthTexture.IsValid()) builder.SetRenderAttachmentDepth(commonResourceData.activeDepthTexture); builder.AllowGlobalStateModification(true); // Post set global light textures for next renderer pass var nextBatch = batchIndex + 1; if (nextBatch < universal2DResourceData.lightTextures.Length) SetGlobalLightTextures(graph, builder, frameData, nextBatch, isLightingActive); builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => { Execute(context, data); }); } } void SetGlobalLightTextures(RenderGraph graph, IRasterRenderGraphBuilder builder, ContextContainer frameData, int batchIndex, bool isLightingActive) { UniversalCameraData cameraData = frameData.Get(); Renderer2DData rendererData = frameData.Get().renderingData; var layerBatch = frameData.Get().layerBatches[batchIndex]; var lightTextures = frameData.Get().lightTextures[batchIndex]; if (isLightingActive) { if (layerBatch.lightStats.useLights) { for (var i = 0; i < lightTextures.Length; i++) { var blendStyleIndex = layerBatch.activeBlendStylesIndices[i]; builder.SetGlobalTextureAfterPass(lightTextures[i], Shader.PropertyToID(RendererLighting.k_ShapeLightTextureIDs[blendStyleIndex])); } } else if (rendererData.lightCullResult.IsSceneLit()) { for (var i = 0; i < RendererLighting.k_ShapeLightTextureIDs.Length; i++) builder.SetGlobalTextureAfterPass(graph.defaultResources.blackTexture, Shader.PropertyToID(RendererLighting.k_ShapeLightTextureIDs[i])); } } } } }