viewport-lib 0.14.0

3D viewport rendering library
Documentation
// mc_wireframe.wgsl - Phase 17 GPU marching cubes wireframe overlay.
//
// Draws the triangle edges of the MC surface output procedurally from the vertex
// storage buffer.  No vertex buffer is bound; positions are fetched via vertex_index.
//
// The MC output has flat (non-indexed) triangle vertices packed as:
//   6 f32 per vertex: position.xyz (offsets 0-2), normal.xyz (offsets 3-5)
//   triangles are contiguous triples: [V3i, V3i+1, V3i+2]
//
// wire_indirect_buf holds draw_indirect args: [vertex_count=triangles*6, 1, 0, 0].
// Each group of 6 vertex_index values covers one triangle:
//   vid%6 in {0,1} -> edge 0 -> endpoints (V0, V1)
//   vid%6 in {2,3} -> edge 1 -> endpoints (V1, V2)
//   vid%6 in {4,5} -> edge 2 -> endpoints (V2, V0)
//
// Group 0 : camera_bgl
//   binding 0 : Camera uniform
//
// Group 1 :
//   binding 0 : MC vertex storage buffer (array<f32>, 6 f32 per vertex)

struct Camera {
    view_proj:     mat4x4<f32>,
    eye_pos:       vec3<f32>,
    _pad:          f32,
    forward:       vec3<f32>,
    _pad1:         f32,
    inv_view_proj: mat4x4<f32>,
    view:          mat4x4<f32>,
};

@group(0) @binding(0) var<uniform>      camera:      Camera;
@group(1) @binding(0) var<storage, read> mc_vertices: array<f32>;

@vertex
fn vs_main(@builtin(vertex_index) vid: u32) -> @builtin(position) vec4<f32> {
    let tri_id  = vid / 6u;
    let sub     = vid % 6u;
    let edge_id = sub / 2u; // 0, 1, or 2
    let end_id  = sub % 2u; // 0 = start vertex, 1 = end vertex

    // Local vertex index within the triangle (0, 1, or 2).
    // Edge 0: (0->1), Edge 1: (1->2), Edge 2: (2->0)
    var local_vert: u32;
    if edge_id == 0u {
        local_vert = select(0u, 1u, end_id != 0u);
    } else if edge_id == 1u {
        local_vert = select(1u, 2u, end_id != 0u);
    } else {
        local_vert = select(2u, 0u, end_id != 0u);
    }

    let base = (tri_id * 3u + local_vert) * 6u;
    let pos = vec3<f32>(mc_vertices[base], mc_vertices[base + 1u], mc_vertices[base + 2u]);
    return camera.view_proj * vec4<f32>(pos, 1.0);
}

@fragment
fn fs_main() -> @location(0) vec4<f32> {
    return vec4<f32>(0.75, 0.75, 0.75, 1.0);
}