docs: update rendering agent guide

This commit is contained in:
2026-04-27 00:58:53 +08:00
parent a3e2e2b4a9
commit 2be6a32424

View File

@@ -1,158 +1,351 @@
# Rendering Agent Guide
This file records the long-term rendering direction and the architecture cuts
already made. It is intentionally not a full map of the current implementation.
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.
If this file conflicts with the current code, trust the code and update this
file in the same change.
## Direction
## Next-Stage Goal
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.
The rendering module's next stage is to close the SRP / URP architecture around
Unity's public rendering model. The goal is not merely to have similar class
names; pipeline authors should be able to reason about XCEngine rendering with
the same mental model they use for Unity SRP and URP.
- 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 alignment is the primary design constraint:
## Pipeline Selection
- Treat `GraphicsSettings.renderPipelineAsset`, `RenderPipelineAsset`,
`ScriptableRenderPipelineAsset`, `ScriptableRenderPipeline`,
`ScriptableRenderContext`, `ScriptableRendererData`,
`ScriptableRenderer`, `ScriptableRendererFeature`,
`ScriptableRenderPass`, `RenderPassEvent`, `RenderingData`, and
`UniversalAdditionalCameraData` as the product-facing spine.
- Keep the managed API close to Unity semantics wherever the engine can support
it. If XCEngine must diverge, the divergence should be explicit, documented,
and caused by a real engine constraint rather than native convenience.
- Prefer Unity-style authoring concepts over native implementation concepts.
Public C# code should feel like URP pipeline authoring, not like remote
control over a native built-in renderer.
- `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`.
The pipeline selection contract must stay explicit and Unity-like:
## Current Shape
- `GraphicsSettings.renderPipelineAsset == null` selects the built-in pipeline.
- `GraphicsSettings.renderPipelineAsset != null` selects the managed SRP path.
- Runtime startup must not silently assign a project default SRP asset. A
project default can be loaded by project/editor policy, but rendering mode
changes must remain visible through `GraphicsSettings.renderPipelineAsset`.
- If a managed SRP asset cannot create a valid pipeline, recorder, or backend
bridge, creation should fail visibly and let the top-level factory choose the
built-in pipeline. `ScriptableRenderPipelineHost` must not impersonate a
successful managed SRP by drawing through a hidden fallback renderer.
The native renderer is now a camera frame planner plus RenderGraph executor,
with managed SRP/URP recording layered above a native scene draw backend.
The URP object model should be the center of future work:
- `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.
- `ScriptableRenderPipelineAsset` owns pipeline defaults, renderer-data lists,
default renderer selection, camera policy, final-color policy, shadow policy,
and managed pipeline lifetime.
- `UniversalRenderPipelineAsset` is the public URP asset spine. It owns
`rendererDataList`, `defaultRendererIndex`, renderer-data synchronization,
runtime renderer cache release, camera renderer override resolution, and
`UniversalRenderPipeline` creation directly. Do not put another public
renderer-backed bridge layer between URP assets and SRP assets.
- `UniversalRenderPipeline` is the public URP pipeline object. It should route
stage support and stage recording to the selected `ScriptableRenderer`
through the owning `UniversalRenderPipelineAsset`, not through XCEngine-only
public base classes.
- `ScriptableRendererData` is the serialized renderer configuration. It owns
renderer feature lists, default feature creation, runtime invalidation, and
renderer instance rebuilds.
- `ScriptableRenderer` owns per-camera pass queue construction. It should
enqueue passes from renderer features, sort by `RenderPassEvent`, partition
work into URP-like renderer blocks, and record only the stage requested by
the native frame plan.
- `ScriptableRendererFeature` owns reusable renderer extensions. Features
should configure camera/frame policy and enqueue `ScriptableRenderPass`
instances without reaching into native private pass order.
- `ScriptableRenderPass` owns pass lifecycle and recording. The long-term pass
surface should be `RecordRenderGraph(...)`, renderer-list drawing, public
texture/resource declarations, and explicit pass data.
## Frame Stages
The native/managed boundary should remain strict:
`CameraFrameStage` is the authoritative frame-stage model. Keep every native and
managed stage enum in sync.
- Managed SRP / URP owns renderer selection, feature/pass organization,
optional stage planning, camera clear policy, shadow/depth requests,
post-process and final-output policy, and public frame data exposed to user
passes.
- Native rendering owns scene extraction, culling and renderer-list
realization, render graph compilation/execution, RHI resource lifetime,
fullscreen primitive execution, and private built-in draw kernels.
- Managed scene drawing should expose draw capabilities, not native injection
points. Keep the public scene surface centered on `DrawRenderers(...)`,
`DrawSkybox()`, `DrawOpaqueRenderers()`, and
`DrawTransparentRenderers()`.
- Main-scene, shadow, and depth work should be renderer-driven. Managed passes
may request those stages and call public draw APIs, while native continues to
execute renderer lists and low-level draw kernels.
- 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.
Managed RenderGraph is the key capability gap for the next stage:
## RenderGraph
- Grow the current fullscreen-pass bridge into a URP-style render-graph
authoring surface with explicit texture creation/imports, read/write
declarations, pass data, frame-data/context-container access, and scheduled
renderer-list drawing.
- Post-process and final-output should become ordinary URP feature/pass work
where possible. Native fullscreen kernels may remain execution primitives,
but they should not appear as feature-specific public shortcuts.
- Prefer data-driven frame state (`CameraData`, `LightingData`, `ShadowData`,
`EnvironmentData`, `FinalColorData`, `StageColorData`) over direct scene
object inspection during pass recording.
The native RenderGraph is the execution spine for camera frames.
Tests should protect Unity-facing semantics while the architecture closes:
- 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.
- Prioritize contract tests for null-vs-SRP selection, managed SRP creation
failure, no hidden fallback rendering, renderer-data/default-renderer
selection, camera renderer override, feature/pass enqueue order, stage
planning, render-graph recording, and forbidden public API surface.
- Add URP integration scenes after the API and responsibility boundaries are
stable: default Universal renderer, `RenderObjectsRendererFeature`,
post-process/final-output, shadow/depth, camera override, and camera stack.
- Avoid overfitting tests to temporary native bridge details. Tests should lock
Unity SRP / URP semantics first, implementation mechanics second.
## Native Passes
Guardrails:
Native passes still matter for backend fallback, tools, and built-in rendering.
- Do not reintroduce public managed wrappers for native private scene injection
points.
- Do not reintroduce public managed bridge classes such as
`RendererBackedRenderPipelineAsset`, `RendererBackedRenderPipeline`, or
`RendererDrivenRenderPipeline`. Renderer-backed behavior belongs inside the
Unity-facing URP asset/pipeline pair.
- Do not make `RenderPassEvent` or renderer blocks a thin alias for native
built-in pass order. They should describe URP scheduling semantics.
- Do not add managed APIs that only work by reaching into one built-in native
renderer path. Add a public renderer-list, render-graph, or pass abstraction
instead.
- A managed SRP stage that declares support and then fails to record should
fail visibly. It should not silently continue by drawing the default native
scene.
- 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.
## Managed Boundary
Managed SRP assets are selected through `GraphicsSettings.renderPipelineAsset`
and bridged through `ManagedScriptableRenderPipelineAsset`.
- `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.
## URP Model
The URP package is in `managed/XCEngine.RenderPipelines.Universal`. It should be
treated as the primary user-facing render pipeline package.
- `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 RenderGraph
Managed RenderGraph is intentionally small but should keep Unity's modern shape.
- 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.
## Scene Data
Scene data is extracted once per camera frame and then adjusted by the pipeline.
- `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.
## Materials And Shaders
- 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.
## Modification Rules
- 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.
## Tests
Use the narrowest test set that covers the changed boundary, then broaden when a
change crosses native/managed or RenderGraph execution.
- Build engine after native Rendering changes:
`cmake --build <build-dir> --config Debug --target XCEngine`
- Build managed assemblies after ScriptCore or URP changes:
`cmake --build <build-dir> --config Debug --target xcengine_managed_assemblies`
- Build native rendering unit tests:
`cmake --build <build-dir> --config Debug --target rendering_unit_tests`
- Run native rendering tests directly:
`<build-dir>/tests/Rendering/unit/<config>/rendering_unit_tests`
- Or run the native rendering CTest subset:
`ctest -C Debug -R "RenderGraph|CameraFrame|SceneRender|RenderPass|BuiltinForward|FullscreenPass" --output-on-failure`
- Build scripting bridge tests:
`cmake --build <build-dir> --config Debug --target scripting_tests`
- Run scripting bridge tests directly:
`<build-dir>/tests/scripting/<config>/scripting_tests`
- Or run the SRP/URP scripting CTest subset:
`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:
`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`.
## 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.
## Past Execution
- Removed fullscreen-kernel-specific authoring from the public managed
RenderGraph / URP pass surface. Public C# pass authors now use
`AddRasterPass(...)`, resource declarations, and `SetRenderFunc(...)`;
`ColorScaleFullscreen`, `ShaderVectorFullscreen`, and `FinalColorFullscreen`
execution setters are internal implementation hooks for URP's built-in
passes. Native now records generic managed raster passes as declared callback
graph work in any stage, while true deferred managed command-buffer execution
remains the next capability gap.
- Made the public managed
`ScriptableRenderPass.RecordRenderGraph(RenderGraph, ContextContainer)` path
receive real URP frame data. `RenderingData`, `CameraData`, `LightingData`,
`ShadowData`, `EnvironmentData`, `FinalColorData`, and `StageColorData` are
now `ContextItem`s populated before public render-graph recording.
- Moved managed public render-graph frame data ownership from individual
`ScriptableRenderPass` calls to the `ScriptableRenderer` stage recording
scope. Public `ContextContainer` state is now shared across renderer passes
for the same stage, matching URP's frame-data mental model instead of
pass-local scratch data.
- Removed the non-Unity public renderer-backed bridge layer from the Universal
package. `UniversalRenderPipelineAsset` now derives directly from
`ScriptableRenderPipelineAsset`, owns renderer-data selection and runtime
resource lifecycle itself, and creates `UniversalRenderPipeline` directly.
The deleted bridge types must remain absent from the public API surface.
- Removed the public managed `SceneRenderInjectionPoint` type. Native scene
injection points remain internal built-in scene-recorder detail; managed SRP /
URP authors should use `RenderPassEvent`, renderer blocks, renderer-list draw
APIs, and RenderGraph declarations instead.
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`.