Files
XCEngine/engine/include/XCEngine/Rendering/AGENTS.md

9.1 KiB
Raw Blame History

Rendering 模块说明

1. 目的

  • 本文记录当前渲染模块已经落地的真实边界,以及后续改动必须遵守的约束。
  • 本文优先描述代码现状和明确目标,不替代码补脑。
  • 如果实现与本文冲突,以代码为准;修完代码后同步更新本文。

2. 当前主链

SceneRenderer
  -> SceneRenderRequestPlanner
  -> RenderPipelineHost
      -> CameraFramePlanBuilder
      -> CameraRenderer
          -> DirectionalShadowRuntime
          -> RenderSceneExtractor
          -> CameraFrameGraph
              -> RenderGraph Record / Compile / Execute

3. 当前顶层切换语义

  • 顶层切换目标向 Unity 对齐。
  • GraphicsSettings.renderPipelineAsset == null:走内置管线。
  • GraphicsSettings.renderPipelineAsset != null:走可编程渲染管线。
  • 当前内置管线默认直连 BuiltinForwardPipelineAsset -> BuiltinForwardPipeline
  • 当前可编程管线默认直连 ManagedScriptableRenderPipelineAsset -> ScriptableRenderPipelineHost
  • 运行时启动不得再偷偷自动选择 ProjectDefaultRenderPipelineAsset
  • “当前项目里存在某个默认 SRP asset” 不是切换条件;唯一切换条件是 GraphicsSettings.renderPipelineAsset

4. 和 Unity SRP / URP 的对齐方式

  • RenderPipelineAsset 对应 Unity 的 RenderPipelineAsset
  • ScriptableRenderPipelineHost 对应 native 侧承接托管 SRP 的 RenderPipeline 宿主。
  • managed 侧产品骨架仍是: ScriptableRenderPipelineAsset -> ScriptableRendererData -> ScriptableRenderer -> ScriptableRendererFeature/Pass
  • builtin 和 SRP 现在都必须是显式可切换的顶层路径而不是“SRP 隐式优先builtin 只是兜底”。
  • ScriptableRenderPipelineHost 里的 native backend 是 managed SRP 的绘制后端,不是 SRP stage 录制失败时的顶层兜底。
  • managed ScriptableRenderContext 的公开场景接口只表达绘制能力:DrawRenderers(...)DrawSkybox()DrawOpaqueRenderers()DrawTransparentRenderers()
  • renderer-backed SRP 的 frame stage 组织权归 ScriptableRenderer / ScriptableRendererFeature,包括 shadow caster、depth only、post-process、final output 等可选 stage。

5. 当前硬边界

  • RenderPipelineFactory 在无显式 asset、无托管配置、创建失败回退时都必须先回 builtin而不是回 ScriptableRenderPipelineHost
  • MonoScriptRuntime::OnRuntimeStart() 不得隐式写入 render pipeline 选择。
  • builtin 私有 native feature 通道只能留在 native 内部使用。
  • managed SRP runtime 或 stage recorder 存在时stage 组织权归 managed SRPnative backend 不得在 host 层隐式接管 RecordStageRenderGraphRender(...) 或 scene-pass standalone stage。
  • RendererBackedRenderPipelineAsset 进入 frame planning 时必须先清掉 native 默认请求出来的可选 stage再由 renderer / feature 显式请求需要的 stage。
  • 下列能力不得再暴露给 managed / URP 公开层: NativeSceneFeaturePassId ScriptableRenderContext.RecordNativeSceneFeaturePass(...) ScriptableRenderContext.RecordScene(...) ScriptableRenderContext.RecordScenePhase(...) ScriptableRenderContext.RecordSceneInjectionPoint(...) ScriptableRenderContext.RecordOpaque/Skybox/TransparentScenePhase(...) ScriptableRenderContext.RecordBefore/After*Injection(...) 依赖上述接口的 managed wrapper feature / controller
  • CameraRenderRequestContext.hasDirectionalShadowCameraRenderRequestContext.ClearDirectionalShadow() 不得作为 ScriptCore public surface 暴露core 层只能保留内部桥接,产品层策略放在 URP renderer asset / renderer data / feature。
  • URP 默认 renderer feature 工厂不得自动注入 builtin 私有 feature wrapper。

6. native / managed 分层

  • 放在 native 的内容: scene extraction renderer list 绘制 render graph 执行 fullscreen primitive 执行 builtin 私有 scene feature 执行内核
  • 放在 managed URP 的内容: renderer 选择 stage planning renderer feature / pass 组织 renderer feature 的 frame-plan / scene-setup / shadow-execution 配置分发 camera 级策略 shadow caster / depth only 等可选 stage 的显式请求 产品层行为差异
  • 判断原则: 如果新增的是“绘制能力”或“后端 contract”优先放 C++。 如果新增的是“渲染组织策略”或“URP 行为”,优先放 managed。

