Skip to main content

PASS_WGSL

Constant PASS_WGSL 

Source
pub const PASS_WGSL: &str = r#"
const FLAT_FILL_SHIFT: u32 = 4u;
const FLAT_DASHED: u32 = 256u;

struct FlatView {
    size: vec4f,
    light: vec4f,
    environment: vec4f,
}

@group(0) @binding(0) var<uniform> flat_view: FlatView;
@group(0) @binding(1) var flat_icons: texture_2d<f32>;
@group(0) @binding(2) var flat_icon_sampler: sampler;
@group(0) @binding(3) var flat_environment: texture_2d<f32>;
@group(0) @binding(4) var flat_environment_sampler: sampler;
@group(0) @binding(5) var flat_gradients: texture_2d<f32>;
@group(0) @binding(6) var flat_sprites: texture_2d<f32>;
@group(0) @binding(7) var flat_sprite_sampler: sampler;

struct FlatInstance {
    @location(0) axes: vec4f,
    @location(1) origin: vec4f,
    @location(2) bounds: vec4f,
    @location(3) shape: vec4f,
    @location(4) stroke: vec4f,
    @location(5) fill_top: vec4f,
    @location(6) fill_bottom: vec4f,
    @location(7) stroke_colour: vec4f,
    @location(8) icon: vec4f,
    @location(9) info: vec4u,
    @location(10) material: vec4f,
    @location(11) frame_x: vec4f,
    @location(12) frame_y: vec4f,
    @location(13) frame_z: vec4f,
    @location(14) corners: vec4f,
}

struct FlatVaryings {
    @builtin(position) position: vec4f,
    @location(0) local: vec2f,
    @location(1) @interpolate(flat) inverse: vec4f,
    @location(2) @interpolate(flat) origin: vec4f,
    @location(3) @interpolate(flat) shape: vec4f,
    @location(4) @interpolate(flat) stroke: vec4f,
    @location(5) @interpolate(flat) fill_top: vec4f,
    @location(6) @interpolate(flat) fill_bottom: vec4f,
    @location(7) @interpolate(flat) stroke_colour: vec4f,
    @location(8) @interpolate(flat) icon: vec4f,
    @location(9) @interpolate(flat) info: vec4u,
    @location(10) @interpolate(flat) material: vec4f,
    @location(11) @interpolate(flat) frame_x: vec4f,
    @location(12) @interpolate(flat) frame_y: vec4f,
    @location(13) @interpolate(flat) frame_z: vec4f,
    @location(14) @interpolate(flat) corners: vec4f,
}

fn flat_place(instance: FlatInstance, index: u32) -> FlatVaryings {
    let corner = vec2f(f32(index & 1u), f32((index >> 1u) & 1u)) * 2.0 - 1.0;
    let axes = mat2x2f(instance.axes.xy, instance.axes.zw);
    let inverse = mat2x2f(vec2f(axes[1].y, -axes[0].y), vec2f(-axes[1].x, axes[0].x))
        * (1.0 / determinant(axes));
    let margin = 1.5 * vec2f(
        length(vec2f(inverse[0].x, inverse[1].x)),
        length(vec2f(inverse[0].y, inverse[1].y)),
    );
    let local = instance.bounds.xy + corner * (instance.bounds.zw + margin);
    let pixel = axes * local + instance.origin.xy;
    var out: FlatVaryings;
    out.position = vec4f(
        pixel.x * flat_view.size.z * 2.0 - 1.0,
        1.0 - pixel.y * flat_view.size.w * 2.0,
        0.0,
        1.0,
    );
    out.local = local;
    out.inverse = vec4f(inverse[0], inverse[1]);
    out.origin = instance.origin;
    out.shape = instance.shape;
    out.stroke = instance.stroke;
    out.fill_top = instance.fill_top;
    out.fill_bottom = instance.fill_bottom;
    out.stroke_colour = instance.stroke_colour;
    out.icon = instance.icon;
    out.info = instance.info;
    out.material = instance.material;
    out.frame_x = instance.frame_x;
    out.frame_y = instance.frame_y;
    out.frame_z = instance.frame_z;
    out.corners = instance.corners;
    return out;
}

