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/diffuse_brdf.glsl + diffuse_btdf.glsl
// EON: "A practical energy-preserving rough diffuse BRDF" (Portsmouth, Kutz, Hill)

const constant1_FON: f32 = 0.5 - 2.0 / (3.0 * PI);
const constant2_FON: f32 = 2.0 / 3.0 - 28.0 / (15.0 * PI);

fn E_FON_exact(mu: f32, r: f32) -> f32 {
    let AF = 1.0 / (1.0 + constant1_FON * r);
    let BF = r * AF;
    let Si = sqrt(1.0 - (mu * mu));
    let G = Si * (acos(clamp(mu, -1.0, 1.0)) - Si * mu)
          + (2.0 / 3.0) * ((Si / mu) * (1.0 - (Si * Si * Si)) - Si);
    return AF + (BF / PI) * G;
}

fn E_FON_approx(mu: f32, r: f32) -> f32 {
    let mucomp = 1.0 - mu;
    let mucomp2 = mucomp * mucomp;
    let Gcoeffs = mat2x2<f32>(vec2<f32>(0.0571085289, -0.332181442), vec2<f32>(0.491881867, 0.0714429953));
    let GoverPi = dot(Gcoeffs * vec2<f32>(mucomp, mucomp2), vec2<f32>(1.0, mucomp2));
    return (1.0 + r * GoverPi) / (1.0 + constant1_FON * r);
}

fn f_EON(rho: vec3<f32>, r: f32, wi_local: vec3<f32>, wo_local: vec3<f32>, exact: bool) -> vec3<f32> {
    let mu_i = wi_local.z;
    let mu_o = wo_local.z;
    let s = dot(wi_local, wo_local) - mu_i * mu_o;
    let sovertF = select(s, s / max(mu_i, mu_o), s > 0.0);
    let AF = 1.0 / (1.0 + constant1_FON * r);
    let f_ss = (rho / PI) * AF * (1.0 + r * sovertF);
    let EFo = select(E_FON_approx(mu_o, r), E_FON_exact(mu_o, r), exact);
    let EFi = select(E_FON_approx(mu_i, r), E_FON_exact(mu_i, r), exact);
    let avgEF = AF * (1.0 + constant2_FON * r);
    let rho_ms = (rho * rho) * avgEF / (vec3<f32>(1.0) - rho * (1.0 - avgEF));
    let eps = 1.0e-7;
    let f_ms = (rho_ms / PI) * max(eps, 1.0 - EFo) * max(eps, 1.0 - EFi) / max(eps, 1.0 - avgEF);
    return f_ss + f_ms;
}

fn E_EON(rho: vec3<f32>, r: f32, wi_local: vec3<f32>, exact: bool) -> vec3<f32> {
    let mu_i = wi_local.z;
    let AF = 1.0 / (1.0 + constant1_FON * r);
    let EF = select(E_FON_approx(mu_i, r), E_FON_exact(mu_i, r), exact);
    let avgEF = AF * (1.0 + constant2_FON * r);
    let rho_ms = (rho * rho) * avgEF / (vec3<f32>(1.0) - rho * (1.0 - avgEF));
    return rho * EF + rho_ms * (1.0 - EF);
}

struct LtcTerms {
    a: f32,
    b: f32,
    c: f32,
    d: f32,
};

fn ltc_terms(mu: f32, r: f32) -> LtcTerms {
    var t: LtcTerms;
    t.a = 1.0 + r * (0.303392 + (-0.518982 + 0.111709 * mu) * mu + (-0.276266 + 0.335918 * mu) * r);
    t.b = r * (-1.16407 + 1.15859 * mu + (0.150815 - 0.150105 * mu) * r) / (mu * mu * mu - 1.43545);
    t.c = 1.0 + (0.20013 + (-0.506373 + 0.261777 * mu) * mu) * r;
    t.d = ((0.540852 + (-1.01625 + 0.475392 * mu) * mu) * r) / (-1.0743 + mu * (0.0725628 + mu));
    return t;
}

fn cltc_sample(wo_local: vec3<f32>, r: f32, u1: f32, u2: f32) -> vec4<f32> {
    let t = ltc_terms(wo_local.z, r);
    let R = sqrt(u1);
    let phi = 2.0 * PI * u2;
    var x = R * cos(phi);
    let y = R * sin(phi);
    let vz = 1.0 / sqrt(t.d * t.d + 1.0);
    let s = 0.5 * (1.0 + vz);
    x = -mix(sqrt(1.0 - y * y), x, s);
    let wh = vec3<f32>(x, y, sqrt(max(1.0 - (x * x + y * y), 0.0)));
    let pdf_wh = wh.z / (PI * s);
    var wi = vec3<f32>(t.a * wh.x + t.b * wh.z, t.c * wh.y, t.d * wh.x + wh.z);
    let len = length(wi);
    let detM = t.c * (t.a - t.b * t.d);
    let pdf_wi = pdf_wh * len * len * len / detM;
    let fromLTC = orthonormal_basis_ltc(wo_local);
    wi = normalize(fromLTC * wi);
    return vec4<f32>(wi, pdf_wi);
}

fn cltc_pdf(wo_local: vec3<f32>, wi_local: vec3<f32>, r: f32) -> f32 {
    let toLTC = transpose(orthonormal_basis_ltc(wo_local));
    let wi = toLTC * wi_local;
    let t = ltc_terms(wo_local.z, r);
    let detM = t.c * (t.a - t.b * t.d);
    let wh = vec3<f32>(t.c * (wi.x - t.b * wi.z), (t.a - t.b * t.d) * wi.y, -t.c * (t.d * wi.x - t.a * wi.z));
    let lensq = dot(wh, wh);
    let vz = 1.0 / sqrt(t.d * t.d + 1.0);
    let s = 0.5 * (1.0 + vz);
    let pdf = sqr(detM / lensq) * max(wh.z, 0.0) / (PI * s);
    return pdf;
}

