codecraft 0.2.0

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/metal_brdf.glsl (haze/retro omitted, see specular_brdf.wgsl)

fn metal_fresnel(mu: f32) -> vec3<f32> {
    let F_nofilm = FresnelF82Tint(mu, base_weight * base_color, specular_color);
    if (thin_film_weight > 0.0) {
        let eta_fe = mix(thin_film_ior / ambient_ior, thin_film_ior / coat_ior, coat_weight);
        let F_film = FresnelThinFilmOverConductor(mu, eta_fe);
        return mix(F_nofilm, F_film, thin_film_weight);
    }
    return F_nofilm;
}

fn metal_brdf_evaluate(winputL: vec3<f32>, woutputL: vec3<f32>) -> BsdfEval {
    var out: BsdfEval;
    out.f = vec3<f32>(0.0);
    out.pdf = PDF_EPSILON;
    if (winputL.z < DENOM_TOLERANCE || woutputL.z < DENOM_TOLERANCE) { return out; }
    let a = specular_ndf_roughnesses();
    let mR = normalize(woutputL + winputL);
    let D = ggx_ndf_eval(mR, a.x, a.y);
    let DV = D * ggx_G1(winputL, a.x, a.y) * max(0.0, dot(winputL, mR)) / max(DENOM_TOLERANCE, winputL.z);
    let dwh_dwo = 1.0 / max(abs(4.0 * dot(winputL, mR)), DENOM_TOLERANCE);
    let G2 = ggx_G2(winputL, woutputL, a.x, a.y);
    let DG2 = D * G2;
    out.pdf = max(PDF_EPSILON, DV * dwh_dwo);
    let F = metal_fresnel(abs(dot(winputL, mR)));
    out.f = metal_energy_scale(winputL) * min(vec3<f32>(1.0), specular_weight * F) * DG2 / max(4.0 * abs(woutputL.z) * abs(winputL.z), DENOM_TOLERANCE);
    return out;
}

fn metal_brdf_sample(winputL: vec3<f32>) -> BsdfSample {
    var out: BsdfSample;
    out.f = vec3<f32>(0.0);
    out.woutputL = vec3<f32>(0.0, 0.0, 1.0);
    out.pdf = PDF_EPSILON;
    if (winputL.z < DENOM_TOLERANCE) { return out; }
    let a = specular_ndf_roughnesses();
    let mR = ggx_ndf_sample(winputL, a.x, a.y);
    let woutputL = -winputL + 2.0 * dot(winputL, mR) * mR;
    out.woutputL = woutputL;
    if (winputL.z * woutputL.z < FLT_EPSILON) {
        out.pdf = 0.0;
        return out;
    }
    let D = ggx_ndf_eval(mR, a.x, a.y);
    let DV = D * ggx_G1(winputL, a.x, a.y) * max(0.0, dot(winputL, mR)) / max(DENOM_TOLERANCE, winputL.z);
    let dwh_dwo = 1.0 / max(abs(4.0 * dot(winputL, mR)), DENOM_TOLERANCE);
    let G2 = ggx_G2(winputL, woutputL, a.x, a.y);
    let DG2 = D * G2;
    out.pdf = max(PDF_EPSILON, DV * dwh_dwo);
    let F = metal_fresnel(abs(dot(winputL, mR)));
    out.f = metal_energy_scale(winputL) * min(vec3<f32>(1.0), specular_weight * F) * DG2 / max(4.0 * abs(woutputL.z) * abs(winputL.z), DENOM_TOLERANCE);
    return out;
}

fn metal_brdf_albedo(winputL: vec3<f32>) -> vec3<f32> {
    if (winputL.z < DENOM_TOLERANCE) { return vec3<f32>(0.0); }
    let num_samples = 4;
    var albedo = vec3<f32>(0.0);
    for (var n = 0; n < num_samples; n++) {
        let s = metal_brdf_sample(winputL);
        if (length(s.f) > RADIANCE_EPSILON) {
            albedo += s.f * abs(s.woutputL.z) / max(PDF_EPSILON, s.pdf);
        }
    }
    albedo /= f32(num_samples);
    return albedo;
}