using System; using UnityEngine.Rendering.RenderGraphModule; // cleanup code // listMinDepth and maxDepth should be stored in a different uniform block? // Point lights stored as vec4 // RelLightIndices should be stored in ushort instead of uint. // TODO use Unity.Mathematics // TODO Check if there is a bitarray structure (with dynamic size) available in Unity namespace UnityEngine.Rendering.Universal.Internal { // Render all tiled-based deferred lights. internal class DeferredPass : ScriptableRenderPass { DeferredLights m_DeferredLights; public DeferredPass(RenderPassEvent evt, DeferredLights deferredLights) { profilingSampler = new ProfilingSampler("Render Deferred Lighting"); base.renderPassEvent = evt; m_DeferredLights = deferredLights; } private class PassData { internal UniversalCameraData cameraData; internal UniversalLightData lightData; internal UniversalShadowData shadowData; internal TextureHandle[] gbuffer; internal DeferredLights deferredLights; } internal void Render(RenderGraph renderGraph, ContextContainer frameData, TextureHandle color, TextureHandle depth, TextureHandle[] gbuffer) { UniversalCameraData cameraData = frameData.Get(); UniversalLightData lightData = frameData.Get(); UniversalShadowData shadowData = frameData.Get(); using (var builder = renderGraph.AddRasterRenderPass(passName, out var passData, profilingSampler)) { passData.cameraData = cameraData; passData.lightData = lightData; passData.shadowData = shadowData; builder.SetRenderAttachment(color, 0, AccessFlags.Write); builder.SetRenderAttachmentDepth(depth, AccessFlags.ReadWrite); passData.deferredLights = m_DeferredLights; if (!m_DeferredLights.UseFramebufferFetch) { for (int i = 0; i < gbuffer.Length; ++i) { if (i != m_DeferredLights.GBufferLightingIndex) builder.UseTexture(gbuffer[i], AccessFlags.Read); } } else { var idx = 0; for (int i = 0; i < gbuffer.Length; ++i) { if (i != m_DeferredLights.GBufferLightingIndex) { builder.SetInputAttachment(gbuffer[i], idx); idx++; } } } builder.AllowGlobalStateModification(true); builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => { data.deferredLights.ExecuteDeferredPass(context.cmd, data.cameraData, data.lightData, data.shadowData); }); } } // ScriptableRenderPass public override void OnCameraCleanup(CommandBuffer cmd) { m_DeferredLights.OnCameraCleanup(cmd); } } }