Skip to content

Cluster demo: Precision/Voltage concepts with screen-space reflections - #366

Merged
corepunch merged 1 commit into
mainfrom
cluster-concept-ssr
Oct 3, 2026
Merged

corepunch merged 1 commit into
mainfrom
cluster-concept-ssr

Conversation

@corepunch

Copy link
Copy Markdown
Owner

What

Rebuilds apps/cluster-demo to match two concept frames (01 Classic / Precision, 03 Cool / Voltage) and makes screen-space reflections work in the engine.

Scene (apps/cluster-demo/blender/build_cluster.py → tools/blender-export.py)

  • Classic: black-chrome mirror cups that reflect the neon ring and needle, spun dial faces, a recessed centre screen with a mirror road floor, glass plaques for the speed and the temperature/clock, and a glossy chin that mirrors the glows.
  • Voltage: neon chevron blade corridor (value-driven fill across the stack, depth falloff), glass gauge cards, mirror deck with an animated dot matrix, bottom info bar.
  • New shader groups, each a Blender node graph plus matching GLSL: IC_Neon, IC_DialFace, IC_Glass, IC_Plaque, IC_DotGrid, IC_Road, IC_Mirror (SSR + studio cubemap). The studio softboxes are one table in studio.py, used by both the cubemap bake and the Blender preview.
  • Oil gauge removed: neither concept has one. Demo curves and the navigation test were updated to match.

Engine

  • Two-pass SSR (plugins/SceneKit/RenderPass.c, source/renderer/r_main.c): reflective models draw their base in the main pass, the frame is captured, then they draw again adding only the reflected light (additive, no depth write). Glows drawn over reflective surfaces survive and show up in reflections. The shader tells the passes apart by u_sceneTextureSize (0 in the main pass).
  • Blended materials no longer write depth unless the shader sets DepthWriteEnabled. Depth state no longer carries over between draws, which was hiding dial numerals.
  • Supporting pieces: cubemap sampler uniforms, the scene capture API (ScreenSpaceCapture, Model3D.ScreenSpaceReflectionEnabled), and tests: test_shader_uniforms.c, test_screen_space_capture.c (now links and renders into its own depth FBO, since the macOS offscreen surface has no depth), test_scene_reflections.lua.

Tooling / app

  • Exporter draw order: opaque siblings now come before blended ones (back to front by bounding-box centre).
  • Exporter package.lua check: missing property types are matched by whole name (Fade was treated as present because FadeIn existed).
  • Cluster controller: RenderScreen never reached Lua and Screen is not a Node (no KeyDown). The controller now initialises from an orca.async coroutine and handles keys as Viewport_KeyDown with focus on the Viewport. CLUSTER_DEMO_START=voltage starts on Voltage for captures.

Testing

  • make test-headless passes.
  • make test-screen-space-capture passes.
  • build/bin/orca -test=apps/cluster-demo/Tests/navigation.lua passes.
  • Ran the exported app. It loads with no shader or resource errors, and SSR reflections show on the chrome, chin and decks (design/*-orca.jpg).

Reviewer notes

  • Arrow keys untested by hand: real Left/Right presses haven't been tried, because synthetic keystrokes don't reach the bare binary.
  • Engine captures predate the last tuning: design/*-orca.jpg were taken before the final blade/falloff tweak (the display locked). design/*-blender.png show the current state.
  • Generated content: Meshes/, Materials/, Shaders/, Scenes/ and Animations.* are exporter output.
  • History: apps/cluster-demo/HANDOVER.md has the full background.

🤖 Generated with Claude Code

…ace reflections

Scene (apps/cluster-demo, built by blender/build_cluster.py and exported):
- Classic/Precision: black-chrome mirror cups, spun dial faces, neon value
  ring, recessed centre screen with a mirror road floor, glass plaques for
  speed and temperature/clock, glossy chin reflecting the glows.
- Cool/Voltage: neon chevron blade corridor with value-driven fill and depth
  falloff, glass gauge cards, mirror deck with an animated dot matrix.
- New shader groups (node graph + matching GLSL): IC_Neon, IC_DialFace,
  IC_Glass, IC_Plaque, IC_DotGrid, IC_Road, IC_Mirror; shared studio table.

Engine:
- Two-pass screen-space reflections: reflective models draw their base in the
  main pass, the scene is captured, then their reflection is added. Glows over
  reflective surfaces survive and are reflected.
- Blended materials no longer write depth unless the shader asks; depth state
  no longer leaks between draws.
- Cubemap uniforms, scene capture helpers and tests (shader uniforms, GPU
  capture with a depth FBO, reflection opt-in).

Tooling and app:
- Exporter draws opaque siblings before blended ones and matches missing
  property types by whole name.
- Cluster controller initialises from a coroutine and takes keys on the
  Viewport (Screen gets neither RenderScreen nor KeyDown in Lua).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@corepunch
corepunch merged commit 65694d8 into main Oct 3, 2026
4 checks passed
@corepunch
corepunch deleted the cluster-concept-ssr branch October 3, 2026 14:09
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