fn uniform_lobe_sample(u1: f32, u2: f32) -> vec3<f32> {
    let sinT = sqrt(1.0 - u1 * u1);
    let phi = 2.0 * PI * u2;
    return vec3<f32>(sinT * cos(phi), sinT * sin(phi), u1);
}

fn sample_EON(wo_local: vec3<f32>, r: f32, u1_in: f32, u2: f32) -> vec4<f32> {
    let mu = wo_local.z;
    let P_u = pow(r, 0.1) * (0.162925 + mu * (-0.372058 + (0.538233 - 0.290822 * mu) * mu));
    let P_c = 1.0 - P_u;
    var wi: vec4<f32>;
    var pdf_c: f32;
    var u1 = u1_in;
    if (u1 <= P_u) {
        u1 = u1 / P_u;
        let d = uniform_lobe_sample(u1, u2);
        wi = vec4<f32>(d, 0.0);
        pdf_c = cltc_pdf(wo_local, d, r);
    } else {
        u1 = (u1 - P_u) / P_c;
        wi = cltc_sample(wo_local, r, u1, u2);
        pdf_c = wi.w;
    }
    let pdf_u = 1.0 / (2.0 * PI);
    wi.w = P_u * pdf_u + P_c * pdf_c;
    return wi;
}

fn pdf_EON(wo_local: vec3<f32>, wi_local: vec3<f32>, r: f32) -> f32 {
    let mu = wo_local.z;
    let P_u = pow(r, 0.1) * (0.162925 + mu * (-0.372058 + (0.538233 - 0.290822 * mu) * mu));
    let P_c = 1.0 - P_u;
    let pdf_c = cltc_pdf(wo_local, wi_local, r);
    let pdf_u = 1.0 / (2.0 * PI);
    return P_u * pdf_u + P_c * pdf_c;
}

// ---------------------------------------------------------------------------
// diffuse BRDF
// ---------------------------------------------------------------------------
// f = diffuse_w_color * f_EON(rho = base_color) + diffuse_w_white * f_EON(rho = 1)
fn diffuse_lobe_f(winputL: vec3<f32>, woutputL: vec3<f32>) -> vec3<f32> {
    var f = vec3<f32>(0.0);
    if (maxComponent(diffuse_w_color) > 0.0) {
        f += diffuse_w_color * f_EON(base_color, base_diffuse_roughness, winputL, woutputL, true);
    }
    if (maxComponent(diffuse_w_white) > 0.0) {
        f += diffuse_w_white * f_EON(vec3<f32>(1.0), base_diffuse_roughness, winputL, woutputL, true);
    }
    return f;
}

fn diffuse_brdf_evaluate(winputL: vec3<f32>, woutputL: vec3<f32>) -> BsdfEval {
    var out: BsdfEval;
    out.f = vec3<f32>(0.0);
    out.pdf = 0.0;
    if (winputL.z < DENOM_TOLERANCE || woutputL.z < DENOM_TOLERANCE) { return out; }
    out.pdf = pdf_EON(winputL, woutputL, base_diffuse_roughness);
    out.f = diffuse_lobe_f(winputL, woutputL);
    return out;
}

fn diffuse_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 = 0.0;
    if (winputL.z < DENOM_TOLERANCE) { return out; }
    let u1 = rand();
    let u2 = rand();
    let wiP = sample_EON(winputL, base_diffuse_roughness, u1, u2);
    out.woutputL = wiP.xyz;
    out.pdf = wiP.w;
    out.f = diffuse_lobe_f(winputL, out.woutputL);
    return out;
}

fn diffuse_brdf_albedo(winputL: vec3<f32>) -> vec3<f32> {
    if (winputL.z < DENOM_TOLERANCE) { return vec3<f32>(0.0); }
    return diffuse_w_color * E_EON(base_color, base_diffuse_roughness, winputL, true)
         + diffuse_w_white * E_EON(vec3<f32>(1.0), base_diffuse_roughness, winputL, true);
}

// ---------------------------------------------------------------------------
// diffuse BTDF: EON lobe flipped into the negative hemisphere (thin-walled SSS)
// ---------------------------------------------------------------------------
fn diffuse_btdf_evaluate(winputL: vec3<f32>, woutputL_in: vec3<f32>) -> BsdfEval {
    var out: BsdfEval;
    out.f = vec3<f32>(0.0);
    let reflected = woutputL_in.z * winputL.z > 0.0;
    if (reflected) {
        out.pdf = 0.0; // (viewer: 1.0 — see specular_btdf.wgsl)
        return out;
    }
    var woutputL = woutputL_in;
    woutputL.z *= -1.0;
    out.pdf = pdf_EON(winputL, woutputL, base_diffuse_roughness);
    out.f = f_EON(vec3<f32>(1.0), base_diffuse_roughness, winputL, woutputL, true);
    return out;
}

fn diffuse_btdf_sample(winputL: vec3<f32>) -> BsdfSample {
    var out: BsdfSample;
    let u1 = rand();
    let u2 = rand();
    let wiP = sample_EON(winputL, base_diffuse_roughness, u1, u2);
    var woutputL = wiP.xyz;
    out.pdf = wiP.w;
    out.f = f_EON(vec3<f32>(1.0), base_diffuse_roughness, winputL, woutputL, true);
    woutputL.z *= -1.0;
    out.woutputL = woutputL;
    return out;
}

fn diffuse_btdf_albedo(winputL: vec3<f32>) -> vec3<f32> {
    return E_EON(vec3<f32>(1.0), base_diffuse_roughness, winputL, true);
}