Skip to content

Scenery shaders: compile once, during the loading screen - #14

Merged
mbeczynski merged 1 commit into
mainfrom
perf/shader-material-cache
Oct 21, 2026
Merged

mbeczynski merged 1 commit into
mainfrom
perf/shader-material-cache

Conversation

@mbeczynski

Copy link
Copy Markdown
Contributor

Measurement (simulator, A/B old main 147f911 vs new main a6f231d)

Interleaved A/B/A/B, 5 regions × 2, live 45 s races with nitro:

  • Frame time / hitches: unchanged — p95 16.8–16.9 ms in both (simulator is vsync-capped at 60 fps), hitches > 25 ms: 320 vs 320 in total, CPU work per frame p95 0.36–0.42 vs 0.38–0.45 ms (noise).
  • Race loading: +0.75 s (~9%) in every pair. Track build 0.68 → 1.29 s: every scenery material loaded the Metal library and built its CustomMaterial from scratch (45 hazy materials + road, walls, ground, shopfronts).

Changes

  • SceneShaders: one Metal library, one template per surface shader; each material is a copy (a copy shares the compiled shader). Later races in the same session compile nothing.
  • The five scenery shaders compile at the start of the loading screen, while textures load in the background.
  • tools/scenery-shots.sh: absolute output path (simctl launch --stdout with a relative path fails with "No such process"); rotate only portrait screenshots.

Result (city + forest, 4 runs each build)

new main old main delta
before this PR 9.32 s 8.57 s +0.75 s
templates only 9.25 s 8.54 s +0.71 s
templates + warm-up (this PR) 9.31 s 8.78 s +0.53 s

Track build itself is now 0.25 s (old main 0.68 s); the warm-up shares the main thread with car loading, so the first race gains ~0.2 s net. The remaining ~0.5 s comes from the larger texture set (asphalt, new impostors) and first-time shader compilation.

Tests

  • swift test: 61 tests, 0 failures; Debug / Family / Release builds succeeded
  • Fixed-frame screenshots (city, snow): no visual change

🤖 Generated with Claude Code

https://claude.ai/code/session_018YYRkMvxEa4GxWLW2SrVyF

A/B on the simulator (old main vs new main, interleaved, 5 regions x 2): frame
time and hitches unchanged (p95 16.8-16.9 ms, 320 vs 320 hitches), but race
loading +0.75 s — track build 0.68 -> 1.29 s. Every scenery material loaded
the Metal library and built its CustomMaterial from scratch (45 hazy
materials, road, walls, ground, shopfronts).

- SceneShaders: one Metal library, one template per surface shader, copies
  for each material (a copy shares the compiled shader). Later races in the
  same session compile nothing.
- The five shaders compile at the start of the loading screen while textures
  load in the background. Track build 1.29 -> 0.25 s; first-race loading
  +0.75 -> +0.53 s vs old main (the warm-up shares the main thread with car
  loading).
- tools/scenery-shots.sh: absolute output path (simctl launch --stdout with a
  relative path fails with "No such process"); rotate only portrait shots.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018YYRkMvxEa4GxWLW2SrVyF
@mbeczynski
mbeczynski merged commit b1bf97e into main Oct 21, 2026
1 check passed
@mbeczynski
mbeczynski deleted the perf/shader-material-cache branch October 21, 2026 03:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant