Skip to content

Add gsplatModifyPS hook for gsplat fragment color customization#8872

Merged
mvaligursky merged 3 commits into
mainfrom
mv-gsplat-modify-ps
Jun 11, 2026
Merged

Add gsplatModifyPS hook for gsplat fragment color customization#8872
mvaligursky merged 3 commits into
mainfrom
mv-gsplat-modify-ps

Conversation

@mvaligursky

Copy link
Copy Markdown
Contributor

Adds a user-overridable fragment shader chunk to gsplat rendering, allowing per-pixel customization of the final splat color. This complements the existing gsplatModifyVS vertex hook: effects that vary across a splat's footprint (e.g. sampling a screen-space texture) can now be done per fragment, avoiding the per-splat popping/flickering inherent to vertex-stage color modification.

Changes:

  • New gsplatModifyPS shader chunk (GLSL + WGSL) with a default no-op implementation:
    void modifySplatColor(vec2 gaussianUV, inout vec4 color) — called in the forward pass after gaussian falloff and dither, before premultiplication. gaussianUV is the fragment position within the gaussian footprint ((0,0) at center, length 1 at the clipping edge); color.a is the final fragment alpha and may be modified. Override it on app.scene.gsplat.material.
  • The GPU-sort (hybrid) renderer now syncs user material customizations (defines, parameters, shader chunks) from app.scene.gsplat.material to its render material, matching the quad renderer (extends the fix from Custom gsplat shader chunks don't see per-frame uniform updates in unified rendering mode (2.18.1) #8773 to the GPU-sort path), so the fragment hook works on both raster paths. Chunk copy is gated on a content hash to avoid per-frame shader rebuilds.
  • GsplatShaderEffect base script supports optional fragment chunks via getFragmentShaderGLSL() / getFragmentShaderWGSL(), and the vertex chunk is now optional too.
  • Supported by the raster gsplat renderers (CPU and GPU sort); the compute renderer does not use the fragment chunk.

Examples:

  • New gaussian-splatting/relighting example demonstrating the hook: a Draco-compressed proxy mesh of the splat scene is lit by standard lights (IBL with rotation/exposure controls, PCSS directional light, gizmo-positioned omni lights with static shadows) and rendered into a screen-aligned offscreen texture by the new GsplatRelighting script (scripts/esm/gsplat/gsplat-relighting.mjs). The gsplatModifyPS chunk then modulates each splat fragment by the mesh lighting sampled at its own screen position, relighting the splat scene per pixel.

Fixes #7438
Fixes #8462

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.

MRT issue for multiple gsplat color buffers Consider integrating GSplat shader with lit shader features.

1 participant