@vertex
fn flat_vertex(instance: FlatInstance, @builtin(vertex_index) index: u32) -> FlatVaryings {
    return flat_place(instance, index);
}

@vertex
fn flat_id_vertex(instance: FlatInstance, @builtin(vertex_index) index: u32) -> FlatVaryings {
    var out = flat_place(instance, index);
    if ((instance.info.x & 15u) == FLAT_SHADOW) {
        out.position = vec4f(2.0, 2.0, 2.0, 1.0);
    }
    return out;
}

struct FlatPaint {
    colour: vec4f,
    footprint: f32,
}

fn flat_field(v: FlatVaryings, kind: u32, p: vec2f) -> vec3f {
    if (kind == FLAT_RECT) {
        return flat_rect(p, v.shape.xy, v.corners);
    } else if (kind == FLAT_CIRCLE) {
        return flat_circle(p, v.shape.x);
    } else if (kind == FLAT_RING) {
        return flat_ring(p, v.shape.x, v.shape.y);
    } else if (kind == FLAT_ARC) {
        return flat_arc(p, v.shape.x, v.shape.y, v.shape.z, v.shape.w);
    }
    return vec3f(textureSampleLevel(flat_icons, flat_icon_sampler, v.icon.xy + p * v.icon.zw, 0.0).r, 0.0, 0.0);
}

fn flat_stroke_cover(v: FlatVaryings, kind: u32, p: vec2f, field: vec3f, inverse: mat2x2f) -> f32 {
    let icon = kind == FLAT_ICON_FILL || kind == FLAT_ICON_LINE;
    let band = vec3f(abs(field.x) - v.stroke.x * 0.5, flat_sign(field.x) * field.yz);
    var cover = select(flat_coverage(band, inverse), flat_coverage_even(band.x, inverse), icon);
    if ((v.info.x & FLAT_DASHED) != 0u) {
        var along = flat_circle_along(p, v.shape.x);
        if (kind == FLAT_RECT) {
            along = flat_rect_along(p, v.shape.xy, v.corners);
        }
        cover *= flat_coverage(flat_dash(along, v.stroke.y, v.stroke.z, v.stroke.w), inverse);
    }
    return cover;
}

fn flat_gradient_offset(row: i32, index: u32) -> f32 {
    return textureLoad(flat_gradients, vec2i(8 + i32(index / 4u), row), 0)[index % 4u];
}

fn flat_gradient_stop(row: i32, index: u32) -> vec4f {
    return textureLoad(flat_gradients, vec2i(i32(index), row), 0);
}

fn flat_gradient(v: FlatVaryings, p: vec2f) -> vec4f {
    let row = i32(v.fill_bottom.x);
    let count = u32(v.fill_bottom.y);
    let mode = u32(v.fill_bottom.z);
    let oklab = (mode & 2u) != 0u;
    let t = look_gradient_position(f32(mode & 1u), v.fill_top, p);
    var colour = flat_gradient_stop(row, count - 1u);
    if (t <= flat_gradient_offset(row, 0u)) {
        colour = flat_gradient_stop(row, 0u);
    } else {
        for (var i = 0u; i + 1u < count; i += 1u) {
            let a = flat_gradient_offset(row, i);
            let b = flat_gradient_offset(row, i + 1u);
            if (t < b) {
                colour = look_stop_mix(flat_gradient_stop(row, i), flat_gradient_stop(row, i + 1u), (t - a) / (b - a), oklab);
                break;
            }
        }
    }
    return vec4f(colour.rgb * colour.a, colour.a);
}

fn flat_fill_base(v: FlatVaryings, fill_mode: u32, p: vec2f) -> vec4f {
    if (fill_mode == 3u) {
        return flat_gradient(v, p);
    }
    if (fill_mode == 4u) {
        let texel = textureSampleLevel(flat_sprites, flat_sprite_sampler, v.icon.xy + p * v.icon.zw, 0.0) * v.fill_top;
        return vec4f(texel.rgb * texel.a, texel.a);
    }
    var t = 0.0;
    if (fill_mode == 2u) {
        t = clamp((p.y - v.origin.z) / (v.origin.w - v.origin.z), 0.0, 1.0);
    }
    let colour = mix(v.fill_top, v.fill_bottom, t);
    return vec4f(colour.rgb * colour.a, colour.a);
}

