const DIRS = array(vec2i(1, 0), vec2i(0, 1), vec2i(-1, 0), vec2i(0, -1)); const ATTEN: f32 = 0.999; const W_FWD: f32 = 0.70; const W_SIDE: f32 = 0.15; @group(0) @binding(0) var scene: texture_2d; @group(0) @binding(1) var src: texture_2d_array; @group(0) @binding(2) var dst: texture_storage_2d_array; @compute @workgroup_size(8, 8, 1) fn propagate(@builtin(global_invocation_id) gid: vec3) { let dims = textureDimensions(dst); if gid.x >= dims.x || gid.y >= dims.y { return; } let p = vec2(gid.xy); let s = textureLoad(scene, p, 0); let t = s.a; for (var d = 0u; d < 4u; d++) { let q = p - DIRS[d]; var inc = vec3f(0.0); inc += textureLoad(src, q, d, 0).rgb * W_FWD; inc += textureLoad(src, q, (d + 1u) % 4u, 0).rgb * W_SIDE; inc += textureLoad(src, q, (d + 3u) % 4u, 0).rgb * W_SIDE; let o = inc * t * ATTEN + s.rgb * 0.25; textureStore(dst, p, d, vec4f(o, 1.0)); } }