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:
- GLSL
- WGSL
void modifySplatColor(vec2 gaussianUV, inout vec4 color);
fn modifySplatColor(gaussianUV: vec2f, color: ptr<function, vec4f>);
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.color—rgbis the splat color,ais 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 pixelsuScreenSize— engine-providedvec4uniform: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:
- GLSL
- WGSL
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;
}
var uTintMap: texture_2d<f32>;
var uTintMapSampler: sampler;
uniform uScreenSize: vec4f;
fn modifySplatColor(gaussianUV: vec2f, color: ptr<function, vec4f>) {
let tint = textureSampleLevel(uTintMap, uTintMapSampler, pcPosition.xy * uniform.uScreenSize.zw, 0.0).rgb;
*color = vec4f((*color).rgb * tint, (*color).a);
}
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
- Vertex Stage Customization — move, scale and tint splats
- Relighting — light splats using a proxy mesh, built on this hook