-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Follow-up to #73. The render graph framework (RenderPass, RenderGraph, CompiledGraph) landed in #76 but doesn't touch the actual render pipeline. This issue is about extracting the stages from render() and _update_frame() into concrete RenderPass subclasses.
Goal
Replace the hardcoded sequential pipeline in analysis/render.py and engine.py with render graph execution. Right now, adding or reordering passes means editing control flow by hand.
Passes to extract
Each pass wraps existing CUDA kernel calls. No new GPU code, just reorganizing.
| Pass | Current location | Inputs | Outputs |
|---|---|---|---|
| GBufferPass | _generate_perspective_rays() + optix.trace() (primary) |
scene, camera params | primary_rays, primary_hits, albedo, instance_ids, primitive_ids |
| ShadowPass | _generate_shadow_rays_from_hits() + optix.trace() (occlusion) |
primary_rays, primary_hits, sun params |
shadow_hits |
| AOPass | AO sample loop + _generate_ao_rays() + _accumulate_ao/gi() |
primary_rays, primary_hits |
ao_factor, gi_color |
| ReflectionPass | _generate_reflection_rays() + optix.trace() |
primary_rays, primary_hits, instance_ids |
reflection_hits |
| ShadePass | _shade_terrain() |
all ray buffers, colormap, overlays | color, albedo |
| DenoisePass | denoise() from rtx.py |
color, albedo, normals |
denoised_color |
| EdgeOutlinePass | _edge_outline() |
color, instance_ids |
color (in-place) |
| EDLPass | _edl() |
color, depth |
color (in-place) |
| BloomPass | _bloom() |
color |
color (in-place) |
| TonemapPass | _tone_map_aces() |
color |
color (in-place) |
Implementation approach
- Start with
render()(the offline path) since it's simpler — no accumulation loop, no particle splatting, no async readback. - Pass classes go in
rtxpy/render_passes.py. - A
build_default_graph()factory builds the same pipeline the current code runs. - Add
use_render_graph=Falsetorender()so the graph path is opt-in while both paths coexist. - Once the graph path matches existing output pixel-for-pixel, flip the default and remove the old code path.
- Adapt
_update_frame()in the viewer to the same graph, with particle splatting and accumulation as viewer-specific passes.
Watch out for
- In-place passes (EdgeOutline, EDL, Bloom, Tonemap) read and write the same buffer. The graph handles this (a pass can list a buffer in both inputs and outputs), but they have to run in the right order after shading.
- AO accumulation runs multiple samples per frame with progressive accumulation in
_update_frame(). Probably best modeled as a single AOPass that loops internally, not N separate pass executions. - External state — camera params, sun direction, colormap LUTs, overlay textures aren't graph buffers. Pass them via
external_buffersor a config dict on the pass. - Double allocation —
_RenderBufferscurrently handles allocation, the graph'sAllocationPlanwill replace it. During the opt-in period, can't have both allocating at once.
Done when
-
render(use_render_graph=True)produces identical output to the current path (pixel-level comparison) -
explore()works with the graph path - A custom pass can be inserted into the default graph (e.g. a user post-process)
- Disabling a pass via the graph (e.g. AO, denoise) matches disabling via render parameters
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request