68 lines
No EOL
2.4 KiB
WebGPU Shading Language
68 lines
No EOL
2.4 KiB
WebGPU Shading Language
struct GridParams {
|
|
cols: u32,
|
|
rows: u32,
|
|
cell_w: f32,
|
|
cell_h: f32,
|
|
window_w: f32,
|
|
window_h: f32,
|
|
atlas_cols: u32,
|
|
atlas_rows: u32,
|
|
atlas_size: f32,
|
|
flip_y: f32,
|
|
_pad1: u32,
|
|
_pad2: u32,
|
|
}
|
|
|
|
@group(0) @binding(0) var font_atlas: texture_2d<f32>;
|
|
@group(0) @binding(1) var font_sampler: sampler;
|
|
@group(0) @binding(2) var<uniform> grid: GridParams;
|
|
@group(0) @binding(3) var<storage, read> char_data: array<vec4<u32>>;
|
|
|
|
struct VIn { @location(0) pos: vec2f, @location(1) uv: vec2f, };
|
|
struct VOut { @builtin(position) position: vec4f, @location(0) uv: vec2f, @location(1) fg: vec4f, @location(2) bg: vec4f, @location(3) attr: u32, @location(4) cell_uv: vec2f, };
|
|
|
|
fn unpack_color(packed: u32) -> vec4f {
|
|
return vec4f(
|
|
f32((packed >> 24u) & 0xFFu) / 255.0,
|
|
f32((packed >> 16u) & 0xFFu) / 255.0,
|
|
f32((packed >> 8u) & 0xFFu) / 255.0,
|
|
1.0,
|
|
);
|
|
}
|
|
|
|
@vertex
|
|
fn vs_main(input: VIn, @builtin(instance_index) iid: u32) -> VOut {
|
|
let col = iid % grid.cols;
|
|
let row = iid / grid.cols;
|
|
let x = f32(col) * grid.cell_w + input.pos.x * grid.cell_w;
|
|
let y = f32(row) * grid.cell_h + input.pos.y * grid.cell_h;
|
|
let ndc_x = x / grid.window_w * 2.0 - 1.0;
|
|
let ndc_y = grid.flip_y * (1.0 - y / grid.window_h * 2.0);
|
|
var out: VOut;
|
|
out.position = vec4f(ndc_x, ndc_y, 0.0, 1.0);
|
|
let entry = char_data[iid];
|
|
out.fg = unpack_color(entry.y);
|
|
out.bg = unpack_color(entry.z);
|
|
out.attr = entry.w;
|
|
let slot = entry.x;
|
|
let ac = slot % grid.atlas_cols;
|
|
let ar = slot / grid.atlas_cols;
|
|
let uvx = (f32(ac) + input.uv.x) * grid.cell_w / grid.atlas_size;
|
|
let uvy = (f32(ar) + input.uv.y) * grid.cell_h / grid.atlas_size;
|
|
out.uv = vec2f(uvx, uvy);
|
|
out.cell_uv = input.uv;
|
|
return out;
|
|
}
|
|
|
|
@fragment
|
|
fn fs_main(@location(0) uv: vec2f, @location(1) fg: vec4f, @location(2) bg: vec4f, @location(3) attr: u32, @location(4) cell_uv: vec2f) -> @location(0) vec4f {
|
|
let texel = textureSample(font_atlas, font_sampler, uv);
|
|
let glyph_alpha = texel.a;
|
|
let is_color = texel.r != 1.0 || texel.g != 1.0 || texel.b != 1.0;
|
|
let glyph_color = select(fg.rgb * texel.rgb, texel.rgb, is_color);
|
|
var color = vec4f(mix(bg.rgb, glyph_color, glyph_alpha), 1.0);
|
|
if (attr & 4u) != 0u && cell_uv.y >= 0.79 && cell_uv.y <= 0.85 {
|
|
color = vec4f(fg.rgb, 1.0);
|
|
}
|
|
return color;
|
|
} |