refactor(srp): move renderer model into universal package

This commit is contained in:
2026-04-19 14:11:25 +08:00
parent 570467a083
commit a7cda9375a
18 changed files with 23 additions and 31 deletions

View File

@@ -1,6 +1,5 @@
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.Universal
{

View File

@@ -1,6 +1,5 @@
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.Universal
{

View File

@@ -0,0 +1,23 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public enum RenderPassEvent
{
BeforeRenderingOpaques = 100,
RenderOpaques = 110,
AfterRenderingOpaques = 120,
BeforeRenderingSkybox = 200,
RenderSkybox = 210,
AfterRenderingSkybox = 220,
BeforeRenderingTransparents = 300,
RenderTransparents = 310,
AfterRenderingTransparents = 320,
BeforeRenderingPostProcessing = 400,
AfterRenderingPostProcessing = 420,
BeforeRenderingFinalOutput = 500,
AfterRenderingFinalOutput = 520
}
}

View File

@@ -0,0 +1,50 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class RendererBackedRenderPipeline
: ScriptableRenderPipeline
{
private ScriptableRenderer m_renderer;
protected RendererBackedRenderPipeline()
{
}
protected internal virtual ScriptableRenderer CreateRenderer()
{
return null;
}
protected override bool SupportsStageRenderGraph(
CameraFrameStage stage)
{
ScriptableRenderer renderer = GetOrCreateRenderer();
return renderer != null &&
renderer.SupportsStageRenderGraph(stage);
}
protected override bool RecordStageRenderGraph(
ScriptableRenderContext context)
{
ScriptableRenderer renderer = GetOrCreateRenderer();
return renderer != null &&
renderer.RecordStageRenderGraph(context);
}
protected ScriptableRenderer renderer =>
GetOrCreateRenderer();
private ScriptableRenderer GetOrCreateRenderer()
{
if (m_renderer == null)
{
m_renderer = CreateRenderer();
}
return m_renderer;
}
}
}

View File

@@ -0,0 +1,42 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class RendererBackedRenderPipelineAsset
: ScriptableRenderPipelineAsset
{
protected RendererBackedRenderPipelineAsset()
{
}
protected override ScriptableRenderPipeline CreatePipeline()
{
ScriptableRendererData rendererData =
ResolveRendererData();
return rendererData != null
? new RendererDrivenRenderPipeline(rendererData)
: null;
}
protected override void ConfigureCameraRenderRequest(
ScriptableRenderPipelineCameraRequestContext context)
{
ScriptableRendererData rendererData =
ResolveRendererData();
if (rendererData != null)
{
rendererData.ConfigureCameraRenderRequestInstance(
context);
}
}
protected abstract ScriptableRendererData GetRendererData();
private ScriptableRendererData ResolveRendererData()
{
return GetRendererData();
}
}
}

View File

@@ -0,0 +1,25 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public class RendererDrivenRenderPipeline
: RendererBackedRenderPipeline
{
private readonly ScriptableRendererData m_rendererData;
public RendererDrivenRenderPipeline(
ScriptableRendererData rendererData)
{
m_rendererData = rendererData;
}
protected internal override ScriptableRenderer CreateRenderer()
{
return m_rendererData != null
? m_rendererData.CreateRendererInstance()
: null;
}
}
}

View File

