(dir: Vec3, sun_position: Vec3, sun_intensity_extra_spec_const_factor: u32)
| 72 | } |
| 73 | |
| 74 | fn sky(dir: Vec3, sun_position: Vec3, sun_intensity_extra_spec_const_factor: u32) -> Vec3 { |
| 75 | let up = vec3(0.0, 1.0, 0.0); |
| 76 | let sunfade = 1.0 - (1.0 - saturate(sun_position.y / 450000.0).exp()); |
| 77 | let rayleigh_coefficient = RAYLEIGH - (1.0 * (1.0 - sunfade)); |
| 78 | let beta_r = total_rayleigh(PRIMARIES) * rayleigh_coefficient; |
| 79 | |
| 80 | // Mie coefficient |
| 81 | let beta_m = total_mie(PRIMARIES, MIE_K_COEFFICIENT, TURBIDITY) * MIE_COEFFICIENT; |
| 82 | |
| 83 | // Optical length, cutoff angle at 90 to avoid singularity |
| 84 | let zenith_angle = acos_approx(up.dot(dir).max(0.0)); |
| 85 | let denom = (zenith_angle).cos() + 0.15 * (93.885 - ((zenith_angle * 180.0) / PI)).powf(-1.253); |
| 86 | |
| 87 | let s_r = RAYLEIGH_ZENITH_LENGTH / denom; |
| 88 | let s_m = MIE_ZENITH_LENGTH / denom; |
| 89 | |
| 90 | // Combined extinction factor |
| 91 | let fex = exp(-(beta_r * s_r + beta_m * s_m)); |
| 92 | |
| 93 | // In-scattering |
| 94 | let sun_direction = sun_position.normalize(); |
| 95 | let cos_theta = dir.dot(sun_direction); |
| 96 | let beta_r_theta = beta_r * rayleigh_phase(cos_theta * 0.5 + 0.5); |
| 97 | |
| 98 | let beta_m_theta = beta_m * henyey_greenstein_phase(cos_theta, MIE_DIRECTIONAL_G); |
| 99 | let sun_e = sun_intensity(sun_direction.dot(up)) |
| 100 | |
| 101 | // HACK(eddyb) this acts like an integration test for specialization constants, |
| 102 | // but the correct value is only obtained when this is a noop (multiplies by `1`). |
| 103 | * (sun_intensity_extra_spec_const_factor as f32 / 100.0); |
| 104 | |
| 105 | let mut lin = pow( |
| 106 | sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * (Vec3::splat(1.0) - fex), |
| 107 | 1.5, |
| 108 | ); |
| 109 | |
| 110 | lin *= Vec3::splat(1.0).lerp( |
| 111 | pow( |
| 112 | sun_e * ((beta_r_theta + beta_m_theta) / (beta_r + beta_m)) * fex, |
| 113 | 0.5, |
| 114 | ), |
| 115 | saturate((1.0 - up.dot(sun_direction)).powf(5.0)), |
| 116 | ); |
| 117 | |
| 118 | // Composition + solar disc |
| 119 | let sun_angular_diameter_cos = SUN_ANGULAR_DIAMETER_DEGREES.cos(); |
| 120 | let sundisk = smoothstep( |
| 121 | sun_angular_diameter_cos, |
| 122 | sun_angular_diameter_cos + 0.00002, |
| 123 | cos_theta, |
| 124 | ); |
| 125 | let mut l0 = 0.1 * fex; |
| 126 | l0 += sun_e * 19000.0 * fex * sundisk; |
| 127 | |
| 128 | lin + l0 |
| 129 | } |
| 130 | |
| 131 | fn get_ray_dir(uv: Vec2, pos: Vec3, look_at_pos: Vec3) -> Vec3 { |
no test coverage detected