Skip to content

Reflect the playfield in the balls, light ray-traced reflections with every lamp, and toggle depth of field - #38

Merged
freezy merged 6 commits into
masterfrom
fix/inserts
Nov 1, 2026
Merged

freezy merged 6 commits into
masterfrom
fix/inserts

Conversation

@freezy

@freezy freezy commented Nov 1, 2026

Copy link
Copy Markdown
Member

HDRP side of the player's new graphics options: the balls reflect the playfield, ray-traced reflections see every lamp, and depth of field can be toggled at runtime. It implements the hooks added in freezy/VisualPinball.Engine#612 and needs that PR.

Summary

  • Ball reflections. Each ball gets a reflection probe the size of the ball. A custom pass fills its cubemap from the frame the camera just rendered: every direction is marched through the depth buffer, which finds what stands on the playfield, then falls back to the playfield plane or the sky. HDRP applies the cubemap through each ball's own material, so every ball look keeps working, and SSR still wins where it finds a hit. The graphics applier adds the component to the main camera while the setting is on. It costs about 0.14 ms of GPU and 0.35 ms of CPU time per ball.
  • Ray-traced reflections light every lamp. HDRP's light cluster is a fixed 64×32×64 grid around the camera, and at the default range the playfield fell into a few 30 cm cells holding more lamps than a cell can, so HDRP left lamps out of the reflections. The range now shrinks every frame to the smallest cube around the camera that still holds the playfield up to the glass, and a LightCluster is added when a ray-traced effect is on and the profiles have none. Lamp lights are included in ray tracing.
  • Depth of field. The applier handles VpeGraphics.SetDepthOfField by adding the auto focus to the main camera, or restarting it so it finds the volume a table load brought. The auto focus compute shader moves to Resources (same GUID), so a camera that gets the component at runtime still finds it.
  • Shared frame settings. Ball reflections and the auto focus both turn on the camera's custom pass frame setting. CameraFrameSettings counts who needs a field and restores the camera's own value only when the last one lets go, so turning one off no longer switches the other's pass off.
  • Inserts follow the core's new color preset apply signature.
  • Look dev: inserts are cut after a stale cutout reference, and the tool no longer waits on missing screenshots.

Testing

  • Used in the HDRP player on Terminator 2: ball reflections on and off, depth of field toggled with D, and both together.

…he light cluster to the playfield.

HDRP's ray tracing light cluster is a fixed 64x32x64 grid around the camera. At the default range, the playfield fell into a few 30 cm cells, many of them holding more lamps than a cell can, and HDRP leaves the extra lamps out of the reflections. Every frame, the range now shrinks to the smallest cube around the camera that still holds the playfield up to the glass, which keeps the cells a few centimetres wide. A LightCluster component is added when a ray-traced effect is on and the profiles have none.

Lamp lights are now included in ray tracing. The bulb models had left it off, and packages exported with them still do.
Each ball gets a reflection probe the size of the ball. A custom pass fills
its cubemap from the frame the camera just rendered: every direction is
marched through the depth buffer, which finds what stands on the playfield,
and falls back to where it meets the playfield plane, or to the sky. HDRP
applies the cubemap through each ball's own material, so every ball look
keeps working, and SSR still wins where it finds a hit.

The graphics applier puts the component on the main camera while the setting
is on. Turning it off restores the camera's frame settings. It costs about
0.14 ms of GPU and 0.35 ms of CPU time per ball.
…mera's frame settings.

The applier handles VpeGraphics.SetDepthOfField by adding the auto focus to
the main camera, or restarting it so it finds the volume a table load
brought.

The auto focus' compute shader moves to Resources (same GUID), so a camera
that gets the component at runtime still finds it.

Ball reflections and the auto focus both turn on the camera's custom pass
frame setting. CameraFrameSettings counts who needs a field and restores the
camera's own value only when the last one lets go, so turning one off no
longer switches the other's pass off.
@greptile-apps

greptile-apps Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The latest change appears safe to merge and fixes the previously reported depth-of-field issue.

Summary

Adds playfield reflections in balls, fits ray-traced lighting around the playfield, and supports runtime depth-of-field controls.

  • Each ball reflects the playfield around it.
  • Ray-traced table lighting includes pinball lamps.
  • Depth of field now follows the player’s runtime toggle.
  • Thumbnail runs recover insert cutouts and wait for screenshots.
  • The insert showcase uses the current color-preset call.

Reviews (2) · Last reviewed commit: "graphics: turn a table's own depth of fi..." · Reviewed by Greptile

Comment thread Runtime/HdrpGraphicsApplier.cs Resolved
Switching depth of field off only stopped the auto focus, so a table
whose profile brings a depth of field of its own stayed blurred: with no
auto focus on the camera nothing touched it, and an auto focus that was
already off didn't reach the volume a new table load brought. Off now
sets the focus mode off on every global volume the camera sees.
@freezy
freezy merged commit 3fc2f1e into master Nov 1, 2026
5 checks passed
@freezy
freezy deleted the fix/inserts branch November 1, 2026 15:28
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