7. 禁止回退的实现方式

  • 不要再引入“项目默认 SRP asset 自动生效”的隐式逻辑。
  • 不要再把 builtin 私有 native feature 包成 public managed API 方便调用。
  • 不要让 managed ScriptableRenderContext.RecordScene(...) 或任何 managed pass 录制 native scene injection point。
  • 不要再让 “null 选择” 默认落到 ScriptableRenderPipelineHost
  • 不要把非通用产品层策略继续直接塞回 BuiltinForwardPipeline
  • 不要让 ScriptableRenderPipelineHost 在 managed SRP 未支持或未录制某个 stage 时自动回退到 native backend需要绘制时应通过 managed ScriptableRenderContext 显式调用 native draw 能力。
  • 不要让 renderer-backed SRP 继续继承 native planner 默认请求出来的 shadow/depth stage需要这些 stage 时必须由 managed renderer / feature 显式请求并录制。

8. 关键文件

  • engine/src/Rendering/Internal/RenderPipelineFactory.cpp
  • engine/src/Rendering/Execution/RenderPipelineHost.cpp
  • engine/src/Rendering/Execution/CameraRenderer.cpp
  • engine/src/Rendering/Extraction/RenderSceneExtractor.cpp
  • engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp
  • engine/src/Rendering/Pipelines/ScriptableRenderPipelineHost.cpp
  • engine/src/Scripting/Mono/MonoScriptRuntime.cpp
  • managed/XCEngine.ScriptCore/Rendering/Core/GraphicsSettings.cs
  • managed/XCEngine.ScriptCore/Rendering/Core/ScriptableRenderPipeline*.cs
  • managed/XCEngine.RenderPipelines.Universal/Rendering/Universal/*.cs

9. 当前验证点

  • tests/scripting/test_project_script_assembly.cpp 运行时启动不会自动配置 ProjectDefaultRenderPipelineAsset
  • tests/Rendering/unit/test_camera_scene_renderer.cpp 无 managed 选择时默认走 builtin。 设置 managed descriptor 后切到 ScriptableRenderPipelineHost。 清空 managed descriptor 后退回 builtin。
  • tests/scripting/test_mono_script_runtime.cpp ScriptableRenderContextPublicApiSurfaceUsesDirectContextModel 保证 public managed surface 不再暴露 native scene injection / phase wrapper。 DefaultSceneRendererUsesManagedUniversalPipelineForPlannedMainSceneAndPostProcessRender 保证 managed URP 通过显式 renderer/pass 录制主场景和后处理。 ManagedRenderContextExposes*ThroughRenderingData 保证 managed renderer 可通过 RenderingData 观察 camera / lighting / shadow / environment / final color / stage color 数据。 ManagedStageRecorderRecordsMainSceneThroughScriptableRenderContext 保证主场景通过 ScriptableRenderContext 的显式 draw 能力录制。 ScriptCoreUniversalRendererFeatureConfiguresCameraRequestPolicy 保证 URP renderer feature 能通过产品层相机请求策略真正禁用 native 默认方向光阴影规划。

10. 后续演进方向

  • 继续补齐 URP 上层组织能力,但不能破坏 builtin / programmable 的显式切换语义。
  • 如果未来继续向 Unity 收口,优先收口“入口语义”和“分层边界”,不要靠隐式 fallback 和私有桥接维持表面形似。

过去几刀

  • 收回 managed native scene injection 公开面:渲染模块目标向 Unity SRP / URP 对齐,但 managed / URP 层仍公开 native builtin scene injection point 和 phase wrapper导致产品层像是在组织 URP实质上仍在调用 builtin 私有时序。
  • 移除 ScriptableRenderContext.RecordSceneInjectionPoint(...)RecordBefore/After*Injection(...)RecordOpaque/Skybox/TransparentScenePhase(...) 等 public managed API移除对应 Mono internal callRecordScene() / RecordScenePhase(...) 收回 internal。
  • 确立 managed 公开层只通过 DrawRenderers(...)DrawSkybox()DrawOpaqueRenderers()DrawTransparentRenderers() 表达 native draw 能力pass / feature / stage 的组织权归 managed SRP / URP。
  • ScriptableRenderer 统一驱动 renderer feature 的 frame-plan、scene-setup、directional-shadow execution 配置;RendererBackedRenderPipelineAsset 清掉 native 默认 optional stage 后再让 renderer / feature 显式请求。
  • CameraRenderRequestContext.hasDirectionalShadowClearDirectionalShadow() 从 ScriptCore public surface 收回 internal避免 core public API 泄漏 native shadow 规划控制。
  • 收口 managed 相机请求策略顺序:MonoManagedRenderPipelineAssetRuntime::ConfigureCameraRenderRequest 先生成 native 默认方向光阴影基线给 managed / URP 观察,再按 managed 最终策略重算或清除,避免 ClearDirectionalShadow() 之后又被 native 默认规划补回。
  • 当时验证:xcengine_managed_assembliesscripting_tests 构建通过;聚焦 MonoScriptRuntimeTest 12 项 SRP / URP / API surface 测试通过。