@@ -0,0 +1,92 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public sealed class RenderingData
{
internal RenderingData(CameraFrameStage stage)
: this(
stage,
CameraData.Default,
LightingData.Default,
ShadowData.Default,
EnvironmentData.Default,
FinalColorData.Default,
StageColorData.Default)
{
}
internal RenderingData(ScriptableRenderContext context)
: this(
context != null
? context.stage
: CameraFrameStage.MainScene,
context != null
? context.cameraData
: CameraData.Default,
context != null
? context.lightingData
: LightingData.Default,
context != null
? context.shadowData
: ShadowData.Default,
context != null
? context.environmentData
: EnvironmentData.Default,
context != null
? context.finalColorData
: FinalColorData.Default,
context != null
? context.stageColorData
: StageColorData.Default)
{
}
private RenderingData(
CameraFrameStage stage,
CameraData cameraData,
LightingData lightingData,
ShadowData shadowData,
EnvironmentData environmentData,
FinalColorData finalColorData,
StageColorData stageColorData)
{
this.stage = stage;
this.cameraData = cameraData ?? CameraData.Default;
this.lightingData =
lightingData ?? LightingData.Default;
this.shadowData =
shadowData ?? ShadowData.Default;
this.environmentData =
environmentData ?? EnvironmentData.Default;
this.finalColorData =
finalColorData ?? FinalColorData.Default;
this.stageColorData =
stageColorData ?? StageColorData.Default;
}
public CameraFrameStage stage { get; }
public CameraData cameraData { get; }
public LightingData lightingData { get; }
public ShadowData shadowData { get; }
public EnvironmentData environmentData { get; }
public FinalColorData finalColorData { get; }
public StageColorData stageColorData { get; }
public bool isMainSceneStage =>
stage == CameraFrameStage.MainScene;
public bool isPostProcessStage =>
stage == CameraFrameStage.PostProcess;
public bool isFinalOutputStage =>
stage == CameraFrameStage.FinalOutput;
}
}

View File

@@ -0,0 +1,70 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class ScriptableRenderPass
{
protected ScriptableRenderPass()
{
}
public RenderPassEvent renderPassEvent { get; protected set; } =
RenderPassEvent.BeforeRenderingOpaques;
public virtual bool SupportsStage(
CameraFrameStage stage)
{
CameraFrameStage resolvedStage;
return TryResolveStage(
renderPassEvent,
out resolvedStage) &&
resolvedStage == stage;
}
internal bool Record(
ScriptableRenderContext context,
RenderingData renderingData)
{
return RecordRenderGraph(
context,
renderingData);
}
protected abstract bool RecordRenderGraph(
ScriptableRenderContext context,
RenderingData renderingData);
internal static bool TryResolveStage(
RenderPassEvent passEvent,
out CameraFrameStage stage)
{
switch (passEvent)
{
case RenderPassEvent.BeforeRenderingOpaques:
case RenderPassEvent.RenderOpaques:
case RenderPassEvent.AfterRenderingOpaques:
case RenderPassEvent.BeforeRenderingSkybox:
case RenderPassEvent.RenderSkybox:
case RenderPassEvent.AfterRenderingSkybox:
case RenderPassEvent.BeforeRenderingTransparents:
case RenderPassEvent.RenderTransparents:
case RenderPassEvent.AfterRenderingTransparents:
stage = CameraFrameStage.MainScene;
return true;
case RenderPassEvent.BeforeRenderingPostProcessing:
case RenderPassEvent.AfterRenderingPostProcessing:
stage = CameraFrameStage.PostProcess;
return true;
case RenderPassEvent.BeforeRenderingFinalOutput:
case RenderPassEvent.AfterRenderingFinalOutput:
stage = CameraFrameStage.FinalOutput;
return true;
default:
stage = CameraFrameStage.MainScene;
return false;
}
}
}
}

View File

