docs: update rendering agent guide
This commit is contained in:
@@ -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`.
|
||||
|
||||
Reference in New Issue
Block a user