|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| struct Params {
|
| scale: vec2<f32>,
|
| offset: vec2<f32>,
|
| grid: u32,
|
| pad0: u32,
|
| pad1: u32,
|
| pad2: u32,
|
| };
|
| var<storage, read> params: Params;
|
| var<storage, read> cells: array<f32>;
|
|
|
| struct VsOut {
|
| @builtin(position) position: vec4<f32>,
|
| @location(0) uv: vec2<f32>,
|
| };
|
|
|
| @vertex
|
| fn vs_main(@builtin(vertex_index) vi: u32) -> VsOut {
|
|
|
| var xs = array<f32, 6>(-1.0, 1.0, -1.0, -1.0, 1.0, 1.0);
|
| var ys = array<f32, 6>(-1.0, -1.0, 1.0, 1.0, -1.0, 1.0);
|
| let x = xs[vi];
|
| let y = ys[vi];
|
|
|
| var out: VsOut;
|
| out.position = vec4<f32>(
|
| x * params.scale.x + params.offset.x,
|
| y * params.scale.y + params.offset.y,
|
| 0.0,
|
| 1.0,
|
| );
|
|
|
|
|
|
|
| out.uv = vec2<f32>(x * 0.5 + 0.5, 0.5 - y * 0.5);
|
| return out;
|
| }
|
|
|
| fn cell(ix: i32, iy: i32) -> vec3<f32> {
|
| let g = i32(params.grid);
|
| let x = clamp(ix, 0, g - 1);
|
| let y = clamp(iy, 0, g - 1);
|
| let base = u32((y * g + x) * 3);
|
| return vec3<f32>(cells[base], cells[base + 1u], cells[base + 2u]);
|
| }
|
|
|
| @fragment
|
| fn fs_main(in: VsOut) -> @location(0) vec4<f32> {
|
| let p = in.uv * f32(params.grid) - 0.5;
|
| let corner = floor(p);
|
| let frac = p - corner;
|
| let ix = i32(corner.x);
|
| let iy = i32(corner.y);
|
|
|
| let top = mix(cell(ix, iy), cell(ix + 1, iy), frac.x);
|
| let bottom = mix(cell(ix, iy + 1), cell(ix + 1, iy + 1), frac.x);
|
| let rgb = clamp(mix(top, bottom, frac.y), vec3<f32>(0.0), vec3<f32>(1.0));
|
| return vec4<f32>(rgb, 1.0);
|
| }
|
|
|