← Build a viewer

examples/mini_splat.wgsl

Repository source snapshot · Plain text · GitHub

1// Teaching compute rasterizer: one invocation owns one pixel, no triangle pass.2// Inputs must already be sorted back-to-front. Complexity is O(pixels*splats).3struct Splat {4  mean_sigma: vec4<f32>, // camera-space xyz (+Z forward), world-space sigma5  rgb_alpha: vec4<f32>,6};7@group(0) @binding(0) var<storage, read> splats: array<Splat>;8@group(0) @binding(1) var output: texture_storage_2d<rgba8unorm, write>;910@compute @workgroup_size(8, 8)11fn main(@builtin(global_invocation_id) id: vec3<u32>) {12  let size = textureDimensions(output);13  if any(id.xy >= size) { return; }14  let pixel = vec2<f32>(id.xy) + 0.5;15  let focal = 0.8 * f32(size.x);16  var color = vec3<f32>(0.0);17  for (var i = 0u; i < arrayLength(&splats); i++) {18    let s = splats[i];19    let p = s.mean_sigma.xyz;20    if p.z <= 0.05 { continue; }21    let center = focal * p.xy / p.z + vec2<f32>(size) * 0.5;22    // Isotropic world covariance projected through the perspective Jacobian.23    let jx = vec3<f32>(focal/p.z, 0.0, -focal*p.x/(p.z*p.z));24    let jy = vec3<f32>(0.0, focal/p.z, -focal*p.y/(p.z*p.z));25    let variance = s.mean_sigma.w * s.mean_sigma.w;26    let a = variance * dot(jx, jx) + 0.3;27    let b = variance * dot(jx, jy);28    let c = variance * dot(jy, jy) + 0.3;29    let d = pixel - center;30    let power = -0.5 * (c*d.x*d.x - 2.0*b*d.x*d.y + a*d.y*d.y) / (a*c-b*b);31    let alpha = min(0.99, s.rgb_alpha.a * exp(power));32    if alpha < 1.0/255.0 { continue; }33    color = s.rgb_alpha.rgb * alpha + color * (1.0-alpha);34  }35  textureStore(output, vec2<i32>(id.xy), vec4<f32>(color, 1.0));36}37