codecraft 0.1.2

A minimalist 3D game engine built on parts of Bevy (ECS, color) with wgpu and winit: OpenPBR materials, clustered lighting, a yakui-drawn UI, audio and gamepad haptics; its binary maps any folder, and the symbols of its Rust files, as a 3D wall of boxes
Documentation
// Port of glsl/pathtracing/thin-film.glsl (Airy summation with complex arithmetic,
// evaluated at the hero wavelength).

fn cx(r: f32, i: f32) -> vec2<f32> { return vec2<f32>(r, i); }
fn cx_mul(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> { return vec2<f32>(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }
fn cx_conj(z: vec2<f32>) -> vec2<f32> { return vec2<f32>(z.x, -z.y); }
fn cx_abs2(z: vec2<f32>) -> f32 { return z.x * z.x + z.y * z.y; }
fn cx_div(a: vec2<f32>, b: vec2<f32>) -> vec2<f32> { return cx_mul(a, cx_conj(b)) / max(cx_abs2(b), 1e-30); }
fn cx_exp(z: vec2<f32>) -> vec2<f32> { return exp(z.x) * vec2<f32>(cos(z.y), sin(z.y)); }

fn cx_sqrt(z: vec2<f32>) -> vec2<f32> {
    let r = length(z);
    if (r < 1e-30) { return vec2<f32>(0.0); }
    let half_angle = 0.5 * atan2(z.y, z.x);
    return sqrt(r) * vec2<f32>(cos(half_angle), sin(half_angle));
}

struct NK {
    n: vec3<f32>,
    k: vec3<f32>,
};

// "Artist Friendly Metallic Fresnel", Gulbrandsen 2014
fn GulbrandsenMapping(F0: vec3<f32>, edgetint: vec3<f32>) -> NK {
    let r = clamp(F0, vec3<f32>(0.0), vec3<f32>(0.99));
    let g = edgetint;
    let r_sqrt = sqrt(r);
    let n_min = (vec3<f32>(1.0) - r) / (vec3<f32>(1.0) + r);
    let n_max = (vec3<f32>(1.0) + r_sqrt) / (vec3<f32>(1.0) - r_sqrt);
    var out: NK;
    out.n = mix(n_max, n_min, g);
    var k2 = (sqr3(out.n + vec3<f32>(1.0)) * r - sqr3(out.n - vec3<f32>(1.0))) / (vec3<f32>(1.0) - r);
    k2 = max(vec3<f32>(0.0), k2);
    out.k = sqrt(k2);
    return out;
}

fn conductor_ior_at_wavelength(n_rgb: vec3<f32>, k_rgb: vec3<f32>, lambda: f32) -> vec2<f32> {
    var w = max(vec3<f32>(0.0), xyzToRgb(xyzFit_1931(lambda)));
    let ws = w.r + w.g + w.b;
    if (ws < 1e-10) { return vec2<f32>(n_rgb.g, k_rgb.g); }
    w /= ws;
    return vec2<f32>(dot(n_rgb, w), dot(k_rgb, w));
}

fn cos_refracted(cos_i: vec2<f32>, n_i: vec2<f32>, n_t: vec2<f32>) -> vec2<f32> {
    let sin_i_sq = cx(1.0, 0.0) - cx_mul(cos_i, cos_i);
    let ratio = cx_div(n_i, n_t);
    let sin_t_sq = cx_mul(cx_mul(ratio, ratio), sin_i_sq);
    var cos_t = cx_sqrt(cx(1.0, 0.0) - sin_t_sq);
    if (cx_mul(n_t, cos_t).y < 0.0) { cos_t = -cos_t; }
    return cos_t;
}

struct FresnelCoeffs {
    r_s: vec2<f32>,
    r_p: vec2<f32>,
    t_s: vec2<f32>,
    t_p: vec2<f32>,
};

fn fresnel_coeffs(cos_i: vec2<f32>, cos_t: vec2<f32>, n_i: vec2<f32>, n_t: vec2<f32>) -> FresnelCoeffs {
    let ni_ci = cx_mul(n_i, cos_i);
    let nt_ct = cx_mul(n_t, cos_t);
    let ni_ct = cx_mul(n_i, cos_t);
    let nt_ci = cx_mul(n_t, cos_i);
    var c: FresnelCoeffs;
    c.r_s = cx_div(ni_ci - nt_ct, ni_ci + nt_ct);
    c.t_s = cx_div(2.0 * ni_ci, ni_ci + nt_ct);
    c.r_p = cx_div(nt_ci - ni_ct, nt_ci + ni_ct);
    c.t_p = cx_div(2.0 * ni_ci, nt_ci + ni_ct);
    return c;
}

fn thin_film_R(cos_1: f32, n_1: f32, n_2: f32, n_3: vec2<f32>, d: f32, lambda: f32) -> f32 {
    let cn1 = cx(n_1, 0.0);
    let cn2 = cx(n_2, 0.0);
    let cos_2 = cos_refracted(cx(cos_1, 0.0), cn1, cn2);
    let cos_3 = cos_refracted(cos_2, cn2, n_3);

    let c12 = fresnel_coeffs(cx(cos_1, 0.0), cos_2, cn1, cn2);
    let c23 = fresnel_coeffs(cos_2, cos_3, cn2, n_3);

    let r21_s = -c12.r_s;
    let r21_p = -c12.r_p;
    let ratio = cx_div(cx_mul(cn2, cos_2), cx_mul(cn1, cx(cos_1, 0.0)));
    let t21_s = cx_mul(c12.t_s, ratio);
    let t21_p = cx_mul(c12.t_p, ratio);

    let delta = (4.0 * PI * n_2 * d / lambda) * cos_2;
    let phi = cx_exp(cx(-delta.y, delta.x));

    let denom_s = cx(1.0, 0.0) - cx_mul(r21_s, cx_mul(c23.r_s, phi));
    let numer_s = cx_mul(c12.t_s, cx_mul(c23.r_s, cx_mul(t21_s, phi)));
    let r_s = c12.r_s + cx_div(numer_s, denom_s);

    let denom_p = cx(1.0, 0.0) - cx_mul(r21_p, cx_mul(c23.r_p, phi));
    let numer_p = cx_mul(c12.t_p, cx_mul(c23.r_p, cx_mul(t21_p, phi)));
    let r_p = c12.r_p + cx_div(numer_p, denom_p);

    let R = 0.5 * (cx_abs2(r_s) + cx_abs2(r_p));
    return clamp(R, 0.0, 1.0);
}

// `internal`: the ray is inside the dielectric substrate hitting the film from below,
// so the media order is substrate -> film -> exterior (this is what makes TIR appear
// correctly in the film reflectance; the viewer always assumes exterior incidence).
fn FresnelThinFilmOverDielectric(mui: f32, eta_fe: f32, internal: bool) -> f32 {
    let n_external = thin_film_ior / eta_fe;
    // substrate IOR, scaled by the specular_weight IOR modulation
    let n_substrate = specular_ior_dispersive() * eta_s() / max(eta_s_unmodulated(), DENOM_TOLERANCE);
    if (internal) {
        return thin_film_R(mui, n_substrate, thin_film_ior, cx(n_external, 0.0), thin_film_thickness, wavelength_nm);
    }
    return thin_film_R(mui, n_external, thin_film_ior, cx(n_substrate, 0.0), thin_film_thickness, wavelength_nm);
}

fn FresnelThinFilmOverConductor(mui: f32, eta_fe: f32) -> vec3<f32> {
    let n_external = thin_film_ior / eta_fe;
    let nk_rgb = GulbrandsenMapping(base_weight * base_color, specular_color);
    let nk = conductor_ior_at_wavelength(nk_rgb.n, nk_rgb.k, wavelength_nm);
    let R = thin_film_R(mui, n_external, thin_film_ior, cx(nk.x, nk.y), thin_film_thickness, wavelength_nm);
    return vec3<f32>(R);
}