Constant SKY_MODEL_WGSL
Source pub const SKY_MODEL_WGSL: &str = r#"
struct SkyUniform {
sun: vec4f,
sun_colour_intensity: vec4f,
ambient_turbidity_albedo: vec4f,
albedo_mode: vec4f,
forward: vec4f,
right: vec4f,
up: vec4f,
};
@group(1) @binding(0) var<uniform> sky: SkyUniform;
@group(1) @binding(1) var hdr: texture_2d<f32>;
@group(1) @binding(2) var hdr_sampler: sampler;
fn sky_diffuse(direction: vec3f) -> vec3f {
let d = normalize(direction);
if d.y < 0.0 {
return vec3f(sky.ambient_turbidity_albedo.zw, sky.albedo_mode.x) * sky.ambient_turbidity_albedo.x * 0.12;
}
let cos_theta = max(d.y, 0.001);
let cos_gamma = clamp(dot(d, sky.sun.xyz), -1.0, 1.0);
let gamma = acos(cos_gamma);
let t = sky.ambient_turbidity_albedo.y;
let a = 0.1787*t-1.4630;
let b = -0.3554*t+0.4275;
let c = -0.0227*t+5.3251;
let dd = 0.1206*t-2.5771;
let e = -0.0670*t+0.3703;
let shape = (1.0+a*exp(b/cos_theta))*(1.0+c*exp(dd*gamma)+e*cos_gamma*cos_gamma);
let zenith_gamma = acos(clamp(sky.sun.y, -1.0, 1.0));
let zenith_cos = cos(zenith_gamma);
let norm = (1.0+a*exp(b))*(1.0+c*exp(dd*zenith_gamma)+e*zenith_cos*zenith_cos);
let haze = (t-1.0)/9.0;
let warm = pow(1.0-max(sky.sun.y, 0.0), 2.0)*exp(-gamma*2.0);
let base = vec3f(0.34+0.24*haze, 0.50+0.18*haze, 1.05-0.30*haze);
let tint = vec3f(1.0+0.75*warm, 1.0+0.15*warm, 1.0-0.45*warm);
let rise = max(sky.sun.y, 0.0);
let scale = 0.215*pow(rise, 2.5)+0.05*(1.0-smoothstep(0.2, 0.6, rise));
return base*tint*max(shape/max(norm, 0.01), 0.0)*sky.ambient_turbidity_albedo.x*scale;
}
fn sky_analytic(direction: vec3f) -> vec3f {
let d = normalize(direction);
var value = sky_diffuse(d);
let cosine = clamp(dot(d, sky.sun.xyz), -1.0, 1.0);
let radius = 0.004675;
if sky.sun.y > 0.0 && cosine >= cos(radius) {
let radial = sqrt(2.0*(1.0-cosine))/radius;
let limb = 0.4+0.6*sqrt(max(1.0-radial*radial, 0.0));
value += sky.sun_colour_intensity.xyz*(sky.sun_colour_intensity.w*limb/(3.14159265*radius*radius*0.8));
}
return value;
}
fn sky_radiance(direction: vec3f) -> vec3f {
let d = normalize(direction);
if sky.albedo_mode.y < 0.5 {
return sky_analytic(d);
}
let u = fract(atan2(d.x, -d.z)/6.28318531+0.5);
let v = acos(clamp(d.y, -1.0, 1.0))/3.14159265;
return textureSampleLevel(hdr, hdr_sampler, vec2f(u, v), 0.0).rgb;
}
"#;