using System; using XCEngine; using XCEngine.Rendering; namespace XCEngine.Rendering.Universal { internal sealed class UniversalSceneRecordingPass : ScriptableRenderPass { private readonly Func m_recordAction; public UniversalSceneRecordingPass( RenderPassEvent passEvent, Func recordAction) { renderPassEvent = passEvent; m_recordAction = recordAction; } protected override bool RecordRenderGraph( ScriptableRenderContext context, RenderingData renderingData) { return context != null && renderingData != null && renderingData.isMainSceneStage && m_recordAction != null && m_recordAction(context); } } internal sealed class UniversalSceneFeature : ScriptableRendererFeature { private readonly UniversalRendererData m_rendererData; private readonly UniversalSceneRecordingPass m_beforeOpaquePass = new UniversalSceneRecordingPass( RenderPassEvent.BeforeRenderingOpaques, context => context.RecordBeforeOpaqueInjection()); private readonly UniversalSceneRecordingPass m_opaquePass = new UniversalSceneRecordingPass( RenderPassEvent.RenderOpaques, context => context.RecordOpaqueScenePhase()); private readonly UniversalSceneRecordingPass m_afterOpaquePass = new UniversalSceneRecordingPass( RenderPassEvent.AfterRenderingOpaques, context => context.RecordAfterOpaqueInjection()); private readonly UniversalSceneRecordingPass m_beforeSkyboxPass = new UniversalSceneRecordingPass( RenderPassEvent.BeforeRenderingSkybox, context => context.RecordBeforeSkyboxInjection()); private readonly UniversalSceneRecordingPass m_skyboxPass = new UniversalSceneRecordingPass( RenderPassEvent.RenderSkybox, context => context.RecordSkyboxScenePhase()); private readonly UniversalSceneRecordingPass m_afterSkyboxPass = new UniversalSceneRecordingPass( RenderPassEvent.AfterRenderingSkybox, context => context.RecordAfterSkyboxInjection()); private readonly UniversalSceneRecordingPass m_beforeTransparentPass = new UniversalSceneRecordingPass( RenderPassEvent.BeforeRenderingTransparents, context => context.RecordBeforeTransparentInjection()); private readonly UniversalSceneRecordingPass m_transparentPass = new UniversalSceneRecordingPass( RenderPassEvent.RenderTransparents, context => context.RecordTransparentScenePhase()); private readonly UniversalSceneRecordingPass m_afterTransparentPass = new UniversalSceneRecordingPass( RenderPassEvent.AfterRenderingTransparents, context => context.RecordAfterTransparentInjection()); 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)); ScriptableRendererFeature[] rendererFeatures = resolvedData.CreateRendererFeaturesInstance(); for (int i = 0; i < rendererFeatures.Length; ++i) { AddFeature(rendererFeatures[i]); } } } }