Skip to main content

KERNEL_FRUSTUM_CULL

Constant KERNEL_FRUSTUM_CULL 

Source
pub const KERNEL_FRUSTUM_CULL: &str = r#"
// Per-instance frustum culling with optional LOD selection.
// Tests each instance's bounding sphere against 6 frustum planes.

layout(local_size_x = 256) in;

struct Instance {
    vec4 position_radius;   // xyz = position, w = bounding sphere radius
    vec4 extra;             // xyz = scale, w = LOD override (-1 = auto)
};

struct VisibleInstance {
    uint original_index;
    uint lod_level;
    vec2 _padding;
};

layout(std430, binding = 0) readonly buffer Instances {
    Instance instances[];
};

layout(std430, binding = 1) writeonly buffer VisibleOut {
    VisibleInstance visible[];
};

layout(binding = 0, offset = 0) uniform atomic_uint u_visible_count;

uniform uint u_instance_count;
uniform vec4 u_planes[6];      // frustum planes (normal.xyz, distance.w)
uniform vec3 u_camera_pos;
uniform vec4 u_lod_distances;  // x=lod0, y=lod1, z=lod2, w=lod3
uniform uint u_enable_lod;

bool sphere_vs_frustum(vec3 center, float radius) {
    for (int i = 0; i < 6; i++) {
        float dist = dot(u_planes[i].xyz, center) + u_planes[i].w;
        if (dist < -radius) {
            return false;  // fully outside this plane
        }
    }
    return true;
}

uint compute_lod(vec3 pos, float radius) {
    if (u_enable_lod == 0u) return 0u;

    float dist = length(pos - u_camera_pos) - radius;
    if (dist < u_lod_distances.x) return 0u;
    if (dist < u_lod_distances.y) return 1u;
    if (dist < u_lod_distances.z) return 2u;
    return 3u;
}

void main() {
    uint idx = gl_GlobalInvocationID.x;
    if (idx >= u_instance_count) return;

    Instance inst = instances[idx];
    vec3 center = inst.position_radius.xyz;
    float radius = inst.position_radius.w * max(inst.extra.x, max(inst.extra.y, inst.extra.z));

    if (sphere_vs_frustum(center, radius)) {
        uint lod = (inst.extra.w >= 0.0)
            ? uint(inst.extra.w)
            : compute_lod(center, radius);

        uint slot = atomicCounterIncrement(u_visible_count);
        visible[slot].original_index = idx;
        visible[slot].lod_level = lod;
    }
}
"#;
Expand description

Frustum culling kernel: per-instance visibility testing.