iced_plot 0.4.0

A GPU-accelerated plotting widget for Iced.
Documentation
// Render markers to a uint id target. Each instance writes unique id = instance_index + 1.

const QUAD_POS: array<vec2<f32>, 4> = array<vec2<f32>, 4>(
    vec2<f32>(-1.0, -1.0),  // bottom-left
    vec2<f32>(1.0, -1.0),   // bottom-right
    vec2<f32>(-1.0, 1.0),   // top-left
    vec2<f32>(1.0, 1.0),    // top-right
);

struct CameraUniform {
    view_proj: mat4x4<f32>,
    pixel_to_clip: vec4<f32>,
    pixel_to_world: vec4<f32>,
};

@group(0) @binding(0)
var<uniform> camera: CameraUniform;

struct VertexInput {
    @location(0) position: vec2<f32>,
    @location(1) color: vec4<f32>,
    // We don't care about the marker type which is at location 2.
    @location(3) size: f32,
    @location(4) size_mode: u32,
};

struct VsOut {
    @builtin(position) clip_position: vec4<f32>,
    @location(0) local_pos: vec2<f32>,
    @interpolate(flat) @location(1) instance_id: u32,
};

@vertex
fn vs_main(
    @builtin(vertex_index) vid: u32,
    @builtin(instance_index) iid: u32,
    model: VertexInput,
) -> VsOut {
    var out: VsOut;
    let local = QUAD_POS[vid];
    var center_pos = model.position;
    var half_world = 0.0;
    if (model.size_mode == 1u) {
        half_world = model.size * 0.5;
        center_pos = center_pos + vec2<f32>(half_world, half_world);
    }
    let center = camera.view_proj * vec4<f32>(center_pos, 0.0, 1.0);
    var half_size_px_x = model.size;
    var half_size_px_y = model.size;
    if (model.size_mode == 1u) {
        half_size_px_x = half_world / camera.pixel_to_world.x;
        half_size_px_y = half_world / camera.pixel_to_world.y;
    }
    let offset = vec4<f32>(
        local.x * half_size_px_x * camera.pixel_to_clip.x * center.w,
        local.y * half_size_px_y * camera.pixel_to_clip.y * center.w,
        0.0, 0.0);
    out.clip_position = center + offset;
    out.local_pos = local;
    out.instance_id = iid;
    return out;
}

@fragment
fn fs_main(in: VsOut) -> @location(0) u32 {
    if length(in.local_pos) <= 1.0 {     
        // 1-based id so 0 means background
        return in.instance_id + 1u;
    }
    return 0u;
}