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:
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 mode at 2048 SPP after 20 seconds of stillness. The ImGui panel (right) shows current samples, frame time, and live parameter sliders.
