// Copyright (c) 2023-2025 Cory Petkovsek and Contributors // Copyright (c) 2021 J. Cuellar const float INV_PI = 1. / PI; const float HALF_PI = PI / 2.; const float INV_HALF_PI = 1. / HALF_PI; const float QRT_PI = PI / 4.; const float INV_QRT_PI = 1. / QRT_PI; const float PI4 = PI * 4.; const float INV_PI4 = 1. / PI4; const float INV_TAU = 1. / TAU; const float RAYLEIGH_ZENITH_LENGTH = 8.4e3; const float MIE_ZENITH_LENGTH = 1.25e3; const float THREE_OVER_EIGHT_PI = 3.0 / (8.0 * PI); float clamp_to_unit(float value) { return clamp(value, 0.0, 1.0); } vec3 clamp_rgb_to_unit(vec3 value) { return clamp(value.rgb, 0.0, 1.0); } vec3 adjust_contrast(vec3 vec, float level) { return mix(vec, vec * vec * vec, level); // pow3 } vec3 apply_photo_tonemap(vec3 color, float exposure, float level) { color.rgb *= exposure; return mix(color.rgb, 1.0 - exp(-color.rgb), level); } float calc_rayleigh_phase(float mu) { return THREE_OVER_EIGHT_PI * (1.0 + mu * mu); } float calc_mie_phase(float mu, vec3 partial) { float denominator = partial.y - partial.z * mu; float safe_denominator = max(denominator, 0.0001); // Prevent division by zero on negative powers return PI4 * partial.x * pow(safe_denominator, -1.5); } // Simplifield for more performance void calc_simple_optical_depth(float y, out float sr, out float sm, vec2 params) { y = max(0.03, y + 0.03) + params.y; y = 1.0 / (y * params.x); sr = y * RAYLEIGH_ZENITH_LENGTH; sm = y * MIE_ZENITH_LENGTH; } // Paper based (Unused) void calc_optical_depth(float y, out float sr, out float sm, vec2 params) { y = max(0.0, y); y = clamp_to_unit(y * params.x); float zenith = acos(y); zenith = cos(zenith) + 0.15 * pow(93.885 - ((zenith * 180.0) * INV_PI), -1.253); zenith = 1.0 / (zenith + params.y); sr = zenith * RAYLEIGH_ZENITH_LENGTH; sm = zenith * MIE_ZENITH_LENGTH; }