docs: reorganize rendering agent guide

This commit is contained in:
2026-04-27 01:32:37 +08:00
parent 1b45bbcffc
commit d1126d70f7

View File

@@ -1,412 +1,335 @@
# Rendering Agent Guide
# 渲染模块 Agent 指南
This file is a working map for agents changing `engine/include/XCEngine/Rendering`,
`engine/src/Rendering`, and the matching managed SRP/URP surface under
`managed/`. It is not a substitute for reading the implementation. If this
guide conflicts with code, trust the code and update this guide in the same
change.
本文是修改 `engine/include/XCEngine/Rendering``engine/src/Rendering`,以及
`managed/` 下配套 managed SRP/URP 表面的工作地图。它不能替代阅读实现代码。
如果本文和代码冲突,以代码为准,并在同一次改动里更新本文。
## Direction
## 【未来目标】
The renderer is intentionally shaped after Unity SRP and URP. Future work should
prefer Unity-compatible public names, object ownership, and extension points
when those concepts fit the engine.
### 方向
- Keep the managed public surface close to Unity: `GraphicsSettings.renderPipelineAsset`,
`RenderPipelineAsset`, `ScriptableRenderPipelineAsset`,
`ScriptableRenderPipeline`, `ScriptableRenderContext`,
`UniversalRenderPipelineAsset`, `UniversalRendererData`,
`ScriptableRenderer`, `ScriptableRendererFeature`, `ScriptableRenderPass`,
`RenderPassEvent`, `ContextContainer`, and `RenderGraph`.
- Align behavior before inventing new public vocabulary. If a Unity concept is
only partially implemented here, expose the implemented subset honestly and
keep missing behavior behind internal code or tests.
- Preserve Unity-style numeric ordering for `RenderPassEvent`. Adding or moving
events requires updating `ScriptableRenderPass.TryResolveRendererBlock`,
`RendererBlocks`, probes, and tests together.
- Prefer managed URP features and passes for pipeline customization. Native
paths should supply backend execution, scene extraction, fallback passes, and
tooling support.
- Keep renderer code backend-neutral. D3D12, OpenGL, and Vulkan specifics belong
in `engine/include/XCEngine/RHI/**`, `engine/src/RHI/**`, or editor host
rendering, not in SRP/URP policy.
渲染器有意参考 Unity SRP 和 URP 设计。后续工作在概念适配本引擎时,应优先采用
Unity 兼容的公开命名、对象所有权和扩展点。
## Key Facts
- 保持 managed 公开表面接近 Unity`GraphicsSettings.renderPipelineAsset`
`RenderPipelineAsset``ScriptableRenderPipelineAsset`
`ScriptableRenderPipeline``ScriptableRenderContext`
`UniversalRenderPipelineAsset``UniversalRendererData`
`ScriptableRenderer``ScriptableRendererFeature``ScriptableRenderPass`
`RenderPassEvent``ContextContainer``RenderGraph`
- 在发明新的公开词汇前,优先对齐行为。如果某个 Unity 概念在这里只实现了一部分,
要诚实暴露已实现的子集,把缺失行为留在内部代码或测试里。
- 保留 Unity 风格的 `RenderPassEvent` 数值顺序。新增或移动事件时,必须一起更新
`ScriptableRenderPass.TryResolveRendererBlock``RendererBlocks`、probes 和测试。
- 管线自定义优先使用 managed URP features 和 passes。Native 路径应提供后端执行、
场景提取、fallback passes 和工具支持。
- 渲染器代码保持后端无关。D3D12、OpenGL 和 Vulkan 细节属于
`engine/include/XCEngine/RHI/**``engine/src/RHI/**` 或 editor host rendering
不应进入 SRP/URP 策略层。
These facts are the current architecture baseline. Do not weaken them without a
deliberate architecture cut and tests.
### 近期目标
- The SRP/URP architecture is phase-closed enough to extend. The public object
model, managed asset selection, URP renderer data/features/passes, native
frame planning, stage recording, and RenderGraph execution now form a single
path.
- This is not full Unity URP compatibility yet. The public shape is intentionally
Unity-like, but the execution feature set is still smaller than Unity URP.
- `UniversalRenderPipelineAsset` can be selected as the active managed SRP
asset, so users can route rendering through the URP package. Treat that as
supported but still transitional.
- The current URP package is not yet a complete replacement for the built-in
renderer in the strong sense. URP owns selection, planning, renderer feature
organization, pass ordering, and stage recording; native code still supplies
scene extraction, renderer-list realization, RenderGraph execution, RHI
resources, and the default scene draw backend.
- Native execution is not the problem by itself. Unity also executes through a
native engine. The risk is native code retaining built-in forward pipeline
policy instead of acting as a backend executor for URP-declared work.
- The desired ownership model is: URP decides what to render, when to render it,
which renderer lists/passes/features are active, and which stages exist;
native executes those declarations without smuggling in built-in pipeline
policy.
- Hidden fallback is dangerous. If a managed URP stage declares support but
cannot record, the failure should be visible. Do not silently draw the same
stage through the default built-in path and call it URP.
- The test suite has useful coverage, but it is not complete enough to call the
SRP/URP stack fully locked. Add high-value contract tests as architecture
boundaries close; do not pause the architecture work for a broad test-system
rewrite yet.
当前优先级是完成 SRP/URP 架构切分,并在每条边界上补目标明确的测试。近期产品目标
是让 URP 成为渲染决策层,让 native rendering 成为执行层。
## Near-Term Goals
-`BuiltinForwardPipeline` 从策略中心降级为默认 native scene draw backend。它可以
继续作为 backend/fallback 实现存在,但不应决定 URP pass 顺序、feature 参与方式或
stage 策略。
-`ScriptableRenderer` 及其 active pass queue 成为 URP main-scene scheduling 的权威。
Opaque、skybox、transparent、depth、shadow、post 和 final-output 流程应来自 URP
blocks 和 passes。
- 保持 `DrawObjectsPass``DrawSkyboxPass` 作为 managed URP pass declarations并通过
renderer-list/native scene-recorder backends 执行。
- 收紧 stage 支持规则。如果 fullscreen 或 main-scene stage 需要 managed graph recording
必须要求所选 renderer/pipeline 支持并记录该 stage。
- 只在 Unity 形态的 API 后面扩展 managed RenderGraphresource declarations、frame data、
renderer-list drawing、pass data 和 command recording。避免暴露 native 私有 graph 或
scene-recorder 细节。
- 在切分架构时补 contract testsURP selection、renderer data selection、renderer override、
pass event ordering、renderer feature invalidation、stage planning、RenderGraph recording
以及 no hidden built-in fallback。
- 等 SRP/URP 所有权边界稳定后,再做大范围测试体系重组。过早重组有可能固化当前的过渡行为。
Current priority is to finish the SRP/URP architecture cut, with targeted tests
on each boundary. The immediate product goal is to make URP the render decision
layer and make native rendering the execution layer.
### 修改规则
- Demote `BuiltinForwardPipeline` from policy center toward default native scene
draw backend. It can remain a backend/fallback implementation, but it should
not decide URP pass order, feature participation, or stage policy.
- Make `ScriptableRenderer` and its active pass queue the authority for URP
main-scene scheduling. Opaque, skybox, transparent, depth, shadow, post, and
final-output flow should come from URP blocks and passes.
- Keep `DrawObjectsPass` and `DrawSkyboxPass` as managed URP pass declarations
that execute through renderer-list/native scene-recorder backends.
- Tighten stage support rules. If a fullscreen or main-scene stage requires
managed graph recording, require the selected renderer/pipeline to support and
record that stage.
- Grow managed RenderGraph only behind Unity-shaped APIs: resource declarations,
frame data, renderer-list drawing, pass data, and command recording. Avoid
exposing native private graph or scene-recorder details.
- Add contract tests while cutting architecture: URP selection, renderer data
selection, renderer override, pass event ordering, renderer feature
invalidation, stage planning, RenderGraph recording, and no hidden built-in
fallback.
- Defer broad test-suite reorganization until these SRP/URP ownership boundaries
are stable. Reorganizing too early risks preserving transitional behavior.
- 行为变更要从 pipeline asset/request/plan 路径开始。app/editor 代码中的临时 pass execution
通常表示层级位置不对。
- Native headers 保持小而后端无关。可行时 forward declare RHI 类型,只在后端代码里 include
具体后端头。
- 新增 camera-stack、renderer-index、shadow、depth、post-process 或 final output 行为时,不要绕过
`CameraFramePlanBuilder``SceneRenderRequestPlanner`
- 不要在 native 长生命周期对象里保存 raw managed object pointers 或 managed context handles。
需要持久化时,通过现有 external managed object handle 系统 retain。
- Managed URP public APIs 不要依赖 `CameraFrameGraph``NativeSceneRecorder` 这类 native
实现名。
- Dirty/invalidation 路径必须显式。`ScriptableRendererFeature.SetActive`
feature `ComputeRuntimeStateHash`、renderer data feature collection hashes 和 asset runtime
resource versions 必须保持一致。
- 修改 renderer-index 行为时,要一起更新 `CameraRenderRequest.rendererIndex`、stage support contexts、
`RendererRecordingContext`、managed probes 和 Mono bridge calls。
- 新增 public managed rendering type 时,将它加入 `managed/CMakeLists.txt`,并在对应 managed probe
里覆盖 API presence。
## Pipeline Selection
## 【当下事实】
- `GraphicsSettings.renderPipelineAsset == null` means the renderer uses the
engine default native pipeline selection.
- `GraphicsSettings.renderPipelineAsset != null` means the renderer uses the
managed SRP asset descriptor path.
- Runtime startup must not silently assign a project default SRP asset. Project
or editor policy may choose one explicitly, but the active rendering mode must
remain observable through `GraphicsSettings.renderPipelineAsset`.
- If a managed asset cannot create a valid pipeline, recorder, or backend
bridge, fail visibly and let the top-level factory choose the fallback path.
Do not let `ScriptableRenderPipelineHost` look like a successful managed SRP
while secretly rendering an unsupported managed stage through a hidden native
path.
- Keep the deleted public bridge types absent:
`RendererBackedRenderPipelineAsset`, `RendererBackedRenderPipeline`, and
`RendererDrivenRenderPipeline`.
### 架构基线
## Current Shape
这些事实是当前架构基线。除非有明确的架构切分和测试,不要削弱它们。
The native renderer is now a camera frame planner plus RenderGraph executor,
with managed SRP/URP recording layered above a native scene draw backend.
- SRP/URP 架构已经阶段性收口到可以继续扩展。公开对象模型、managed asset selection、
URP renderer data/features/passes、native frame planning、stage recording 和 RenderGraph execution
现在组成了一条路径。
- 这还不是完整 Unity URP 兼容。公开形态有意接近 Unity但执行 feature set 仍小于 Unity URP。
- `UniversalRenderPipelineAsset` 可以被选为 active managed SRP asset所以用户可以把渲染路由到
URP package。把它视为受支持能力但仍处于过渡状态。
- 当前 URP package 还不是强意义上对 built-in renderer 的完整替代。URP 拥有 selection、planning、
renderer feature organization、pass ordering 和 stage recordingnative code 仍提供 scene extraction、
renderer-list realization、RenderGraph execution、RHI resources 和默认 scene draw backend。
- Native execution 本身不是问题。Unity 也通过 native engine 执行。风险在于 native code 继续保留
built-in forward pipeline policy而不是作为 URP-declared work 的 backend executor。
- 目标所有权模型是URP 决定渲染什么、何时渲染、哪些 renderer lists/passes/features 激活,以及
哪些 stages 存在native 只执行这些声明,不夹带 built-in pipeline policy。
- Hidden fallback 很危险。如果 managed URP stage 声明支持但无法 record失败必须可见。不要静默用
default built-in path 画同一个 stage然后称之为 URP。
- 测试体系已经有有价值的覆盖,但还不足以宣称 SRP/URP stack 完全锁定。随着架构边界收口,应补高价值
contract tests现阶段不要为了大范围测试体系重写而暂停架构工作。
- `SceneRenderer` is the scene-level convenience entry point. It collects camera
requests through `SceneRenderRequestPlanner`, builds frame plans through
`RenderPipelineHost`, then renders sorted camera plans.
- `RenderPipelineHost` owns a `CameraFramePlanBuilder` and a `CameraRenderer`.
It is the normal native bridge from `CameraRenderRequest` to `CameraFramePlan`.
- `CameraRenderer` owns the selected `RenderPipeline`, extracts
`RenderSceneData`, resolves directional shadow execution, records all frame
stages into a native `RenderGraph`, compiles the graph, and executes it.
- `RenderPipelineAsset` is the native asset contract. It creates a pipeline,
configures request policy, configures frame plan policy, and supplies default
final color settings.
- `RenderPipeline`, `RenderPipelineBackend`, and
`RenderPipelineStageRecorder` split backend rendering from graph recording.
Managed SRP normally supplies a stage recorder while the native backend
supplies scene drawing.
### 管线选择
## Frame Stages
- `GraphicsSettings.renderPipelineAsset == null` 表示 renderer 使用 engine default native pipeline selection。
- `GraphicsSettings.renderPipelineAsset != null` 表示 renderer 使用 managed SRP asset descriptor path。
- Runtime startup 不应静默指定 project default SRP asset。Project 或 editor policy 可以显式选择一个,
但 active rendering mode 必须能通过 `GraphicsSettings.renderPipelineAsset` 观察到。
- 如果 managed asset 无法创建有效 pipeline、recorder 或 backend bridge应显式失败并让 top-level factory
选择 fallback path。不要让 `ScriptableRenderPipelineHost` 看起来像成功的 managed SRP同时在背后用
hidden native path 渲染不受支持的 managed stage。
- 保持已删除的 public bridge types 不再出现:
`RendererBackedRenderPipelineAsset``RendererBackedRenderPipeline`
`RendererDrivenRenderPipeline`
`CameraFrameStage` is the authoritative frame-stage model. Keep every native and
managed stage enum in sync.
### 当前形态
- Current ordered stages are `PreScenePasses`, `ShadowCaster`, `DepthOnly`,
`MainScene`, `PostProcess`, `FinalOutput`, `ObjectId`, `PostScenePasses`, and
`OverlayPasses`.
- `ShadowCaster`, `DepthOnly`, and `ObjectId` are standalone-pass stages.
`MainScene` is the main pipeline stage. `PostProcess` and `FinalOutput` are
fullscreen sequence stages that may be graph-recorded by the pipeline when no
legacy `RenderPassSequence` is present.
- Use `CameraFramePlan` APIs such as `RequestFullscreenStage`,
`ClearFullscreenStage`, `RequestShadowCasterStage`, and
`RequestDepthOnlyStage`. Do not mutate plan stage fields directly unless you
are inside the plan implementation.
- Graph-managed color flow is explicit. `CameraFrameColorSource`,
`UsesGraphManagedSceneColor`, and `UsesGraphManagedOutputColor` decide whether
a stage reads from the main scene, post process, or an explicit surface.
- When adding a stage, update `CameraFrameStage.h`, managed
`CameraFrameStage.cs`, `CameraFramePlan`, camera-frame graph state/policy,
stage dispatch/contract tests, managed probes, and any Mono internal-call
conversion code.
Native renderer 现在是 camera frame planner 加 RenderGraph executormanaged SRP/URP recording
叠在 native scene draw backend 之上。
## RenderGraph
- `SceneRenderer` 是 scene-level convenience entry point。它通过 `SceneRenderRequestPlanner` 收集
camera requests通过 `RenderPipelineHost` 构建 frame plans然后渲染排序后的 camera plans。
- `RenderPipelineHost` 拥有一个 `CameraFramePlanBuilder` 和一个 `CameraRenderer`。它是从
`CameraRenderRequest``CameraFramePlan` 的常规 native bridge。
- `CameraRenderer` 拥有所选 `RenderPipeline`,提取 `RenderSceneData`,解析 directional shadow execution
把全部 frame stages 记录进 native `RenderGraph`,编译 graph 并执行。
- `RenderPipelineAsset` 是 native asset contract。它创建 pipeline配置 request policy配置 frame plan
policy并提供默认 final color settings。
- `RenderPipeline``RenderPipelineBackend``RenderPipelineStageRecorder` 将 backend rendering
与 graph recording 分开。Managed SRP 通常提供 stage recordernative backend 提供 scene drawing。
The native RenderGraph is the execution spine for camera frames.
### 帧阶段
- Record all graph resource usage through `RenderGraphBuilder` and
`RenderGraphPassBuilder`; do not rely on hidden RHI side effects.
- Imported textures need valid descriptions. If `graphOwnsTransitions` is true,
the imported view must expose a texture so the executor can create barriers.
- Transient textures require valid width, height, format, type, and sample
description. Invalid transient reads are compile errors.
- Use `RenderGraphRecordingContext` helpers to clone or adapt pass contexts
between `RenderPass`, `SceneRenderFeaturePass`, and pipeline-stage recorders.
- `RenderGraphBlackboard` carries per-frame shared data such as
`CameraFrameRenderGraphFrameData`; prefer typed blackboard entries over global
or static frame state.
- Current graph execution does dependency sorting, lifetime tracking,
transient allocation, and resource transitions. Do not assume pass culling or
transient aliasing exists unless you add and test it.
`CameraFrameStage` 是权威 frame-stage model。保持所有 native 和 managed stage enum 同步。
## Native Passes
- 当前有序 stages 是 `PreScenePasses``ShadowCaster``DepthOnly``MainScene``PostProcess`
`FinalOutput``ObjectId``PostScenePasses``OverlayPasses`
- `ShadowCaster``DepthOnly``ObjectId` 是 standalone-pass stages。`MainScene` 是主 pipeline stage。
`PostProcess``FinalOutput` 是 fullscreen sequence stages没有 legacy `RenderPassSequence` 时,
它们可以由 pipeline 进行 graph recording。
- 使用 `CameraFramePlan` APIs例如 `RequestFullscreenStage``ClearFullscreenStage`
`RequestShadowCasterStage``RequestDepthOnlyStage`。除非在 plan implementation 内部,否则不要直接
改 plan stage fields。
- Graph-managed color flow 是显式的。`CameraFrameColorSource``UsesGraphManagedSceneColor`
`UsesGraphManagedOutputColor` 决定 stage 是读取 main scene、post process 还是 explicit surface。
- 新增 stage 时,更新 `CameraFrameStage.h`、managed `CameraFrameStage.cs``CameraFramePlan`
camera-frame graph state/policy、stage dispatch/contract tests、managed probes以及所有 Mono
internal-call conversion code。
Native passes still matter for backend fallback, tools, and built-in rendering.
### RenderGraph
- New native passes should implement `RecordRenderGraph` when possible. Keep
`Execute` as the fallback path only when legacy execution is still required.
- Use `RenderPassGraphContract` and `RecordRenderGraphSurfaceIO` helpers for
fallback-compatible raster passes.
- `SceneRenderFeaturePass` is for native scene feature injection around scene
phases. Keep injection points in `SceneRenderInjectionPoint` and scene phases
in `ScenePhase` aligned with `SceneRenderSequence`.
- Object-id rendering is tooling/editor support. `CameraRenderer` installs the
top-level `BuiltinObjectIdPass` only when
`XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT` is enabled. Do not move object-id
ownership into the scene backend.
- Built-in fullscreen passes live under `Passes/` and planning factories live
under `Planning/`. Keep stage planning separate from pass implementation.
Native RenderGraph 是 camera frames 的执行主干。
## Managed Boundary
- 所有 graph resource usage 都通过 `RenderGraphBuilder``RenderGraphPassBuilder` 记录;不要依赖隐藏的
RHI side effects。
- Imported textures 需要有效 descriptions。如果 `graphOwnsTransitions` 为 trueimported view 必须暴露
texture以便 executor 创建 barriers。
- Transient textures 需要有效 width、height、format、type 和 sample description。无效 transient reads 是
compile errors。
- 使用 `RenderGraphRecordingContext` helpers 在 `RenderPass``SceneRenderFeaturePass` 和 pipeline-stage
recorders 之间 clone 或 adapt pass contexts。
- `RenderGraphBlackboard` 携带 per-frame shared data例如 `CameraFrameRenderGraphFrameData`;优先使用
typed blackboard entries不要用 global 或 static frame state。
- 当前 graph execution 已有 dependency sorting、lifetime tracking、transient allocation 和 resource transitions。
除非实现并测试,否则不要假设存在 pass culling 或 transient aliasing。
Managed SRP assets are selected through `GraphicsSettings.renderPipelineAsset`
and bridged through `ManagedScriptableRenderPipelineAsset`.
### Native Passes
- `ManagedRenderPipelineAssetDescriptor` identifies the managed asset assembly,
namespace, class, and retained managed object handle. Managed descriptors are
stored in `GraphicsSettingsState`.
- `ManagedScriptableRenderPipelineAsset` resolves a
`ManagedRenderPipelineAssetRuntime`, creates a `ScriptableRenderPipelineHost`,
and forwards request/plan/final-color policy calls to managed code.
- `ScriptableRenderPipelineHost` composes a native backend asset and an optional
managed stage recorder. When a managed recorder is authoritative, direct
legacy `Render` fallback is intentionally disabled for those stages.
- Mono creates `MonoManagedRenderPipelineAssetRuntime` and
`MonoManagedRenderPipelineStageRecorder`. Scriptable context, planning
context, camera request context, scene setup context, and shadow execution
context handles are temporary native registry entries. Do not store managed
context objects beyond their invocation.
- Current Mono-backed SRP assets explicitly use `DefaultNativeBackend` for scene
drawing. Managed `ScriptableRenderContext.DrawRenderers` and `DrawSkybox`
delegate to `NativeSceneRecorder` and the native `SceneDrawBackend`.
- Managed resource/version invalidation is part of correctness. If a managed
asset, renderer data, or feature changes runtime state, call `SetDirty` or the
local invalidation helper so native runtime caches are released.
Native passes 仍用于 backend fallback、工具和 built-in rendering。
## URP Model
- 新 native passes 应尽可能实现 `RecordRenderGraph`。只有 legacy execution 仍需要时,才把 `Execute` 保留为
fallback path。
- 对 fallback-compatible raster passes使用 `RenderPassGraphContract``RecordRenderGraphSurfaceIO`
helpers。
- `SceneRenderFeaturePass` 用于在 scene phases 周围注入 native scene feature。保持
`SceneRenderInjectionPoint` 中的 injection points、`ScenePhase` 中的 scene phases 与
`SceneRenderSequence` 对齐。
- Object-id rendering 是 tooling/editor support。只有启用 `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT` 时,
`CameraRenderer` 才安装 top-level `BuiltinObjectIdPass`。不要把 object-id ownership 移入 scene backend。
- Built-in fullscreen passes 位于 `Passes/`planning factories 位于 `Planning/`。保持 stage planning 与
pass implementation 分离。
The URP package is in `managed/XCEngine.RenderPipelines.Universal`. It should be
treated as the primary user-facing render pipeline package.
### Managed Boundary
- `UniversalRenderPipelineAsset` owns `rendererDataList`,
`defaultRendererIndex`, `UniversalShadowSettings`, and
`UniversalFinalColorSettings`. It resolves renderer index from
`UniversalAdditionalCameraData` before delegating to renderer data.
- `ScriptableRendererData` owns the persistent renderer instance and renderer
feature collection. Renderer data dirty state releases the renderer setup
cache and increments runtime state version.
- `ScriptableRenderer` builds `m_activePassQueue` per stage. It calls feature
`SetupRenderPasses`, feature `AddRenderPasses`, then renderer-owned
`AddRenderPasses`; passes are inserted by `RenderPassEvent` order and grouped
into `RendererBlocks`.
- `RendererBlock` maps pass events to camera stages: shadow caster, depth
prepass, main opaque, main skybox, main transparent, post process, and final
output.
- `UniversalRenderer` owns concrete blocks:
`UniversalShadowCasterBlock`, `UniversalDepthPrepassBlock`,
`UniversalMainSceneBlock`, `UniversalPostProcessBlock`, and
`UniversalFinalOutputBlock`.
- Built-in URP passes include `DrawObjectsPass`, `DrawSkyboxPass`, and the
internal `BuiltinFinalColorPass`. Current feature implementations include
`RenderObjectsRendererFeature`, `ColorScalePostProcessRendererFeature`, and
`DisableDirectionalShadowRendererFeature`.
- When adding a URP feature, keep its serializable settings, runtime hash,
`Create`, `ConfigureCameraRenderRequest`, `ConfigureCameraFramePlan`,
`ConfigureRenderSceneSetup`, `AddRenderPasses`, and stage gate behavior
together. If the feature needs a stage, request it during planning before
enqueueing a pass.
Managed SRP assets 通过 `GraphicsSettings.renderPipelineAsset` 选择,并通过
`ManagedScriptableRenderPipelineAsset` bridge。
## Managed RenderGraph
- `ManagedRenderPipelineAssetDescriptor` 标识 managed asset assembly、namespace、class 和 retained managed
object handle。Managed descriptors 存在 `GraphicsSettingsState` 中。
- `ManagedScriptableRenderPipelineAsset` 解析 `ManagedRenderPipelineAssetRuntime`,创建
`ScriptableRenderPipelineHost`,并把 request/plan/final-color policy calls 转发给 managed code。
- `ScriptableRenderPipelineHost` 组合 native backend asset 和可选 managed stage recorder。当 managed recorder
是权威时,这些 stages 的 direct legacy `Render` fallback 会被刻意禁用。
- Mono 创建 `MonoManagedRenderPipelineAssetRuntime``MonoManagedRenderPipelineStageRecorder`
Scriptable context、planning context、camera request context、scene setup context 和 shadow execution
context handles 都是临时 native registry entries。不要在调用之外保存 managed context objects。
- 当前 Mono-backed SRP assets 显式使用 `DefaultNativeBackend` 做 scene drawing。Managed
`ScriptableRenderContext.DrawRenderers``DrawSkybox` 委托给 `NativeSceneRecorder` 以及 native
`SceneDrawBackend`
- Managed resource/version invalidation 是正确性的一部分。如果 managed asset、renderer data 或 feature
修改 runtime state调用 `SetDirty` 或本地 invalidation helper确保 native runtime caches 被释放。
Managed RenderGraph is intentionally small but should keep Unity's modern shape.
### URP Model
- Public managed authoring goes through
`XCEngine.Rendering.RenderGraphModule.RenderGraph.AddRasterPass` and
`RenderGraphRasterPassBuilder`.
- Public passes should declare reads, bindings, color attachments, depth
attachment, and render func, then `Commit`.
- Internal fullscreen helpers such as color scale, shader vector, and final
color are URP implementation details. Do not expose them as public
`ScriptableRenderContext` shortcuts.
- Managed `SetRenderFunc` is not a fully bridged native command buffer yet. It
invokes the managed render func during recording and records declared IO into
native graph execution. Do not add behavior that assumes managed commands run
later on the native command list.
- Public RenderGraph frame data is shared for all passes recorded in the same
renderer stage. Keep `ContextContainer` as stage frame data, not pass-local
scratch data.
- Fullscreen internal passes require valid `sourceColorTexture` and
`primaryColorTarget`. Multi-pass fullscreen chains should update the current
source color after each pass.
URP package 位于 `managed/XCEngine.RenderPipelines.Universal`。它应被视为主要面向用户的 render pipeline
package。
## Scene Data
- `UniversalRenderPipelineAsset` 拥有 `rendererDataList``defaultRendererIndex`
`UniversalShadowSettings``UniversalFinalColorSettings`。它从 `UniversalAdditionalCameraData` 解析
renderer index然后委托给 renderer data。
- `ScriptableRendererData` 拥有持久 renderer instance 和 renderer feature collection。Renderer data dirty
state 会释放 renderer setup cache并递增 runtime state version。
- `ScriptableRenderer` 按 stage 构建 `m_activePassQueue`。它依次调用 feature `SetupRenderPasses`、feature
`AddRenderPasses`,再调用 renderer-owned `AddRenderPasses`passes 按 `RenderPassEvent` 顺序插入,并归组到
`RendererBlocks`
- `RendererBlock` 将 pass events 映射到 camera stagesshadow caster、depth prepass、main opaque、main
skybox、main transparent、post process 和 final output。
- `UniversalRenderer` 拥有具体 blocks
`UniversalShadowCasterBlock``UniversalDepthPrepassBlock``UniversalMainSceneBlock`
`UniversalPostProcessBlock``UniversalFinalOutputBlock`
- Built-in URP passes 包括 `DrawObjectsPass``DrawSkyboxPass` 和内部 `BuiltinFinalColorPass`。当前 feature
implementations 包括 `RenderObjectsRendererFeature``ColorScalePostProcessRendererFeature`
`DisableDirectionalShadowRendererFeature`
- 新增 URP feature 时,保持 serializable settings、runtime hash、`Create`
`ConfigureCameraRenderRequest``ConfigureCameraFramePlan``ConfigureRenderSceneSetup`
`AddRenderPasses` 和 stage gate behavior 一致。如果 feature 需要 stage先在 planning 阶段 request
再 enqueue pass。
Scene data is extracted once per camera frame and then adjusted by the pipeline.
### Managed RenderGraph
- `RenderSceneExtractor` builds `RenderSceneData` from the scene and camera.
Keep component traversal and render item extraction there or in
`Extraction/RenderSceneUtility`.
- Pipeline scene setup belongs in `RenderPipeline::ConfigureRenderSceneData` or
managed `ConfigureRenderSceneSetup`, not in individual draw passes.
- Main-light shadow data is planned through `DirectionalShadowPlanningSettings`
and executed through `DirectionalShadowRuntime`. The current implementation is
a single main directional shadow map, not cascaded shadows.
- Final color policy is resolved from pipeline defaults plus camera overrides.
`FinalOutput` is requested only when final color processing is required or a
feature explicitly asks for it.
- Global shader keywords are normalized. Keep keyword changes centralized in
scene setup policy, not scattered through draw passes.
Managed RenderGraph 目前有意保持较小,但应维持 Unity 的现代形态。
## Materials And Shaders
- Public managed authoring 通过
`XCEngine.Rendering.RenderGraphModule.RenderGraph.AddRasterPass`
`RenderGraphRasterPassBuilder` 进行。
- Public passes 应声明 reads、bindings、color attachments、depth attachment 和 render func然后 `Commit`
- Internal fullscreen helpers例如 color scale、shader vector 和 final color是 URP implementation details。
不要把它们作为 public `ScriptableRenderContext` shortcuts 暴露。
- Managed `SetRenderFunc` 还不是完全 bridged native command buffer。它在 recording 时调用 managed render
func并把声明的 IO 记录进 native graph execution。不要添加依赖 managed commands 之后在 native command
list 上运行的行为。
- Public RenderGraph frame data 由同一个 renderer stage 内记录的所有 passes 共享。保持 `ContextContainer`
作为 stage frame data而不是 pass-local scratch data。
- Fullscreen internal passes 需要有效 `sourceColorTexture``primaryColorTarget`。Multi-pass fullscreen chains
应在每个 pass 后更新 current source color。
- Built-in material pass names and resource semantics live in `Builtin/`.
Update `BuiltinPassTypes`, `BuiltinPassMetadataUtils`, and
`BuiltinPassLayoutUtils` together.
- Material-state resolution belongs under `Materials/`. Avoid duplicating render
state conversion logic inside passes.
- Shader variant helpers are split between public forwarding headers and
`Internal/`; keep public includes stable for engine users.
- URP shader package paths should follow the existing
`Packages/com.xcengine.render-pipelines.universal/...` convention.
### Scene Data
## Modification Rules
Scene data 每个 camera frame 提取一次,然后由 pipeline 调整。
- Start from the pipeline asset/request/plan path for behavior changes. Ad hoc
pass execution in app/editor code usually indicates the wrong layer.
- Keep native headers small and backend-agnostic. Forward declare RHI types where
practical and include concrete backend headers only in backend code.
- Do not bypass `CameraFramePlanBuilder` or `SceneRenderRequestPlanner` when
adding camera-stack, renderer-index, shadow, depth, post-process, or final
output behavior.
- Do not store raw managed object pointers or managed context handles in native
long-lived objects. Retain through the existing external managed object handle
system when persistence is required.
- Do not make managed URP public APIs depend on native implementation names such
as `CameraFrameGraph` or `NativeSceneRecorder`.
- Keep dirty/invalidation paths explicit. `ScriptableRendererFeature.SetActive`,
feature `ComputeRuntimeStateHash`, renderer data feature collection hashes,
and asset runtime resource versions must remain consistent.
- For renderer-index behavior, update `CameraRenderRequest.rendererIndex`,
stage support contexts, `RendererRecordingContext`, managed probes, and Mono
bridge calls together.
- When adding a new public managed rendering type, add it to
`managed/CMakeLists.txt` and cover API presence in the appropriate managed
probe.
- `RenderSceneExtractor` 从 scene 和 camera 构建 `RenderSceneData`。Component traversal 和 render item
extraction 应留在这里,或放在 `Extraction/RenderSceneUtility`
- Pipeline scene setup 属于 `RenderPipeline::ConfigureRenderSceneData` 或 managed
`ConfigureRenderSceneSetup`,不属于单个 draw pass。
- Main-light shadow data 通过 `DirectionalShadowPlanningSettings` 规划,并通过
`DirectionalShadowRuntime` 执行。当前实现是单个 main directional shadow map不是 cascaded shadows。
- Final color policy 由 pipeline defaults 加 camera overrides 解析。只有需要 final color processing 或 feature
显式要求时,才 request `FinalOutput`
- Global shader keywords 是规范化的。Keyword changes 应集中在 scene setup policy不要散落在 draw passes 中。
## Tests
### Materials And Shaders
Use the narrowest test set that covers the changed boundary, then broaden when a
change crosses native/managed or RenderGraph execution.
- Built-in material pass names 和 resource semantics 位于 `Builtin/`。一起更新 `BuiltinPassTypes`
`BuiltinPassMetadataUtils``BuiltinPassLayoutUtils`
- Material-state resolution 属于 `Materials/`。避免在 passes 中重复 render state conversion logic。
- Shader variant helpers 分为 public forwarding headers 和 `Internal/`;保持 public includes 对 engine users 稳定。
- URP shader package paths 应遵循现有
`Packages/com.xcengine.render-pipelines.universal/...` 约定。
- Build engine after native Rendering changes:
### 测试体系
使用覆盖变更边界的最窄测试集合;当改动跨 native/managed 或 RenderGraph execution 时,再扩大范围。
- Native Rendering 改动后构建 engine
`cmake --build <build-dir> --config Debug --target XCEngine`
- Build managed assemblies after ScriptCore or URP changes:
- ScriptCore URP 改动后构建 managed assemblies
`cmake --build <build-dir> --config Debug --target xcengine_managed_assemblies`
- Build native rendering unit tests:
- 构建 native rendering unit tests
`cmake --build <build-dir> --config Debug --target rendering_unit_tests`
- Run native rendering tests directly:
- 直接运行 native rendering tests
`<build-dir>/tests/Rendering/unit/<config>/rendering_unit_tests`
- Or run the native rendering CTest subset:
- 或运行 native rendering CTest 子集:
`ctest -C Debug -R "RenderGraph|CameraFrame|SceneRender|RenderPass|BuiltinForward|FullscreenPass" --output-on-failure`
- Build scripting bridge tests:
- 构建 scripting bridge tests
`cmake --build <build-dir> --config Debug --target scripting_tests`
- Run scripting bridge tests directly:
- 直接运行 scripting bridge tests
`<build-dir>/tests/scripting/<config>/scripting_tests`
- Or run the SRP/URP scripting CTest subset:
- 或运行 SRP/URP scripting CTest 子集:
`ctest -C Debug -R "MonoScriptRuntimeTest|ProjectScriptAssemblyTest" --output-on-failure`
- Run the renderer phase regression suite when SRP/URP phase ordering, renderer
features, or editor viewport rendering changes:
- 当 SRP/URP phase ordering、renderer features 或 editor viewport rendering 改动时,运行 renderer phase
regression suite
`cmake --build <build-dir> --config Debug --target rendering_phase_regression`
- Useful probe files for managed API changes:
`managed/GameScripts/RenderPipelineApiProbe.cs`,
`managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs`, and
`project/Assets/Scripts/ProjectRenderPipelineProbe.cs`.
- Important native test files:
`tests/Rendering/unit/test_render_graph.cpp`,
`tests/Rendering/unit/test_camera_frame_graph_stage_policy.cpp`,
`tests/Rendering/unit/test_camera_frame_graph_stage_contract.cpp`,
`tests/Rendering/unit/test_camera_scene_renderer.cpp`,
`tests/Rendering/unit/test_scene_render_request_planner.cpp`, and
`tests/scripting/test_mono_script_runtime.cpp`.
- Managed API 改动常用 probe files
`managed/GameScripts/RenderPipelineApiProbe.cs`
`managed/GameScripts/ScriptableRenderContextApiSurfaceProbe.cs`
`project/Assets/Scripts/ProjectRenderPipelineProbe.cs`
- 重要 native test files
`tests/Rendering/unit/test_render_graph.cpp`
`tests/Rendering/unit/test_camera_frame_graph_stage_policy.cpp`
`tests/Rendering/unit/test_camera_frame_graph_stage_contract.cpp`
`tests/Rendering/unit/test_camera_scene_renderer.cpp`
`tests/Rendering/unit/test_scene_render_request_planner.cpp`
`tests/scripting/test_mono_script_runtime.cpp`
## Current Debt
### 当前债务
- Managed SRP is still an SRP v1 surface. Main scene drawing is recorded through
managed calls but executed by native scene draw backends.
- Managed `CommandBuffer` and public `SetRenderFunc` do not execute deferred
native command lists yet.
- Managed RenderGraph currently exposes raster authoring. Native graph has
compute pass support, but managed compute authoring is not public.
- `UniversalPostProcessBlock` mostly owns planning and promotion. Actual
post-process work currently comes from features/passes.
- `UniversalRendererData` and features are code-created objects, not a full
Unity-style serialized asset pipeline.
- Current shadow support is a single main directional shadow path with no
cascades.
- The graph compiler/executor does not currently implement pass culling or
transient aliasing.
- Managed SRP 仍是 SRP v1 surfaceMain scene drawing 通过 managed calls 记录,但由 native scene draw
backends 执行。
- Managed `CommandBuffer` public `SetRenderFunc` 还不会执行 deferred native command lists。
- Managed RenderGraph 当前暴露 raster authoring。Native graph 有 compute pass support但 managed compute
authoring 还未公开。
- `UniversalPostProcessBlock` 主要负责 planning 和 promotion。实际 post-process work 当前来自 features/passes。
- `UniversalRendererData` 和 features 是 code-created objects还不是完整 Unity 风格 serialized asset pipeline。
- 当前 shadow support 是单个 main directional shadow path没有 cascades
- Graph compiler/executor 当前没有实现 pass culling 或 transient aliasing。
## Past Execution
## 【过去进展】
This section records architecture cuts that have already been made. Keep it as a
running ledger when future changes close or move ownership boundaries.
### 已完成的架构切分
- `GraphicsSettings.renderPipelineAsset` selects managed SRP assets through
`ManagedScriptableRenderPipelineAsset` and `GraphicsSettingsState`.
- Managed SRP execution is hosted by `ScriptableRenderPipelineHost`, which
combines a native backend with an optional managed stage recorder.
- Mono-backed SRP assets use `DefaultNativeBackend` for scene drawing and record
managed stages into the native RenderGraph.
- URP now has renderer data, renderer features, renderer pass queueing, renderer
blocks, renderer-index resolution, and per-stage recording.
- Public managed RenderGraph raster authoring exists; internal fullscreen
kernels remain URP implementation details.
- Public `ScriptableRenderPass.RecordRenderGraph(RenderGraph, ContextContainer)`
receives real URP frame data through `RenderingData`, `CameraData`,
`LightingData`, `ShadowData`, `EnvironmentData`, `FinalColorData`, and
`StageColorData`.
- Public managed `SceneRenderInjectionPoint` has been removed. Managed SRP/URP
authors should use `RenderPassEvent`, renderer blocks, renderer-list drawing,
and RenderGraph declarations instead of native private injection points.
- Main scene, post process, final output, object id, depth-only, and
shadow-caster stages are centralized under `CameraFrameStage` and
`CameraFramePlan`.
- Final color processing is represented as a policy and a final output stage,
not as implicit swapchain behavior.
- Object-id rendering is a top-level tooling pass guarded by
`XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT`.
本节记录已经完成的架构切分。未来改动关闭或移动所有权边界时,继续把它作为流水账维护。
- `GraphicsSettings.renderPipelineAsset` 已通过 `ManagedScriptableRenderPipelineAsset`
`GraphicsSettingsState` 选择 managed SRP assets。
- Managed SRP execution 由 `ScriptableRenderPipelineHost` 承载,它组合 native backend 和可选 managed
stage recorder。
- Mono-backed SRP assets 使用 `DefaultNativeBackend` 做 scene drawing并把 managed stages 记录到 native
RenderGraph。
- URP 现在已有 renderer data、renderer features、renderer pass queueing、renderer blocks、renderer-index
resolution 和 per-stage recording。
- Public managed RenderGraph raster authoring 已存在internal fullscreen kernels 仍是 URP implementation
details。
- Public `ScriptableRenderPass.RecordRenderGraph(RenderGraph, ContextContainer)` 通过 `RenderingData`
`CameraData``LightingData``ShadowData``EnvironmentData``FinalColorData``StageColorData`
接收真实 URP frame data。
- Public managed `SceneRenderInjectionPoint` 已移除。Managed SRP/URP authors 应使用 `RenderPassEvent`
renderer blocks、renderer-list drawing 和 RenderGraph declarations,而不是 native private injection points
- Main scenepost processfinal outputobject iddepth-only 和 shadow-caster stages 已集中到
`CameraFrameStage` `CameraFramePlan`
- Final color processing 表示为 policy 和 final output stage而不是 implicit swapchain behavior。
- Object-id rendering 是 top-level tooling pass并由 `XCENGINE_ENABLE_RENDERING_EDITOR_SUPPORT` guard。