ddgi_classify.slang

cross platform rendering playground

src/passes/ddgi/ddgi_classify.slang

1.43 KB
#include "shared.h"
#include "renderer_types.h"
#include "lib/ddgi_common.slang"

[[vk::push_constant]]
DdgiClassifyPushConstants pc;

static const f32 DDGI_MISS_DISTANCE = 1e27f;

[shader("compute")]
[numthreads(64, 1, 1)]
void csMain(uvec3 dtid: SV_DispatchThreadID) {
    uint probe_idx = dtid.x;
    FrameUBO frame = *pc.frame;
    DdgiGridParams grid = frame.ddgi_grid;
    DdgiConfig cfg = frame.ddgi_cfg;

    uvec3 dims = uvec3(grid.dims.xyz);
    if (probe_idx >= dims.x * dims.y * dims.z) {
        return;
    }

    // if probe is inside geometry, count backface hits
    uint backface_count = 0;
    f32 closest_frontface = 1e27f;

    for (uint r = 0; r < FIXED_RAY_COUNT; r++) {
        vec4 rad = pc.samples_buffer[probe_idx * RAYS_PER_PROBE + r].radiance_distance;

        if (rad.w < 0.0f) {
            backface_count++;
        } else {
            closest_frontface = min(closest_frontface, rad.w);
        }
    }

    // snap state, 0 active 1 inactive (TODO: REVERSE IT!)
    vec3 geometry_bounds = grid.spacing.xyz * 2.0f * 1.45f;
    f32 backface_ratio = f32(backface_count) / f32(FIXED_RAY_COUNT);
    f32 target = (all(vec3(closest_frontface) <= geometry_bounds) && backface_ratio < cfg.fixed_ray_backface_threshold)
                     ? DDGI_STATE_PROBE_ACTIVE
                     : DDGI_STATE_PROBE_INACTIVE;
    ProbeState ps = pc.probe_state[probe_idx];
    ps.offset_active.w = target;
    pc.probe_state[probe_idx] = ps;
}