Skip to main content

Fragment Stage

The gsplatModifyPS chunk customizes the final splat color in the fragment stage. It runs once per covered pixel, so effects can vary smoothly across a splat's footprint — something the per-splat vertex stage cannot do.

View Live Example - The Relighting technique is built on this hook.

Relighting

Overridable Function

The chunk overrides a single function:

void modifySplatColor(vec2 gaussianUV, inout vec4 color);

It is called in the forward pass after the gaussian falloff and opacity dither have been evaluated, just before the color is premultiplied and output:

  • gaussianUV — the fragment's position within the gaussian footprint: (0,0) at the splat center, length 1 at the edge where the splat is clipped. dot(gaussianUV, gaussianUV) gives the normalized squared radius used by the falloff.
  • colorrgb is the splat color, a is the final fragment alpha. Both can be modified; alpha changes affect the blending weight, enabling custom falloffs or per-pixel fades.

Available Inputs

Inside the chunk you can also use:

  • gl_FragCoord (GLSL) / pcPosition (WGSL) — the fragment's framebuffer position in pixels
  • uScreenSize — engine-provided vec4 uniform: xy = render target size, zw = inverse size
  • Your own uniforms and textures, declared in the chunk and driven via material parameters

Example

This chunk samples a screen-aligned texture at the fragment's own screen position and modulates the splat color by it — the core of the Relighting technique:

uniform sampler2D uTintMap;
uniform vec4 uScreenSize;

void modifySplatColor(vec2 gaussianUV, inout vec4 color) {
vec3 tint = textureLod(uTintMap, gl_FragCoord.xy * uScreenSize.zw, 0.0).rgb;
color.rgb *= tint;
}

Apply it the same way as the vertex chunk, using the gsplatModifyPS key:

const sceneMat = app.scene.gsplat.material;

sceneMat.getShaderChunks('glsl').set('gsplatModifyPS', glslFragShader);
sceneMat.getShaderChunks('wgsl').set('gsplatModifyPS', wgslFragShader);
sceneMat.setParameter('uTintMap', tintTexture);
sceneMat.update();

See Also