fn flat_fill_alpha(v: FlatVaryings, fill_mode: u32) -> f32 {
    return select(max(v.fill_top.a, v.fill_bottom.a), v.fill_bottom.a, fill_mode == 3u);
}

fn flat_paint(v: FlatVaryings) -> FlatPaint {
    let p = v.local;
    let inverse = mat2x2f(v.inverse.xy, v.inverse.zw);
    let kind = v.info.x & 15u;
    if (kind == FLAT_SHADOW) {
        let cover = flat_rounded_shadow(p - v.icon.zw, v.shape.xy, v.corners, v.icon.xy);
        return FlatPaint(vec4f(v.fill_top.rgb * v.fill_top.a, v.fill_top.a) * cover, 0.0);
    }
    let fill_mode = (v.info.x >> FLAT_FILL_SHIFT) & 15u;
    let opacity = bitcast<f32>(v.info.w);
    let icon = kind == FLAT_ICON_FILL || kind == FLAT_ICON_LINE;
    let field = flat_field(v, kind, p);
    var fill = vec4f(0.0);
    var fill_cover = 0.0;
    if (fill_mode != 0u) {
        fill_cover = select(flat_coverage(field, inverse), flat_coverage_even(field.x, inverse), icon);
        var base = flat_fill_base(v, fill_mode, p);
        let pattern = (v.info.x >> 12u) & 7u;
        if (pattern != 0u) {
            base = flat_pattern_over(base, pattern, v.icon, v.info.z, p, inverse);
        }
        fill = base * fill_cover;
        fill = flat_bevel_over(v, kind, p, field, inverse, fill, fill_cover);
    }
    var stroke = vec4f(0.0);
    var stroke_cover = 0.0;
    if (v.stroke.x > 0.0) {
        stroke_cover = flat_stroke_cover(v, kind, p, field, inverse);
        stroke = vec4f(v.stroke_colour.rgb * v.stroke_colour.a, v.stroke_colour.a) * stroke_cover;
    }
    let colour = (stroke + fill * (1.0 - stroke.a)) * opacity;
    let fill_seen = select(0.0, fill_cover, fill_mode != 0u && flat_fill_alpha(v, fill_mode) > 0.0);
    let stroke_seen = select(0.0, stroke_cover, v.stroke_colour.a > 0.0);
    let footprint = select(0.0, max(fill_seen, stroke_seen), opacity > 0.0);
    return FlatPaint(colour, footprint);
}

@fragment
fn flat_colour(v: FlatVaryings) -> @location(0) vec4f {
    return flat_paint(v).colour;
}

@fragment
fn flat_id(v: FlatVaryings) -> @location(0) u32 {
    if (flat_paint(v).footprint < 0.5) {
        discard;
    }
    return v.info.y;
}

struct FlatLayerVaryings {
    @builtin(position) position: vec4f,
    @location(0) @interpolate(flat) opacity: f32,
}

@vertex
fn flat_layer_vertex(@location(0) rect: vec4f, @location(1) opacity: vec4f, @builtin(vertex_index) index: u32) -> FlatLayerVaryings {
    let corner = vec2f(f32(index & 1u), f32((index >> 1u) & 1u));
    let pixel = mix(rect.xy, rect.zw, corner);
    var out: FlatLayerVaryings;
    out.position = vec4f(pixel.x * flat_view.size.z * 2.0 - 1.0, 1.0 - pixel.y * flat_view.size.w * 2.0, 0.0, 1.0);
    out.opacity = opacity.x;
    return out;
}

@group(1) @binding(0) var flat_layer: texture_2d<f32>;

@fragment
fn flat_layer_clear(v: FlatLayerVaryings) -> @location(0) vec4f {
    return vec4f(0.0);
}

@fragment
fn flat_layer_composite(v: FlatLayerVaryings) -> @location(0) vec4f {
    return textureLoad(flat_layer, vec2i(v.position.xy), 0) * v.opacity;
}
"#;