indicatrix 0.9.0

A physically-based spectral gemstone renderer that turns GemCAD-style cutting instructions into rendered output.
Documentation
struct WtBranch {
    origin: vec3<f32>, dir: vec3<f32>, weight: vec3<f32>,
    inside: bool, depth: u32, primary: bool,
}
// Scalar slots, not a function-local array: avoids AMD/FXC array lowering failures.
struct WtStack { a: WtBranch, b: WtBranch, c: WtBranch, d: WtBranch, count: u32 }
fn wt_push(stack: ptr<function, WtStack>, branch: WtBranch) {
    if (!wt_keeps(branch.weight, branch.depth)) { return; }
    switch ((*stack).count) {
        case 0u: { (*stack).a = branch; }
        case 1u: { (*stack).b = branch; }
        case 2u: { (*stack).c = branch; }
        case 3u: { (*stack).d = branch; }
        default: { return; }
    }
    (*stack).count = (*stack).count + 1u;
}
fn wt_pop(stack: ptr<function, WtStack>) -> WtBranch {
    (*stack).count = (*stack).count - 1u;
    switch ((*stack).count) {
        case 0u: { return (*stack).a; }
        case 1u: { return (*stack).b; }
        case 2u: { return (*stack).c; }
        default: { return (*stack).d; }
    }
}
fn wt_emit(stack: ptr<function, WtStack>, sum: ptr<function, vec3<f32>>,
    point: vec3<f32>, dir: vec3<f32>, weight: vec3<f32>, observer: vec3<f32>, depth: u32) {
    if (wt.counts.y == 0u || (*stack).count >= 3u) {
        (*sum) = (*sum) + weight * wt_leaf(dir, observer);
    } else {
        wt_push(stack, WtBranch(wt_scale_add(dir, 1e-4, point), dir, weight, false, depth, false));
    }
}
fn wt_chain(origin: vec3<f32>, direction: vec3<f32>, n: f32, observer: vec3<f32>) -> vec3<f32> {
    let empty = WtBranch(vec3<f32>(0.0), vec3<f32>(0.0), vec3<f32>(0.0), false, 0u, false);
    var stack = WtStack(empty, empty, empty, empty, 0u);
    wt_push(&stack, WtBranch(origin, direction, vec3<f32>(1.0), false, 0u, true));
    var sum = vec3<f32>(0.0);
    loop {
        if (stack.count == 0u) { break; }
        var branch = wt_pop(&stack);
        let hit = wt_intersect(branch.origin, branch.dir);
        if (!hit.valid) {
            // One lookup for every escape: a primary miss sees the same lit tray a window does.
            sum = sum + branch.weight * wt_leaf(branch.dir, observer);
            continue;
        }
        if (hit.side != 0u) { branch.inside = hit.side == 2u; }
        if (branch.inside) {
            let attenuation = -wt_alpha(branch.dir) * hit.t;
            branch.weight = branch.weight * vec3<f32>(exp_poly(attenuation.x), exp_poly(attenuation.y), exp_poly(attenuation.z));
        }
        let frost = wt_frost[hit.facet];
        if (frost.w != 0.0) { sum = sum + branch.weight * frost.xyz; continue; }
        let point = wt_scale_add(branch.dir, hit.t, branch.origin);
        let normal = select(hit.normal, -hit.normal, branch.inside);
        let ci = clamp(-wt_dot(branch.dir, normal), 0.0, 1.0);
        let eta = select(1.0 / n, n, branch.inside);
        let r = wt_fresnel(ci, eta);
        let reflected = wt_reflect(branch.dir, normal);
        let transmitted = wt_refract(branch.dir, normal, eta);
        let depth = branch.depth + 1u;
        if (branch.inside) {
            if (transmitted.valid) {
                wt_emit(&stack, &sum, point, transmitted.dir, branch.weight * (1.0 - r), observer, depth);
            }
            wt_push(&stack, WtBranch(wt_scale_add(reflected, 1e-4, point), reflected,
                branch.weight * r, true, depth, false));
        } else {
            let glare = select(1.0, wt.values.x, branch.primary);
            wt_emit(&stack, &sum, point, reflected, branch.weight * (r * glare), observer, depth);
            if (transmitted.valid) {
                wt_push(&stack, WtBranch(wt_scale_add(transmitted.dir, 1e-4, point), transmitted.dir,
                    branch.weight * (1.0 - r), true, depth, false));
            }
        }
    }
    return sum;
}