Skip to main content

CLASSIFY_COMPUTE

Constant CLASSIFY_COMPUTE 

Source
pub const CLASSIFY_COMPUTE: &str = r#"
#version 430 core
layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;

layout(std430, binding = 0) readonly buffer FieldValues { float field_values[]; };
layout(std430, binding = 1) buffer VertexCounts { uint vertex_counts[]; };

uniform uint u_resolution;
uniform float u_threshold;

// Edge table and vertex count per configuration
// (vertex_count_per_config[i] = number of vertices for cube config i)
// Precomputed from the tri table: count non-(-1) entries / 1
layout(std430, binding = 2) readonly buffer VertCountLUT { uint vert_count_lut[256]; };

uint field_index(uint x, uint y, uint z) {
    return z * u_resolution * u_resolution + y * u_resolution + x;
}

void main() {
    uvec3 gid = gl_GlobalInvocationID;
    uint res_m1 = u_resolution - 1u;
    if (any(greaterThanEqual(gid, uvec3(res_m1)))) return;

    uint x = gid.x, y = gid.y, z = gid.z;
    uint cube_index = 0u;
    float corners[8];
    corners[0] = field_values[field_index(x,   y,   z)];
    corners[1] = field_values[field_index(x+1, y,   z)];
    corners[2] = field_values[field_index(x+1, y+1, z)];
    corners[3] = field_values[field_index(x,   y+1, z)];
    corners[4] = field_values[field_index(x,   y,   z+1)];
    corners[5] = field_values[field_index(x+1, y,   z+1)];
    corners[6] = field_values[field_index(x+1, y+1, z+1)];
    corners[7] = field_values[field_index(x,   y+1, z+1)];

    for (uint i = 0u; i < 8u; ++i) {
        if (corners[i] >= u_threshold) cube_index |= (1u << i);
    }

    uint cell_idx = z * res_m1 * res_m1 + y * res_m1 + x;
    vertex_counts[cell_idx] = vert_count_lut[cube_index];
}
"#;
Expand description

Pass 2: Classify cells and count vertices.