gled 2.14.1

gled is an application for creating animations and effects on artnet or dmx installations
@group(0) @binding(0)
var<storage> positions: array<f32, 10880>;

@group(0) @binding(1)
var sam: sampler;

@group(0) @binding(2)
var tex: texture_2d<f32>;

@group(0) @binding(3)
var<storage, read_write> output: array<u32, 4096>;

struct Uniforms {
    // colors: 288 bytes
    primary_color: vec3<f32>,
    secondary_color: vec3<f32>,
    gradient_colors: array<vec3<f32>, 16>,

    // state: 64 bytes
    random: f32,
    beat_progression: f32,
    beats_per_minute: f32,
    frame_rate: f32,
    opacity: f32,
    color_shift: f32,
    speed: f32,
    u32_0: u32,
    u32_1: u32,
    u32_2: u32,
    f32_0: f32,
    f32_1: f32,
    f32_2: f32,
    f32_3: f32,
    f32_4: f32,
    f32_5: f32,
};

@group(0) @binding(4)
var<uniform> uniforms: Uniforms;

const LAMPS_PER_UNIVERSE: u32 = 170u;

@compute
@workgroup_size(1)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
    let universe: u32 = global_id.x;

    // we get the colors for 4 lamps at a time as we need to interleafe those to fill up 12 bytes 
    // in this pattern: `rbgr grbg bbgr` as access is only possible with 32bit at a time.
    let idx: u32 = global_id.y;
    let start_idx: u32 = universe * LAMPS_PER_UNIVERSE * 2u + idx * 8u;

    var colors: array<u32, 12>;
    for (var i = 0u; i < 4u; i++) {
        if (idx == 42u && i > 1u) {
            continue;
        }

        let x: f32 = positions[start_idx + i * 2u];
        let y: f32 = positions[start_idx + i * 2u + 1u];

        let position_tex = vec2<f32>(x, y);
        var color: vec3<f32> = textureSampleLevel(tex, sam, position_tex, 0.).rgb;
        if 2. - x < 0.001 && 2. - y < 0.001 {
            color = vec3(0.);
        }
        colors[i * 3u] = u32(round(color.r * uniforms.opacity * 254.)) & 0x000000ffu;
        colors[i * 3u + 1u] = u32(round(color.g * uniforms.opacity * 254.)) & 0x000000ffu;
        colors[i * 3u + 2u] = u32(round(color.b * uniforms.opacity * 254.)) & 0x000000ffu;
    }

    let index = universe * 128u + idx * 3u;
    output[index]      = colors[0] | colors[1] << 8u | colors[2] << 16u  | colors[3] << 24u;
    if (idx < 42u) {
        output[index + 1u] = colors[4] | colors[5] << 8u | colors[6] << 16u  | colors[7] << 24u;
        output[index + 2u] = colors[8] | colors[9] << 8u | colors[10] << 16u | colors[11] << 24u;
    } else {
        output[index + 1u] = colors[4] | colors[5] << 8u;
    }
}