Skip to content

Commit 02b6575

Browse files
committed
Clean up TODO.md
1 parent eb1710a commit 02b6575

3 files changed

Lines changed: 80 additions & 99 deletions

File tree

TODO.md

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -42,68 +42,6 @@
4242
- [x] Test cases: Lambertian diffuse, Metal reflection, Dielectric refraction (entering/exiting)
4343
- [x] Helps catch regressions like the normal-flip bug from instance transforms
4444

45-
## Interactive Camera Controls (Live Mode)
46-
47-
Add keyboard and mouse controls to move the camera in real-time during `live` mode.
48-
49-
### Overview
50-
51-
Currently the camera is constructed entirely on the GPU side from hardcoded parameters in each scene function. The host only passes frame dimensions, elapsed time, and cursor position via `ShaderConstants`. To enable interactive controls, camera state must live on the CPU and be passed to the shader each frame.
52-
53-
### Phase 1: CPU-side input and logging (no shader changes)
54-
55-
Get input handling working and validate the camera math before touching the shader.
56-
57-
**Controls:**
58-
- WASD: horizontal movement (forward/back/strafe)
59-
- Space/C: up/down
60-
- Mouse: look direction (no cursor grab - just track movement while window focused)
61-
- Q: quit (in addition to Escape)
62-
63-
**Implementation:**
64-
- [ ] Add camera state to app struct (position, yaw, pitch)
65-
- [ ] Track held keys (simple bools for W/A/S/D/Space/C)
66-
- [ ] Track mouse delta for look direction
67-
- [ ] Each frame: update position based on held keys and orientation, update orientation from mouse
68-
- [ ] Log computed camera params to stdout
69-
- [ ] Q key exits the loop
70-
71-
### Phase 2: Wire up to shader
72-
73-
Once CPU-side camera is working:
74-
75-
- [x] Add camera fields to `ShaderConstants` (cam_pos, cam_dir, cam_fov, etc.)
76-
- [x] Modify shader to construct `Camera` from `ShaderConstants` instead of hardcoded values
77-
- [ ] Remove or bypass per-scene camera construction
78-
79-
### Phase 3: Fix gimbal lock with quaternions
80-
81-
The camera crashes when looking straight up or down because `vup` becomes parallel to the view direction, causing a zero-length cross product that produces NaN values. Tests in `crates/rtx-util/tests/camera_tests.rs` demonstrate this issue.
82-
83-
**Stage 1: Add `vup` to data path**
84-
- [x] Add `vup: [f32; 3]` to `ShaderConstants`
85-
- [x] Thread `vup` through `two_spheres()` and `CameraParams`
86-
- [x] Host computes `vup` dynamically (switch reference vector when pitch exceeds ±45°)
87-
- [x] Update tests to pass with dynamic `vup`
88-
89-
**Stage 2: Switch host to quaternions**
90-
- [x] Add `glam` crate dependency to host (for `Quat`)
91-
- [x] Replace `cam_yaw: f32` / `cam_pitch: f32` with `cam_orientation: Quat`
92-
- [x] Rewrite `update_camera()`:
93-
- Apply yaw rotation in world space (around world Y axis)
94-
- Apply pitch rotation in local space (around camera's right axis)
95-
- Multiply rotations into orientation quaternion
96-
- [x] Extract `cam_dir` and `vup` from quaternion for shader:
97-
- `cam_dir` = quaternion rotated `-Z` (forward)
98-
- `vup` = quaternion rotated `+Y` (up)
99-
- [x] Remove pitch clamping (quaternions handle full rotation)
100-
- [x] Tune mouse sensitivity for natural feel
101-
102-
### Future enhancements (not for first pass)
103-
104-
- [ ] **Dynamic ray sampling**: Lower samples per pixel when camera/world is moving for faster feedback, then accumulate rays over time when stationary for higher quality. Requires tracking frame-to-frame camera changes and maintaining an accumulation buffer.
105-
- [ ] Screenshot with current camera position
106-
10745
## Technical Debt
10846

10947
1. [ ] **Share types from `rtx-prim` with host**: The `rtx-prim` crate contains elementary types (`Vec3`, `Point3`, `Color`, etc.) that should be usable on both GPU and CPU. Currently `host/src/spline.rs` imports `Vec3` directly from `glam`, but ideally it would use the re-exports from `rtx-prim` to keep types consistent across the codebase. This requires making `rtx-prim` compilable for non-SPIR-V targets.

docs/tasks/benchmarking.md

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,41 @@ Track rendering performance across commits to detect regressions.
88
- `crates/host/src/camera_path.rs` - `CameraPath` and `CameraFrame` types (frame = position + look-at target)
99
- `crates/host/src/bench_app.rs` - Benchmark application with render loop
1010
- `crates/host/src/cli.rs` - CLI definitions including `bench` subcommand
11+
- `benchmarks/*.toml` - Benchmark definition files
1112

1213
## Overview
1314

14-
Run `cargo run --release -- bench` to execute a benchmark. The camera follows a predefined spline path through a scene, recording frame timing data. Results are saved to `bench-results/<git-sha>/<datetime>-<scene-name>.jsonl`.
15+
Run `cargo run --release -- bench` to execute all benchmarks. The camera follows a predefined spline path through a scene, recording frame timing data. Results are saved to `bench-results/<git-sha>/<datetime>-<benchmark-name>.jsonl`.
1516

1617
## Status
1718

18-
### Completed
19+
### Core Infrastructure
20+
1921
- [x] `CatmullRomSpline` - interpolates through control points
2022
- [x] `CameraPath` - combines position and look-at splines with duration
2123
- [x] `bench` CLI subcommand - runs benchmark with animated camera
2224
- [x] Benchmark exits after camera path completes
25+
26+
### Output & Metadata
27+
2328
- [x] Benchmark output file (JSONL format with metadata + per-frame records)
24-
- [x] `--scene` CLI argument
2529
- [x] Git SHA baked in at build time (7 characters)
2630
- [x] GPU info capture from wgpu adapter
2731
- [x] Frame timing (wall-clock)
2832
- [x] Datetime in output filename
2933

30-
### Also Completed
34+
### Benchmark Definitions
35+
3136
- [x] Benchmark definition files in `benchmarks/` directory (TOML format with scene + camera path)
37+
- [x] `--scene` CLI argument for single benchmark
3238
- [x] Output filename uses benchmark name (TOML filename) instead of scene name
33-
- [x] Run all benchmarks when no name specified (`cargo run --release -- bench`)
39+
- [x] Run all benchmarks when no name specified
40+
41+
### Future Enhancements
42+
43+
- [ ] Automated regression detection: compare results across commits
44+
- [ ] Warmup frames: discard first N frames to avoid startup costs
45+
- [ ] GPU timestamps: use wgpu timestamp queries for more accurate GPU timing
3446

3547
## Benchmark Definition Format
3648

@@ -59,7 +71,7 @@ Both `position` and `look_at` require at least 4 control points for the Catmull-
5971

6072
## Output Format
6173

62-
Single JSONL file per benchmark run: `bench-results/<git-sha>/<scene-name>.jsonl`
74+
Single JSONL file per benchmark run: `bench-results/<git-sha>/<datetime>-<benchmark-name>.jsonl`
6375

6476
**Every line is a single JSON object, including the first line (metadata).** This allows streaming writes and easy parsing.
6577

@@ -97,34 +109,3 @@ Single JSONL file per benchmark run: `bench-results/<git-sha>/<scene-name>.jsonl
97109
- `cam_pos` - camera position `[x, y, z]`
98110
- `cam_dir` - camera direction `[x, y, z]`
99111
- `cam_vup` - camera up vector `[x, y, z]`
100-
101-
## Implementation Plan
102-
103-
### Step 1: Add serde support
104-
- Add `serde` feature to `glam` dependency
105-
- Derive `Serialize` on `CameraPath`, `CatmullRomSpline`
106-
- Create metadata struct with GPU/CPU info
107-
108-
### Step 2: Capture GPU info
109-
- Extract adapter info from wgpu (`adapter.get_info()`)
110-
- Store name, driver, backend
111-
112-
### Step 3: Frame timing
113-
- Measure wall-clock time between frame start and `frame.present()`
114-
- Store in `Vec<FrameRecord>` during benchmark run
115-
- Note: This measures CPU submission + GPU present latency, not pure GPU render time. For more accurate GPU-only timing, wgpu timestamp queries could be added later (see Future Considerations).
116-
117-
### Step 4: Git SHA
118-
- Run `git rev-parse HEAD` at startup
119-
- Create output directory `bench-results/<sha>/`
120-
121-
### Step 5: Write output
122-
- After benchmark completes, write JSON file
123-
- Metadata on line 1, then one frame per line (JSONL)
124-
125-
## Future Considerations
126-
127-
- **Automated regression detection**: Compare results across commits
128-
- **Multiple runs**: Average multiple benchmark runs for stability
129-
- **Warmup frames**: Discard first N frames to avoid startup costs
130-
- **GPU timestamps**: Use wgpu timestamp queries for more accurate GPU timing

docs/tasks/live-mode.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Interactive Camera Controls (Live Mode)
2+
3+
Keyboard and mouse controls to move the camera in real-time during `live` mode.
4+
5+
## Overview
6+
7+
The camera state lives on the CPU and is passed to the shader each frame via `ShaderConstants`. The host tracks orientation using quaternions to avoid gimbal lock.
8+
9+
## Relevant Files
10+
11+
- `crates/host/src/live_app.rs` - `LiveApp` with camera state, input handling, `update_camera()`
12+
- `crates/shared/src/lib.rs` - `ShaderConstants` with `cam_pos`, `cam_dir`, `cam_vup`
13+
14+
## Controls
15+
16+
- WASD: horizontal movement (forward/back/strafe)
17+
- Space/C: up/down
18+
- Mouse: look direction
19+
- Q/Escape: quit
20+
21+
## Status
22+
23+
### Phase 1: CPU-side input and logging (no shader changes)
24+
25+
- [x] Add camera state to app struct (position, yaw, pitch)
26+
- [x] Track held keys (simple bools for W/A/S/D/Space/C)
27+
- [x] Track mouse delta for look direction
28+
- [x] Each frame: update position based on held keys and orientation, update orientation from mouse
29+
- [x] Log computed camera params to stdout
30+
- [x] Q key exits the loop
31+
32+
### Phase 2: Wire up to shader
33+
34+
- [x] Add camera fields to `ShaderConstants` (cam_pos, cam_dir, cam_fov, etc.)
35+
- [x] Modify shader to construct `Camera` from `ShaderConstants` instead of hardcoded values
36+
- [x] Remove or bypass per-scene camera construction
37+
38+
### Phase 3: Fix gimbal lock with quaternions
39+
40+
The camera previously crashed when looking straight up or down because `vup` became parallel to the view direction. This was fixed with quaternion-based orientation.
41+
42+
**Stage 1: Add `vup` to data path**
43+
- [x] Add `vup: [f32; 3]` to `ShaderConstants`
44+
- [x] Thread `vup` through `two_spheres()` and `CameraParams`
45+
- [x] Host computes `vup` dynamically
46+
- [x] Update tests to pass with dynamic `vup`
47+
48+
**Stage 2: Switch host to quaternions**
49+
- [x] Add `glam` crate dependency to host (for `Quat`)
50+
- [x] Replace `cam_yaw: f32` / `cam_pitch: f32` with `cam_orientation: Quat`
51+
- [x] Rewrite `update_camera()`:
52+
- Apply yaw rotation in world space (around world Y axis)
53+
- Apply pitch rotation in local space (around camera's right axis)
54+
- Multiply rotations into orientation quaternion
55+
- [x] Extract `cam_dir` and `vup` from quaternion for shader
56+
- [x] Remove pitch clamping (quaternions handle full rotation)
57+
- [x] Tune mouse sensitivity for natural feel
58+
59+
## Future Enhancements
60+
61+
- [ ] **Dynamic ray sampling**: Lower samples per pixel when camera/world is moving for faster feedback, then accumulate rays over time when stationary for higher quality. Requires tracking frame-to-frame camera changes and maintaining an accumulation buffer.
62+
- [ ] Screenshot with current camera position

0 commit comments

Comments
 (0)