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.