Hover pick costs ~3.5 ms of main-thread time per frame: move it off the CPU raycast #702

Closed
opened 2026-10-12 09:20:21 +00:00 by sky_line · 2 comments
Owner

Measured (2026-10-12, perf sample of the main thread, ~68 FPS scene): LL_updateUI is ~3.6 ms/frame, and ~3.5 ms of that is not UI: it is the world hover pick (LLToolPie::handleHover -> pickImmediate -> cursorIntersect).

Breakdown of the CPU raycast (overlapping): alpha-tested face tests (LLCleanPickAlpha::intersectFace) ~2.4 ms, worn attachments (vkIntersectAttachmentObject) ~1.6 ms, HUD (vkPickHUD) ~1.3 ms, instance store segment test ~2.1 ms.

The #361 throttle (re-pick only on mouse / modifier / camera change or every 100 ms) doesn't help much in practice: the camera changes on almost every frame.

Direction (to be decided before work starts): answer the hover pick on the GPU against what was drawn (the rigged/particle pick in llcleanpickvk already does this), harvested a couple of frames late; keep an exact pick for clicks. Design questions are being discussed first.

**Measured (2026-10-12, perf sample of the main thread, ~68 FPS scene):** `LL_updateUI` is ~3.6 ms/frame, and ~3.5 ms of that is not UI: it is the world hover pick (`LLToolPie::handleHover` -> `pickImmediate` -> `cursorIntersect`). Breakdown of the CPU raycast (overlapping): alpha-tested face tests (`LLCleanPickAlpha::intersectFace`) ~2.4 ms, worn attachments (`vkIntersectAttachmentObject`) ~1.6 ms, HUD (`vkPickHUD`) ~1.3 ms, instance store segment test ~2.1 ms. The #361 throttle (re-pick only on mouse / modifier / camera change or every 100 ms) doesn't help much in practice: the camera changes on almost every frame. **Direction (to be decided before work starts):** answer the hover pick on the GPU against what was drawn (the rigged/particle pick in `llcleanpickvk` already does this), harvested a couple of frames late; keep an exact pick for clicks. Design questions are being discussed first.
sky_line added this to the Slipstream project 2026-10-12 09:20:21 +00:00
Author
Owner

Design decided (2026-10-12):

  • Raster cursor pick. A compute pass selects the instances whose bounds the cursor ray crosses (frustum/ray test, not occlusion-culled, so a clicky behind a mesh body is still a candidate); they are drawn into a 1-pixel target with the real vertex/alpha shaders (drawn LOD, pre-skinned rigged stream, HUD layer), keeping a list of the nearest hits. The CPU applies the existing precedence rules (ITEM / TOUCH / WEARER claims, rigid clickies through mesh bodies, transparent-button and highlight-transparent rules) to those few hits. Answer harvested ~2 frames late, aged by frame.
  • Clicks: use the per-frame GPU answer when it covers the click ray; otherwise the exact synchronous CPU pick.
  • Rigged pick (#255): folded into the new pass; the separate ray-query / skinned-triangle rigged pick retires.
  • The CPU fallback also gets the cheap fixes: camera-change test with a tolerance (the exact comparison re-picks every frame) and a HUD screen-bounds reject.
Design decided (2026-10-12): - **Raster cursor pick.** A compute pass selects the instances whose bounds the cursor ray crosses (frustum/ray test, not occlusion-culled, so a clicky behind a mesh body is still a candidate); they are drawn into a 1-pixel target with the real vertex/alpha shaders (drawn LOD, pre-skinned rigged stream, HUD layer), keeping a list of the nearest hits. The CPU applies the existing precedence rules (ITEM / TOUCH / WEARER claims, rigid clickies through mesh bodies, transparent-button and highlight-transparent rules) to those few hits. Answer harvested ~2 frames late, aged by frame. - **Clicks:** use the per-frame GPU answer when it covers the click ray; otherwise the exact synchronous CPU pick. - **Rigged pick (#255):** folded into the new pass; the separate ray-query / skinned-triangle rigged pick retires. - The CPU fallback also gets the cheap fixes: camera-change test with a tolerance (the exact comparison re-picks every frame) and a HUD screen-bounds reject.
Author
Owner

Shipped in 1.3.0 Beta 7: hover and click picking run on the GPU (about 3.5 ms less main-thread time per frame).

Shipped in 1.3.0 Beta 7: hover and click picking run on the GPU (about 3.5 ms less main-thread time per frame).
sky_line 2026-10-12 15:12:22 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sky_line/Slipstream#702
No description provided.