2026-04-19 02:38:48 +08:00
|
|
|
using System;
|
|
|
|
|
using XCEngine;
|
|
|
|
|
using XCEngine.Rendering;
|
|
|
|
|
using XCEngine.Rendering.Renderer;
|
2026-04-19 00:05:29 +08:00
|
|
|
|
2026-04-19 02:38:48 +08:00
|
|
|
namespace XCEngine.Rendering.FirstParty
|
|
|
|
|
{
|
|
|
|
|
internal sealed class ForwardSceneRecordingPass : ScriptableRenderPass
|
2026-04-19 00:05:29 +08:00
|
|
|
{
|
2026-04-19 02:38:48 +08:00
|
|
|
private readonly Func<RendererRecordingContext, bool> m_recordAction;
|
2026-04-19 00:05:29 +08:00
|
|
|
|
2026-04-19 02:38:48 +08:00
|
|
|
public ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent passEvent,
|
2026-04-19 02:38:48 +08:00
|
|
|
Func<RendererRecordingContext, bool> recordAction)
|
2026-04-19 00:05:29 +08:00
|
|
|
{
|
|
|
|
|
renderPassEvent = passEvent;
|
2026-04-19 02:38:48 +08:00
|
|
|
m_recordAction = recordAction;
|
2026-04-19 00:05:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override bool RecordRenderGraph(
|
2026-04-19 02:38:48 +08:00
|
|
|
RendererRecordingContext context,
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderingData renderingData)
|
|
|
|
|
{
|
|
|
|
|
return context != null &&
|
|
|
|
|
renderingData != null &&
|
|
|
|
|
renderingData.isMainSceneStage &&
|
2026-04-19 02:38:48 +08:00
|
|
|
m_recordAction != null &&
|
|
|
|
|
m_recordAction(context);
|
2026-04-19 00:05:29 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal sealed class ForwardSceneFeature : ScriptableRendererFeature
|
|
|
|
|
{
|
|
|
|
|
private readonly ForwardRendererData m_rendererData;
|
2026-04-19 02:38:48 +08:00
|
|
|
private readonly ForwardSceneRecordingPass m_beforeOpaquePass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.BeforeRenderingOpaques,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordBeforeOpaqueInjection());
|
|
|
|
|
private readonly ForwardSceneRecordingPass m_opaquePass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.RenderOpaques,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordOpaqueScenePhase());
|
|
|
|
|
private readonly ForwardSceneRecordingPass m_afterOpaquePass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.AfterRenderingOpaques,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordAfterOpaqueInjection());
|
|
|
|
|
private readonly ForwardSceneRecordingPass m_beforeSkyboxPass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.BeforeRenderingSkybox,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordBeforeSkyboxInjection());
|
|
|
|
|
private readonly ForwardSceneRecordingPass m_skyboxPass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.RenderSkybox,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordSkyboxScenePhase());
|
|
|
|
|
private readonly ForwardSceneRecordingPass m_afterSkyboxPass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.AfterRenderingSkybox,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordAfterSkyboxInjection());
|
|
|
|
|
private readonly ForwardSceneRecordingPass m_beforeTransparentPass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.BeforeRenderingTransparents,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordBeforeTransparentInjection());
|
|
|
|
|
private readonly ForwardSceneRecordingPass m_transparentPass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.RenderTransparents,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordTransparentScenePhase());
|
|
|
|
|
private readonly ForwardSceneRecordingPass m_afterTransparentPass =
|
|
|
|
|
new ForwardSceneRecordingPass(
|
2026-04-19 00:05:29 +08:00
|
|
|
RenderPassEvent.AfterRenderingTransparents,
|
2026-04-19 02:38:48 +08:00
|
|
|
context => context.RecordAfterTransparentInjection());
|
2026-04-19 00:05:29 +08:00
|
|
|
|
|
|
|
|
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]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-19 02:38:48 +08:00
|
|
|
|