using System; using XCEngine; using XCEngine.Rendering; using XCEngine.Rendering.Renderer; namespace XCEngine.Rendering.FirstParty { internal sealed class ForwardSceneRecordingPass : ScriptableRenderPass { private readonly Func m_recordAction; public ForwardSceneRecordingPass( 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 ForwardSceneFeature : ScriptableRendererFeature { private readonly ForwardRendererData m_rendererData; private readonly ForwardSceneRecordingPass m_beforeOpaquePass = new ForwardSceneRecordingPass( RenderPassEvent.BeforeRenderingOpaques, context => context.RecordBeforeOpaqueInjection()); private readonly ForwardSceneRecordingPass m_opaquePass = new ForwardSceneRecordingPass( RenderPassEvent.RenderOpaques, context => context.RecordOpaqueScenePhase()); private readonly ForwardSceneRecordingPass m_afterOpaquePass = new ForwardSceneRecordingPass( RenderPassEvent.AfterRenderingOpaques, context => context.RecordAfterOpaqueInjection()); private readonly ForwardSceneRecordingPass m_beforeSkyboxPass = new ForwardSceneRecordingPass( RenderPassEvent.BeforeRenderingSkybox, context => context.RecordBeforeSkyboxInjection()); private readonly ForwardSceneRecordingPass m_skyboxPass = new ForwardSceneRecordingPass( RenderPassEvent.RenderSkybox, context => context.RecordSkyboxScenePhase()); private readonly ForwardSceneRecordingPass m_afterSkyboxPass = new ForwardSceneRecordingPass( RenderPassEvent.AfterRenderingSkybox, context => context.RecordAfterSkyboxInjection()); private readonly ForwardSceneRecordingPass m_beforeTransparentPass = new ForwardSceneRecordingPass( RenderPassEvent.BeforeRenderingTransparents, context => context.RecordBeforeTransparentInjection()); private readonly ForwardSceneRecordingPass m_transparentPass = new ForwardSceneRecordingPass( RenderPassEvent.RenderTransparents, context => context.RecordTransparentScenePhase()); private readonly ForwardSceneRecordingPass m_afterTransparentPass = new ForwardSceneRecordingPass( RenderPassEvent.AfterRenderingTransparents, context => context.RecordAfterTransparentInjection()); public ForwardSceneFeature( ForwardRendererData 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 ForwardRenderer : ScriptableRenderer { public ForwardRenderer( ForwardRendererData rendererData) { ForwardRendererData resolvedData = rendererData ?? new ForwardRendererData(); AddFeature(new ForwardSceneFeature(resolvedData)); ScriptableRendererFeature[] rendererFeatures = resolvedData.CreateRendererFeaturesInstance(); for (int i = 0; i < rendererFeatures.Length; ++i) { AddFeature(rendererFeatures[i]); } } } }