codecraft 0.1.1

A minimalist 3D game engine built on parts of Bevy (ECS, color) with wgpu and winit: OpenPBR materials, clustered lighting, an immediate-mode UI, audio and gamepad haptics
Documentation
struct ScreenUniform {
    size: vec2<f32>,
    _pad: vec2<f32>,
};

@group(0) @binding(0)
var<uniform> screen: ScreenUniform;

struct InstanceInput {
    @location(1) pos: vec2<f32>,
    @location(2) size: vec2<f32>,
    @location(3) color: vec4<f32>,
    // The rectangle of the atlas to sample. An empty one means a flat quad,
    // which is what a panel, a button and a glyph all are.
    @location(4) uv: vec4<f32>,
};

struct VertexOutput {
    @builtin(position) clip_position: vec4<f32>,
    @location(0) color: vec4<f32>,
    @location(1) uv: vec2<f32>,
    // Flat: whether this quad is an icon is a property of the instance, and
    // interpolating it would give a fraction of an icon at the edges.
    @location(2) @interpolate(flat) textured: u32,
};

@group(0) @binding(1)
var atlas: texture_2d<f32>;
@group(0) @binding(2)
var atlas_sampler: sampler;

@vertex
fn vs_main(@location(0) corner: vec2<f32>, instance: InstanceInput) -> VertexOutput {
    let pixel_pos = instance.pos + corner * instance.size;
    let ndc_x = (pixel_pos.x / screen.size.x) * 2.0 - 1.0;
    let ndc_y = 1.0 - (pixel_pos.y / screen.size.y) * 2.0;

    var out: VertexOutput;
    out.clip_position = vec4<f32>(ndc_x, ndc_y, 0.0, 1.0);
    out.color = instance.color;
    out.uv = mix(instance.uv.xy, instance.uv.zw, corner);
    out.textured = select(0u, 1u, instance.uv.z > instance.uv.x);
    return out;
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    if in.textured == 0u {
        return in.color;
    }
    // The atlas holds white masks, so the icon's own colour is whatever asked
    // for it and the raster only says where the strokes are.
    let coverage = textureSample(atlas, atlas_sampler, in.uv).a;
    return vec4<f32>(in.color.rgb, in.color.a * coverage);
}