using System; using XCEngine; using XCEngine.Rendering; namespace XCEngine.Rendering.Universal { internal enum UniversalSceneRecordingKind { BeforeOpaqueInjection, OpaqueScene, AfterOpaqueInjection, BeforeSkyboxInjection, SkyboxScene, AfterSkyboxInjection, BeforeTransparentInjection, TransparentScene, AfterTransparentInjection } internal sealed class UniversalSceneRecordingPass : ScriptableRenderPass { private readonly UniversalSceneRecordingKind m_recordingKind; public UniversalSceneRecordingPass( RenderPassEvent passEvent, UniversalSceneRecordingKind recordingKind) { renderPassEvent = passEvent; m_recordingKind = recordingKind; } protected override bool RecordRenderGraph( ScriptableRenderContext context, RenderingData renderingData) { return context != null && renderingData != null && renderingData.isMainSceneStage && RecordSceneStep(context); } private bool RecordSceneStep( ScriptableRenderContext context) { switch (m_recordingKind) { case UniversalSceneRecordingKind.BeforeOpaqueInjection: return RecordBeforeOpaqueInjection(context); case UniversalSceneRecordingKind.OpaqueScene: return RecordOpaqueScenePhase(context); case UniversalSceneRecordingKind.AfterOpaqueInjection: return RecordAfterOpaqueInjection(context); case UniversalSceneRecordingKind.BeforeSkyboxInjection: return RecordBeforeSkyboxInjection(context); case UniversalSceneRecordingKind.SkyboxScene: return RecordSkyboxScenePhase(context); case UniversalSceneRecordingKind.AfterSkyboxInjection: return RecordAfterSkyboxInjection(context); case UniversalSceneRecordingKind.BeforeTransparentInjection: return RecordBeforeTransparentInjection(context); case UniversalSceneRecordingKind.TransparentScene: return RecordTransparentScenePhase(context); case UniversalSceneRecordingKind.AfterTransparentInjection: return RecordAfterTransparentInjection(context); default: return false; } } } internal sealed class UniversalSceneFeature : ScriptableRendererFeature { private readonly UniversalRendererData m_rendererData; private readonly UniversalSceneRecordingPass m_beforeOpaquePass = new UniversalSceneRecordingPass( RenderPassEvent.BeforeRenderingOpaques, UniversalSceneRecordingKind.BeforeOpaqueInjection); private readonly UniversalSceneRecordingPass m_opaquePass = new UniversalSceneRecordingPass( RenderPassEvent.RenderOpaques, UniversalSceneRecordingKind.OpaqueScene); private readonly UniversalSceneRecordingPass m_afterOpaquePass = new UniversalSceneRecordingPass( RenderPassEvent.AfterRenderingOpaques, UniversalSceneRecordingKind.AfterOpaqueInjection); private readonly UniversalSceneRecordingPass m_beforeSkyboxPass = new UniversalSceneRecordingPass( RenderPassEvent.BeforeRenderingSkybox, UniversalSceneRecordingKind.BeforeSkyboxInjection); private readonly UniversalSceneRecordingPass m_skyboxPass = new UniversalSceneRecordingPass( RenderPassEvent.RenderSkybox, UniversalSceneRecordingKind.SkyboxScene); private readonly UniversalSceneRecordingPass m_afterSkyboxPass = new UniversalSceneRecordingPass( RenderPassEvent.AfterRenderingSkybox, UniversalSceneRecordingKind.AfterSkyboxInjection); private readonly UniversalSceneRecordingPass m_beforeTransparentPass = new UniversalSceneRecordingPass( RenderPassEvent.BeforeRenderingTransparents, UniversalSceneRecordingKind.BeforeTransparentInjection); private readonly UniversalSceneRecordingPass m_transparentPass = new UniversalSceneRecordingPass( RenderPassEvent.RenderTransparents, UniversalSceneRecordingKind.TransparentScene); private readonly UniversalSceneRecordingPass m_afterTransparentPass = new UniversalSceneRecordingPass( RenderPassEvent.AfterRenderingTransparents, UniversalSceneRecordingKind.AfterTransparentInjection); public UniversalSceneFeature( UniversalRendererData rendererData) { m_rendererData = rendererData; } public override void AddRenderPasses( ScriptableRenderer renderer, RenderingData renderingData) { if (renderer == null || renderingData == null || !renderingData.isMainSceneStage || m_rendererData == null) { return; } if (m_rendererData.renderOpaque) { renderer.EnqueuePass(m_beforeOpaquePass); renderer.EnqueuePass(m_opaquePass); renderer.EnqueuePass(m_afterOpaquePass); } if (m_rendererData.renderSkybox) { renderer.EnqueuePass(m_beforeSkyboxPass); renderer.EnqueuePass(m_skyboxPass); renderer.EnqueuePass(m_afterSkyboxPass); } if (m_rendererData.renderTransparent) { renderer.EnqueuePass(m_beforeTransparentPass); renderer.EnqueuePass(m_transparentPass); renderer.EnqueuePass(m_afterTransparentPass); } } } public sealed class UniversalRenderer : ScriptableRenderer { public UniversalRenderer( UniversalRendererData rendererData) { UniversalRendererData resolvedData = rendererData ?? new UniversalRendererData(); AddFeature(new UniversalSceneFeature(resolvedData)); } } }