struct CameraUniform { scale: vec2, offset: vec2, }; @group(0) @binding(0) var camera: CameraUniform; @group(1) @binding(0) var quad_texture: texture_2d; @group(1) @binding(1) var quad_sampler: sampler; struct VertexIn { @location(0) position: vec2, @location(1) uv: vec2, }; struct InstanceIn { @location(2) world_pos: vec2, @location(3) size: vec2, }; struct VertexOut { @builtin(position) clip_position: vec4, @location(0) uv: vec2, }; @vertex fn vs_main(vin: VertexIn, iin: InstanceIn) -> VertexOut { var out: VertexOut; let world = iin.world_pos + vin.position * iin.size; let ndc = world * camera.scale + camera.offset; out.clip_position = vec4(ndc, 0.0, 1.0); out.uv = vin.uv; return out; } @fragment fn fs_main(in: VertexOut) -> @location(0) vec4 { let color = textureSample(quad_texture, quad_sampler, in.uv); if (color.a < 0.01) { discard; } return color; }