Skip to content

Add foveated contribution culling to the GPU-sort gsplat renderer#8869

Merged
mvaligursky merged 1 commit into
mainfrom
mv-gsplat-foveated-cull
Jun 10, 2026
Merged

Add foveated contribution culling to the GPU-sort gsplat renderer#8869
mvaligursky merged 1 commit into
mainfrom
mv-gsplat-foveated-cull

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Adds an optional foveated mode to the GPU-sort (hybrid) gsplat renderer's contribution culling: the minContribution threshold is raised radially from the screen centre, so low-impact splats are culled increasingly toward the screen edges — where peripheral overdraw dominates XR frame cost — while the centre is untouched.

The effective threshold is:

minContribution + foveationStrength * smoothstep(foveationCenter, 1.0, length(ndc))

with r = length(ndc) being 0 at the screen centre, 1 at the edge (corners beyond 1 get full strength).

Changes:

  • GSplatParams.foveationStrength (default 0 = off) and GSplatParams.foveationCenter (default 0.3, the protected-centre radius in NDC units). Only used by the GSPLAT_RENDERER_RASTER_GPU_SORT renderer.
  • The values flow through GSplatManager → projector dispatch params → projector UBO → the shared computeSplatCov cull, which applies the radial boost. With strength 0 the cull is bit-identical to before (additive 0); no shader variant is added — the cost is a few ALU once per splat in the projection compute pass.
  • Stereo XR: culling is evaluated from eye-0 NDC (consistent with the existing shared stereo cull); the projector's pick variant shares the same uniforms so picking stays consistent with the rendered set.
  • The compute-local renderer is unaffected — it passes inert constants (strength 0) to the shared projection helper.

API Changes:

  • GSplatParams#foveationStrength — new property (number, default 0).
  • GSplatParams#foveationCenter — new property (number, default 0.3).

Examples:

  • gaussian-splatting-xr/vr-lod: new in-XR HUD number row to tune the strength live (+/- 5, clamped 0–50).

Performance:

  • Intended as a cheap complement to fixed (resolution) foveation on standalone XR devices: fewer surviving splats at the periphery → fewer quads sorted/rasterized → less peripheral overdraw, which profiling on Quest 3 showed to be the dominant frame cost.

Raises the contribution-culling threshold radially from the screen centre, so
low-impact splats are culled increasingly toward the edges where peripheral
overdraw dominates XR frame cost. Effective threshold:
minContribution + foveationStrength * smoothstep(foveationCenter, 1, length(ndc))

- GSplatParams: new foveationStrength (default 0 = off) and foveationCenter
  (default 0.3, protected-centre radius) — GPU-sort (hybrid) renderer only.
- Projector: values plumbed via dispatch params and the projector UBO; the
  cull in computeSplatCov applies the radial boost (exact no-op at strength 0).
- Compute-local renderer is unaffected (passes inert constants).
- vr-lod example: in-XR HUD number row to tune strength (+/- 5, 0..50).
@github-actions

Copy link
Copy Markdown

Public API report

This PR changes the public API surface (+4 / −0), per the docs' rules (@ignore / @Private / undocumented are excluded).

Show API diff
+GSplatParams.get foveationCenter(): number
+GSplatParams.get foveationStrength(): number
+GSplatParams.set foveationCenter(value: number)
+GSplatParams.set foveationStrength(value: number)

Informational only — this never fails the build.

@mvaligursky mvaligursky merged commit f451f17 into main Jun 10, 2026
9 checks passed
@mvaligursky mvaligursky deleted the mv-gsplat-foveated-cull branch June 10, 2026 14:24
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