Skip to content

Interactive Mode¶

Renderer mode 3 launches an SDL2 window where you can explore any scene in real time with mouse-driven camera controls and an ImGui control panel.


Starting interactive mode¶

# Interactive mode is the default when SDL2 is present:
./rayon --scene ../resources/scenes/default_scene.yaml

# With adaptive depth for progressive quality:
./rayon --adaptive-depth

SDL2 required

Mode 3 is only available when SDL2 is found at CMake configure time. If mode 3 is not available, rebuild with SDL2 installed (-m 3 will be silently rejected without it).


Camera controls¶

Input Effect
Left mouse + drag Orbit — rotate the camera around the look-at point
Right mouse + drag Pan — translate both camera and look-at laterally
Scroll wheel Zoom — change distance from look-at point
Space Force re-render (reset accumulation buffer)
ESC Quit

Any camera change immediately resets sample accumulation. Rendering then continues using the current fixed samples-per-batch value.


Command-line flags for interactive mode¶

Flag Default Effect
--samples-per-batch <n> 10 Fixed samples per batch for interactive rendering
--adaptive-depth off Progressively increase max bounce depth per stage
--no-adaptive-sampling off Disable converged-pixel skipping (adaptive sampling)
--no-auto-accumulate off Disable automatic sample increase when stationary

Example: maximum quality accumulation:

./rayon --scene ../resources/scenes/09_color_bleed_box.yaml \
    --samples-per-batch 24 --adaptive-depth

Example: very responsive orbit for scene exploration:

./rayon --samples-per-batch 4 --no-auto-accumulate

ImGui control panel¶

While the scene is rendering, a panel in the top-right corner of the window provides live controls:

The performance section includes a single combined history graph for throughput and time per pass so short-term responsiveness and rendering cost can be compared in one view. Hovering the graph shows the sampled values at that point in history, and the latest values are listed directly under the plot.

Control Effect Notes
Samples slider Fixed samples per batch (--samples-per-batch) Does not trigger a full reset; the new batch size is used immediately
Max samples slider Upper limit for auto-accumulate —
Light intensity Scales area light emission No reset required — updates via cudaMemcpyToSymbol
Roughness Material roughness Triggers reset
Aperture DOF disk radius Triggers reset
Focus distance Thin lens focal plane Triggers reset
Max depth Ray bounce limit Triggers reset

Parameters that update without a reset (light intensity, exposure) are injected into the running kernel via cudaMemcpyToSymbol — no GPU scene rebuild.


Display pipeline¶

flowchart TD
    A["GPU kernel\n(CUDA)"] -->|accumulates samples| B["Float accum buffer\n(device memory)"]
    B -->|gamma correction kernel| C["uint8 display buffer\n(device memory)"]
    C -->|cudaMemcpy D→H\n3 B/pixel| D["uint8 host buffer\n(CPU RAM)"]
    D -->|SDL_UpdateTexture| E["SDL texture\n(GPU VRAM)"]
    E -->|SDL_RenderCopy| F["SDL renderer"]
    F -->|SDL_GL_SwapWindow| G["Display"]

Only 3 bytes per pixel cross the PCIe bus each frame. At 1920×1080, that is ~6 MB per frame — easily handled at 60 fps. Parameters that update without a full reset (light intensity, exposure) are injected via cudaMemcpyToSymbol directly into the running kernel — no GPU scene rebuild needed.


Sample screenshot¶

Interactive SDL2 window showing path-traced scene with Dear ImGui overlay

Interactive mode at 2048 SPP after 20 seconds of stillness. The ImGui panel (right) shows current samples, frame time, and live parameter sliders.