ponko 0.0.1

A fast 2D game engine for simulating millions of things: ECS on all cores, hot reload, an in-game inspector, AI-agent control, and a C++ API.
Documentation
// Global illumination (Lighting::gi): light bounced off the world's
// surfaces, from a grid of probes around the camera (see gi.rs).
//
// The probe atlas holds, for each probe slot, an 8x8 tile of light (6x6
// octahedral directions in a one-texel border: rgb is the irradiance over
// pi, a which probe the slot holds) in its top part, and a 16x16 tile of
// distances (14x14 in a border: r the mean distance to what the probe sees
// that way, g its mean square) below. Tiles go 64 to a row.
//
// frame.gi[0]: xyz unused, w the probe spacing; frame.gi[1]: xyz probes
// along each axis, w the intensity (0: off); frame.gi[2]: xyz the grid's
// lowest probe (in probe cells), w the rows of tiles.
@group(0) @binding(10) var gi_atlas: texture_2d<f32>;

// The octahedral map of unit direction `d`: -1 to 1 in each axis.
fn gi_octahedral(d: vec3<f32>) -> vec2<f32> {
    let p = d.xy / (abs(d.x) + abs(d.y) + abs(d.z));
    if d.z >= 0.0 {
        return p;
    }
    return (1.0 - abs(p.yx)) * select(vec2<f32>(-1.0), vec2<f32>(1.0), p >= vec2<f32>(0.0));
}

// Where direction `d` is in a probe's tile of `size` texels (the inside is
// `size - 2`), the tile's corner at `corner`, in atlas uv.
fn gi_tile_uv(corner: vec2<f32>, size: f32, d: vec3<f32>) -> vec2<f32> {
    let texel = corner + 1.0 + (gi_octahedral(d) * 0.5 + 0.5) * (size - 2.0);
    return texel / vec2<f32>(textureDimensions(gi_atlas));
}

// The bounced light reaching a surface at `world` facing `n`, seen from
// direction `view`: rgb, and how much it counts (a, 0 to 1) against the
// sky and ground ambient light. It fades out past the grid's edges and
// where its probes haven't looked around yet.
fn gi_light(world: vec3<f32>, n: vec3<f32>, view: vec3<f32>) -> vec4<f32> {
    let intensity = frame.gi[1].w;
    if intensity <= 0.0 {
        return vec4<f32>(0.0);
    }
    let spacing = frame.gi[0].w;
    let counts = frame.gi[1].xyz;
    let lowest = frame.gi[2].xyz;
    let rows = frame.gi[2].w;
    // Looked up a little off the surface, towards the normal and the
    // viewer, so a surface doesn't shadow itself in its probes' distances.
    let p = world + (n * 0.2 + view * 0.1) * spacing;
    let local = p / spacing - lowest;
    let base = clamp(floor(local), vec3<f32>(0.0), counts - 2.0);
    let t = clamp(local - base, vec3<f32>(0.0), vec3<f32>(1.0));
    var sum = vec3<f32>(0.0);
    var total = 0.0;
    var covered = 0.0;
    for (var i = 0u; i < 8u; i++) {
        let offset = vec3<f32>(f32(i & 1u), f32((i >> 1u) & 1u), f32((i >> 2u) & 1u));
        let cell = lowest + base + offset;
        let probe = cell * spacing;
        let corner = mix(1.0 - t, t, offset);
        let trilinear = corner.x * corner.y * corner.z;
        // The probe's slot and tiles (the grid wraps around in its slots).
        let wrap = floor(cell / counts);
        let s = cell - wrap * counts;
        let slot = s.x + counts.x * (s.y + counts.y * s.z);
        let tile = vec2<f32>(slot % 64.0, floor(slot / 64.0));
        let light = textureSampleLevel(gi_atlas, sky_sampler, gi_tile_uv(tile * 8.0, 8.0, n), 0.0);
        let k = wrap - 8.0 * floor(wrap / 8.0);
        if abs(light.a - (1.0 + k.x + 8.0 * k.y + 64.0 * k.z)) > 0.25 {
            continue; // the slot doesn't hold this probe (yet)
        }
        covered += trilinear;
        // Probes behind the surface count less.
        let toward = normalize(probe - world);
        var w = (dot(toward, n) + 1.0) * 0.5;
        w = w * w + 0.2;
        // Only as far as the probe can see the point: Chebyshev's
        // inequality on the distances it saw that way.
        let away = p - probe;
        let r = length(away);
        let depth_uv = gi_tile_uv(vec2<f32>(tile.x * 16.0, rows * 8.0 + tile.y * 16.0), 16.0, away / max(r, 1e-4));
        let moments = textureSampleLevel(gi_atlas, sky_sampler, depth_uv, 0.0).rg;
        if r > moments.x {
            let variance = abs(moments.x * moments.x - moments.y);
            let d = r - moments.x;
            let visible = variance / (variance + d * d);
            w *= max(visible * visible * visible, 0.0);
        }
        w = max(w, 1e-6);
        // Crush tiny weights, so a barely visible probe doesn't tint the point.
        if w < 0.2 {
            w *= w * w / 0.04;
        }
        w *= trilinear;
        sum += light.rgb * w;
        total += w;
    }
    if total <= 0.0 {
        return vec4<f32>(0.0);
    }
    // Past the outermost probes, fade out over one spacing.
    let inside = min(local, counts - 1.0 - local);
    let edge = clamp(1.0 + min(inside.x, min(inside.y, inside.z)), 0.0, 1.0);
    return vec4<f32>(sum / total * intensity, edge * clamp(covered, 0.0, 1.0));
}