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;
}
"#;