myth_render 0.3.0

Core rendering system for the Myth engine (render graph, pipeline, GPU management).
Documentation
// ============================================================================
// Shared Atmosphere Transmittance Helpers
// ============================================================================
//
// Intentionally keeps only the LUT/ray helpers needed by both the atmosphere
// pipeline and forward lighting so material shaders do not inherit unrelated
// constants such as `PI`/`TAU` from `atmosphere_math.wgsl`.

fn ray_sphere_intersect(
    origin: vec3<f32>,
    direction: vec3<f32>,
    radius: f32,
) -> vec2<f32> {
    let a = dot(direction, direction);
    let b = 2.0 * dot(direction, origin);
    let c = dot(origin, origin) - radius * radius;
    let discriminant = b * b - 4.0 * a * c;
    if discriminant < 0.0 {
        return vec2<f32>(-1.0, -1.0);
    }

    let sqrt_discriminant = sqrt(discriminant);
    return vec2<f32>(
        (-b - sqrt_discriminant) / (2.0 * a),
        (-b + sqrt_discriminant) / (2.0 * a),
    );
}

fn transmittance_lut_uv(
    altitude: f32,
    cos_zenith: f32,
    planet_radius: f32,
    atmosphere_radius: f32,
) -> vec2<f32> {
    let safe_cos_zenith = clamp(cos_zenith, -1.0, 1.0);
    let atmosphere_height = sqrt(max(
        0.0,
        atmosphere_radius * atmosphere_radius - planet_radius * planet_radius,
    ));
    let rho = sqrt(max(
        0.0,
        (planet_radius + altitude) * (planet_radius + altitude)
            - planet_radius * planet_radius,
    ));
    let distance = ray_sphere_intersect(
        vec3<f32>(0.0, planet_radius + altitude, 0.0),
        vec3<f32>(
            0.0,
            safe_cos_zenith,
            sqrt(max(0.0, 1.0 - safe_cos_zenith * safe_cos_zenith)),
        ),
        atmosphere_radius,
    ).y;
    let distance_min = atmosphere_radius - planet_radius - altitude;
    let distance_max = rho + atmosphere_height;
    let x_mu = (distance - distance_min) / max(distance_max - distance_min, 1e-6);
    let x_r = rho / max(atmosphere_height, 1e-6);
    return vec2<f32>(x_mu, x_r);
}