roxlap-gpu 0.10.0

GPU compute-shader renderer for the roxlap voxel engine (WGPU + WGSL DDA marcher). Sibling to roxlap-core's CPU opticast.
Documentation
// GPU.0 probe blit — upscales the low-res compute output into the
// swapchain via a fullscreen triangle. Nearest-neighbour sampling
// preserves the chunky pixel aesthetic.

struct VsOut {
    @builtin(position) clip: vec4<f32>,
    @location(0) uv: vec2<f32>,
};

@vertex
fn vs_main(@builtin(vertex_index) vid: u32) -> VsOut {
    // Single triangle covering NDC [-1, 3] × [-1, 3]; clipped to the
    // viewport. vid ∈ {0, 1, 2}.
    let x = f32((vid << 1u) & 2u) * 2.0 - 1.0;
    let y = 1.0 - f32(vid & 2u) * 2.0;
    var out: VsOut;
    out.clip = vec4<f32>(x, y, 0.0, 1.0);
    // Map NDC to UV; flip y so (0,0) is top-left like the compute
    // shader's pixel coordinates.
    out.uv = vec2<f32>((x + 1.0) * 0.5, 1.0 - (y + 1.0) * 0.5);
    return out;
}

@group(0) @binding(0) var src: texture_2d<f32>;
// Kept for bind-group/layout compatibility; the pixel-exact `textureLoad`
// path below doesn't sample, so this sampler is unused.
@group(0) @binding(1) var samp: sampler;

@fragment
fn fs_main(in: VsOut) -> @location(0) vec4<f32> {
    // Pixel-exact fetch instead of `textureSample`. Normalised-UV
    // sampling of the compute pass's storage texture mis-strided on
    // some WebGPU/Dawn drivers (the output tiled across the screen);
    // resolving the source texel by `uv * dimensions` + `textureLoad`
    // reads the logical texel directly, with no sampler/row-stride
    // ambiguity. Nearest-neighbour by construction — preserves the
    // chunky retro look and still upscales a lower-res source (the
    // GPU.0 probe) correctly.
    let dims = vec2<f32>(textureDimensions(src));
    let texel = vec2<i32>(clamp(in.uv, vec2<f32>(0.0), vec2<f32>(0.999999)) * dims);
    return textureLoad(src, texel, 0);
}