refactor(srp): unify main-scene feature injection
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# SRP / URP Main Scene Feature Injection Plan
|
||||
|
||||
时间:2026-04-22
|
||||
|
||||
## 背景
|
||||
|
||||
当前 renderer block 主线已经基本清晰:
|
||||
|
||||
- `ShadowCaster`
|
||||
- `DepthPrepass`
|
||||
- `MainScene`
|
||||
- `PostProcess`
|
||||
- `FinalOutput`
|
||||
|
||||
`UniversalRenderer` 也已经拆出了对应 block owner。
|
||||
|
||||
但 `main scene` 这一面的 renderer feature 注入还不够干净:
|
||||
|
||||
1. `RenderObjectsRendererFeature` 自己手写 scene-stage 与 pass-stage 判断。
|
||||
2. `BuiltinGaussianSplatRendererFeature` / `BuiltinVolumetricRendererFeature` 各自重复一套 native scene feature pass 注入逻辑。
|
||||
3. 缺少统一的 main-scene feature 注入骨架,后续继续加 scene feature 时还会复制这些判断和样板。
|
||||
|
||||
## 本阶段目标
|
||||
|
||||
补齐 `main scene` feature 注入的统一 utility / controller,把当前散落在 feature 里的 main-scene 注入规则收口。
|
||||
|
||||
目标结果:
|
||||
|
||||
1. `RenderObjectsRendererFeature` 走统一的 main-scene pass 注入 helper。
|
||||
2. Gaussian / Volumetric 共用同一套 native scene feature controller。
|
||||
3. 后续再加 main-scene renderer feature 时,有稳定的落点可复用。
|
||||
|
||||
## 范围
|
||||
|
||||
本阶段只处理 main-scene feature 注入骨架,不做:
|
||||
|
||||
- public renderer feature API 改造
|
||||
- deferred rendering
|
||||
- C++ host / RenderGraph 改造
|
||||
|
||||
## 实施步骤
|
||||
|
||||
### 1. 新增 main-scene feature 注入 utility
|
||||
|
||||
职责:
|
||||
|
||||
- 统一判断当前是否处于 main scene stage
|
||||
- 统一判断 pass 是否属于当前 stage
|
||||
- 统一执行 enqueue
|
||||
|
||||
### 2. 新增 native scene feature controller
|
||||
|
||||
职责:
|
||||
|
||||
- 持有 `NativeSceneFeaturePass`
|
||||
- 统一 create / configure / enqueue
|
||||
- 供 Gaussian / Volumetric 复用
|
||||
|
||||
### 3. 接入现有 feature
|
||||
|
||||
接入:
|
||||
|
||||
- `RenderObjectsRendererFeature`
|
||||
- `BuiltinGaussianSplatRendererFeature`
|
||||
- `BuiltinVolumetricRendererFeature`
|
||||
|
||||
## 完成标准
|
||||
|
||||
满足以下条件才算本阶段收口:
|
||||
|
||||
1. main-scene feature 注入规则不再散落在多个 feature 里重复实现。
|
||||
2. Gaussian / Volumetric 共用统一 native scene feature controller。
|
||||
3. `XCEditor` 编译通过,old editor 冒烟通过。
|
||||
@@ -256,6 +256,8 @@ set(XCENGINE_RENDER_PIPELINES_UNIVERSAL_SOURCES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalFinalOutputBlock.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalMainSceneData.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalMainSceneBlock.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalMainSceneFeatureUtility.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalNativeSceneFeatureController.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalDepthPrepassBlock.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalPostProcessBlock.cs
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/XCEngine.RenderPipelines.Universal/Rendering/Universal/UniversalRenderPipeline.cs
|
||||
|
||||
@@ -8,26 +8,23 @@ namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
public RenderPassEvent passEvent =
|
||||
RenderPassEvent.BeforeRenderingTransparents;
|
||||
|
||||
private NativeSceneFeaturePass m_pass;
|
||||
private readonly UniversalNativeSceneFeatureController m_controller =
|
||||
new UniversalNativeSceneFeatureController(
|
||||
NativeSceneFeaturePassId
|
||||
.BuiltinGaussianSplat);
|
||||
|
||||
protected override int ComputeRuntimeStateHash()
|
||||
{
|
||||
int hash =
|
||||
base.ComputeRuntimeStateHash();
|
||||
hash =
|
||||
RuntimeStateHashUtility.Combine(
|
||||
hash,
|
||||
(int)passEvent);
|
||||
return hash;
|
||||
return m_controller.AppendRuntimeStateHash(
|
||||
hash,
|
||||
passEvent);
|
||||
}
|
||||
|
||||
public override void Create()
|
||||
{
|
||||
m_pass = new NativeSceneFeaturePass(
|
||||
NativeSceneFeaturePassId
|
||||
.BuiltinGaussianSplat,
|
||||
passEvent);
|
||||
m_controller.Create(passEvent);
|
||||
}
|
||||
|
||||
public override void AddRenderPasses(
|
||||
@@ -42,9 +39,10 @@ namespace XCEngine.Rendering.Universal
|
||||
}
|
||||
|
||||
CreateInstance();
|
||||
|
||||
m_pass.Configure(passEvent);
|
||||
renderer.EnqueuePass(m_pass);
|
||||
m_controller.EnqueuePass(
|
||||
renderer,
|
||||
renderingData,
|
||||
passEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,26 +8,23 @@ namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
public RenderPassEvent passEvent =
|
||||
RenderPassEvent.BeforeRenderingTransparents;
|
||||
|
||||
private NativeSceneFeaturePass m_pass;
|
||||
private readonly UniversalNativeSceneFeatureController m_controller =
|
||||
new UniversalNativeSceneFeatureController(
|
||||
NativeSceneFeaturePassId
|
||||
.BuiltinVolumetric);
|
||||
|
||||
protected override int ComputeRuntimeStateHash()
|
||||
{
|
||||
int hash =
|
||||
base.ComputeRuntimeStateHash();
|
||||
hash =
|
||||
RuntimeStateHashUtility.Combine(
|
||||
hash,
|
||||
(int)passEvent);
|
||||
return hash;
|
||||
return m_controller.AppendRuntimeStateHash(
|
||||
hash,
|
||||
passEvent);
|
||||
}
|
||||
|
||||
public override void Create()
|
||||
{
|
||||
m_pass = new NativeSceneFeaturePass(
|
||||
NativeSceneFeaturePassId
|
||||
.BuiltinVolumetric,
|
||||
passEvent);
|
||||
m_controller.Create(passEvent);
|
||||
}
|
||||
|
||||
public override void AddRenderPasses(
|
||||
@@ -42,9 +39,10 @@ namespace XCEngine.Rendering.Universal
|
||||
}
|
||||
|
||||
CreateInstance();
|
||||
|
||||
m_pass.Configure(passEvent);
|
||||
renderer.EnqueuePass(m_pass);
|
||||
m_controller.EnqueuePass(
|
||||
renderer,
|
||||
renderingData,
|
||||
passEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,13 +136,10 @@ namespace XCEngine.Rendering.Universal
|
||||
scenePhase,
|
||||
BuildRendererListDesc(),
|
||||
BuildDrawingSettings());
|
||||
if (!m_pass.SupportsStage(
|
||||
renderingData.stage))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
renderer.EnqueuePass(m_pass);
|
||||
UniversalMainSceneFeatureUtility.EnqueuePass(
|
||||
renderer,
|
||||
renderingData,
|
||||
m_pass);
|
||||
}
|
||||
|
||||
private RendererListDesc BuildRendererListDesc()
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using XCEngine;
|
||||
using XCEngine.Rendering;
|
||||
|
||||
namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
internal static class UniversalMainSceneFeatureUtility
|
||||
{
|
||||
public static bool IsActive(
|
||||
RenderingData renderingData)
|
||||
{
|
||||
return renderingData != null &&
|
||||
renderingData.isMainSceneStage;
|
||||
}
|
||||
|
||||
public static bool SupportsPass(
|
||||
RenderingData renderingData,
|
||||
ScriptableRenderPass renderPass)
|
||||
{
|
||||
return IsActive(renderingData) &&
|
||||
renderPass != null &&
|
||||
renderPass.SupportsStage(
|
||||
renderingData.stage);
|
||||
}
|
||||
|
||||
public static bool EnqueuePass(
|
||||
ScriptableRenderer renderer,
|
||||
RenderingData renderingData,
|
||||
ScriptableRenderPass renderPass)
|
||||
{
|
||||
if (renderer == null ||
|
||||
!SupportsPass(
|
||||
renderingData,
|
||||
renderPass))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
renderer.EnqueuePass(renderPass);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using XCEngine;
|
||||
using XCEngine.Rendering;
|
||||
|
||||
namespace XCEngine.Rendering.Universal
|
||||
{
|
||||
internal sealed class UniversalNativeSceneFeatureController
|
||||
{
|
||||
private readonly NativeSceneFeaturePassId m_featurePassId;
|
||||
private NativeSceneFeaturePass m_pass;
|
||||
|
||||
public UniversalNativeSceneFeatureController(
|
||||
NativeSceneFeaturePassId featurePassId)
|
||||
{
|
||||
m_featurePassId =
|
||||
featurePassId;
|
||||
}
|
||||
|
||||
public int AppendRuntimeStateHash(
|
||||
int hash,
|
||||
RenderPassEvent passEvent)
|
||||
{
|
||||
return RuntimeStateHashUtility.Combine(
|
||||
hash,
|
||||
(int)passEvent);
|
||||
}
|
||||
|
||||
public void Create(
|
||||
RenderPassEvent passEvent)
|
||||
{
|
||||
if (m_pass == null)
|
||||
{
|
||||
m_pass = new NativeSceneFeaturePass(
|
||||
m_featurePassId,
|
||||
passEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pass.Configure(passEvent);
|
||||
}
|
||||
|
||||
public void EnqueuePass(
|
||||
ScriptableRenderer renderer,
|
||||
RenderingData renderingData,
|
||||
RenderPassEvent passEvent)
|
||||
{
|
||||
Create(passEvent);
|
||||
UniversalMainSceneFeatureUtility.EnqueuePass(
|
||||
renderer,
|
||||
renderingData,
|
||||
m_pass);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user