@@ -0,0 +1,131 @@
using System.Collections.Generic;
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class ScriptableRenderer
{
private readonly List<ScriptableRendererFeature> m_features =
new List<ScriptableRendererFeature>();
private readonly List<ScriptableRenderPass> m_activePassQueue =
new List<ScriptableRenderPass>();
protected ScriptableRenderer()
{
}
public void EnqueuePass(
ScriptableRenderPass renderPass)
{
if (renderPass == null)
{
return;
}
int insertIndex = m_activePassQueue.Count;
while (insertIndex > 0 &&
m_activePassQueue[insertIndex - 1].renderPassEvent >
renderPass.renderPassEvent)
{
insertIndex--;
}
m_activePassQueue.Insert(
insertIndex,
renderPass);
}
protected void AddFeature(
ScriptableRendererFeature feature)
{
if (feature == null)
{
return;
}
m_features.Add(feature);
feature.Create();
}
protected virtual void AddRenderPasses(
RenderingData renderingData)
{
}
internal bool SupportsStageRenderGraph(
CameraFrameStage stage)
{
RenderingData renderingData = new RenderingData(stage);
BuildPassQueue(renderingData);
for (int i = 0; i < m_activePassQueue.Count; ++i)
{
ScriptableRenderPass renderPass = m_activePassQueue[i];
if (renderPass != null &&
renderPass.SupportsStage(stage))
{
return true;
}
}
return false;
}
internal bool RecordStageRenderGraph(
ScriptableRenderContext context)
{
if (context == null)
{
return false;
}
RenderingData renderingData =
new RenderingData(context);
BuildPassQueue(renderingData);
bool recordedAnyPass = false;
for (int i = 0; i < m_activePassQueue.Count; ++i)
{
ScriptableRenderPass renderPass = m_activePassQueue[i];
if (renderPass == null ||
!renderPass.SupportsStage(renderingData.stage))
{
continue;
}
if (!renderPass.Record(
context,
renderingData))
{
return false;
}
recordedAnyPass = true;
}
return recordedAnyPass;
}
private void BuildPassQueue(
RenderingData renderingData)
{
m_activePassQueue.Clear();
for (int i = 0; i < m_features.Count; ++i)
{
ScriptableRendererFeature feature = m_features[i];
if (feature == null || !feature.isActive)
{
continue;
}
feature.AddRenderPasses(
this,
renderingData);
}
AddRenderPasses(renderingData);
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class ScriptableRendererData : Object
{
private ScriptableRendererFeature[] m_rendererFeatures;
protected ScriptableRendererData()
{
}
internal ScriptableRenderer CreateRendererInstance()
{
return CreateRenderer();
}
internal ScriptableRendererFeature[] CreateRendererFeaturesInstance()
{
return GetRendererFeatures();
}
internal void ConfigureCameraRenderRequestInstance(
ScriptableRenderPipelineCameraRequestContext context)
{
ConfigureCameraRenderRequest(context);
ScriptableRendererFeature[] rendererFeatures =
GetRendererFeatures();
for (int i = 0; i < rendererFeatures.Length; ++i)
{
ScriptableRendererFeature rendererFeature =
rendererFeatures[i];
if (rendererFeature == null ||
!rendererFeature.isActive)
{
continue;
}
rendererFeature.ConfigureCameraRenderRequest(
context);
}
}
protected virtual ScriptableRenderer CreateRenderer()
{
return null;
}
protected virtual void ConfigureCameraRenderRequest(
ScriptableRenderPipelineCameraRequestContext context)
{
}
protected virtual ScriptableRendererFeature[] CreateRendererFeatures()
{
return Array.Empty<ScriptableRendererFeature>();
}
private ScriptableRendererFeature[] GetRendererFeatures()
{
if (m_rendererFeatures == null)
{
m_rendererFeatures =
CreateRendererFeatures() ??
Array.Empty<ScriptableRendererFeature>();
}
return m_rendererFeatures;
}
}
}

View File

@@ -0,0 +1,30 @@
using XCEngine;
using XCEngine.Rendering;
namespace XCEngine.Rendering.Universal
{
public abstract class ScriptableRendererFeature
{
protected ScriptableRendererFeature()
{
}
public bool isActive { get; set; } = true;
public virtual void Create()
{
}
public virtual void ConfigureCameraRenderRequest(
ScriptableRenderPipelineCameraRequestContext context)
{
}
public virtual void AddRenderPasses(
ScriptableRenderer renderer,
RenderingData renderingData)
{
}
}
}

View File

@@ -1,6 +1,5 @@
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.Universal
{

View File

@@ -1,7 +1,6 @@
using System;
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.Universal
{

View File

@@ -1,7 +1,6 @@
using System;
using XCEngine;
using XCEngine.Rendering;
using XCEngine.Rendering.Renderer;
namespace XCEngine.Rendering.Universal
{