From 94c0e3749e75b0bb05786ee262dd51bea46b562a Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 15 Dec 2022 23:56:28 +0000 Subject: [PATCH 1/3] Improved cloud visuals and performance --- .../shaders/include/cloud/regular.glsl | 104 ++++++++---------- assets/voxygen/shaders/include/sky.glsl | 2 +- assets/voxygen/texture/noise.png | 4 +- 3 files changed, 50 insertions(+), 60 deletions(-) diff --git a/assets/voxygen/shaders/include/cloud/regular.glsl b/assets/voxygen/shaders/include/cloud/regular.glsl index 1dca0d58d3..98fd74eaa5 100644 --- a/assets/voxygen/shaders/include/cloud/regular.glsl +++ b/assets/voxygen/shaders/include/cloud/regular.glsl @@ -7,12 +7,12 @@ float falloff(float x) { return pow(max(x > 0.577 ? (0.3849 / x - 0.1) : (0.9 - x * x), 0.0), 4); } -// Return the 'broad' density of the cloud at a position. This gets refined later with extra noise, but is important -// for computing light access. -float cloud_broad(vec3 pos) { - return 0.0 - + 2 * (noise_3d(pos / vec3(vec2(30000.0), 20000.0) / cloud_scale + 1000.0) - 0.5) - ; +float billow_noise_3d(vec3 pos) { + return abs(noise_3d(pos) - 0.5) * 2.0; +} + +float billow_noise_2d(vec2 pos) { + return abs(noise_2d(pos) - 0.5) * 2.0; } // Returns vec4(r, g, b, density) @@ -38,7 +38,7 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground // Mist sits close to the ground in valleys (TODO: use base_alt to put it closer to water) float mist_min_alt = 0.5; #if (CLOUD_MODE >= CLOUD_MODE_MEDIUM) - mist_min_alt = (textureLod(sampler2D(t_noise, s_noise), pos.xy / 50000.0, 0).x - 0.5) * 1.5 + 0.5; + mist_min_alt = (textureLod(sampler2D(t_noise, s_noise), pos.xy / 35000.0, 0).x - 0.5) * 1.5 + 0.5; #endif mist_min_alt = view_distance.z * 1.5 * (1.0 + mist_min_alt * 0.5) + alt * 0.5 + 250; const float MIST_FADE_HEIGHT = 1000; @@ -61,81 +61,66 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground ; } - float cloud_alt = alt + 1800; + float CLOUD_DEPTH = (view_distance.w - view_distance.z) * (0.2 + sqrt(cloud_tendency) * 0.5); + float cloud_alt = alt + CLOUD_DEPTH * 2 + 1000.0; //vec2 cloud_attr = get_cloud_heights(wind_pos.xy); float sun_access = 0.0; float moon_access = 0.0; float cloud_sun_access = clamp((pos.z - cloud_alt) / 1500 + 0.5, 0, 1); float cloud_moon_access = 0.0; - float cloud_broad_a = 0.0; - float cloud_broad_b = 0.0; // This is a silly optimisation but it actually nets us a fair few fps by skipping quite a few expensive calcs - if ((pos.z < CLOUD_AVG_ALT + 15000.0 && cloud_tendency > 0.0)) { + if ((pos.z < CLOUD_AVG_ALT + 8000.0 && cloud_tendency > 0.0)) { // Turbulence (small variations in clouds/mist) const float turb_speed = -1.0; // Turbulence goes the opposite way vec3 turb_offset = vec3(1, 1, 0) * time_of_day.x * turb_speed; - float CLOUD_DEPTH = (view_distance.w - view_distance.z) * 0.8; const float CLOUD_DENSITY = 10000.0; const float CLOUD_ALT_VARI_WIDTH = 100000.0; const float CLOUD_ALT_VARI_SCALE = 5000.0; - cloud_broad_a = cloud_broad(wind_pos + sun_dir.xyz * 250); - cloud_broad_b = cloud_broad(wind_pos - sun_dir.xyz * 250); - cloud = cloud_tendency + cloud_tendency * (0.0 - + 24 * (cloud_broad_a + cloud_broad_b) * 0.5 - #if (CLOUD_MODE >= CLOUD_MODE_MINIMAL) - + 4 * (noise_3d((wind_pos + turb_offset) / 2000.0 / cloud_scale) - 0.5) + float small_nz = 0.0 + #if (CLOUD_MODE >= CLOUD_MODE_MEDIUM) + - (billow_noise_3d((pos + turb_offset * 0.5) / 8000.0) - 0.5) + #else + - (billow_noise_2d((pos.xy + turb_offset.xy * 0.5) / 8000.0) - 0.5) #endif #if (CLOUD_MODE >= CLOUD_MODE_LOW) - + 0.75 * (noise_3d((wind_pos + turb_offset * 0.5) / 750.0 / cloud_scale) - 0.5) + - (noise_3d((pos - turb_offset * 0.1) / 1500.0) - 0.5) * 0.5 #endif - #if (CLOUD_MODE >= CLOUD_MODE_HIGH) - + 0.75 * (noise_3d(wind_pos / 500.0 / cloud_scale) - 0.5) - #endif - ) * 0.1; - cloud = pow(max(cloud, 0), 3) * sign(cloud); - cloud *= CLOUD_DENSITY * sqrt(cloud_tendency + 0.001) * falloff(abs(pos.z - cloud_alt) / CLOUD_DEPTH); + ; + + // Sample twice to allow for self-shadowing + float cloud_p0 = noise_3d((wind_pos + vec3(0, 0, small_nz) * 250 - sun_dir.xyz * 250) * vec3(0.55, 0.55, 1) / (cloud_scale * 20000.0)); + float cloud_p1 = noise_3d((wind_pos + vec3(0, 0, small_nz) * 250 + sun_dir.xyz * 250) * vec3(0.55, 0.55, 1) / (cloud_scale * 20000.0)); + + float cloud_factor = pow(max(((cloud_p0 + cloud_p1) * 0.5 + - 0.5 + - small_nz * 0.1 + + cloud_tendency * 0.3 + ) + , 0.0) * 120.0 * cloud_tendency, 5.0) + * falloff(abs(pos.z - cloud_alt) / CLOUD_DEPTH); + + cloud = cloud_factor * 10; // What proportion of sunlight is *not* being blocked by nearby cloud? (approximation) // Basically, just throw together a few values that roughly approximate this term and come up with an average - cloud_sun_access = mix(cloud_sun_access, exp(( - // Cloud density gradient - 0.25 * (cloud_broad_a - cloud_broad_b + (0.25 * (noise_3d(wind_pos / 4000 / cloud_scale) - 0.5) + 0.1 * (noise_3d(wind_pos / 1000 / cloud_scale) - 0.5))) - #if (CLOUD_MODE >= CLOUD_MODE_HIGH) - // More noise - + 0.01 * (noise_3d(wind_pos / 500) / cloud_scale - 0.5) - #endif - ) * 15.0 - 1.5) * 1.5, min(cloud_tendency * 10, 1)); + cloud_sun_access = clamp( + 0.7 + + pow(abs(cloud_p1 - cloud_p0), 0.5) * sign(cloud_p1 - cloud_p0) * 0.5 + + (pos.z - cloud_alt) / CLOUD_DEPTH * 0.4 + - pow(cloud * 10000000.0, 0.2) * 0.0075 + , + 0.15, + 10.0 + ) + small_nz * 0.2; // Since we're assuming the sun/moon is always above (not always correct) it's the same for the moon cloud_moon_access = 1.0 - cloud_sun_access; } - #if (CLOUD_MODE >= CLOUD_MODE_LOW) - cloud += max(noise_3d((wind_pos) / 25000.0 / cloud_scale) - 0.75 + noise_3d((wind_pos) / 2500.0 / cloud_scale) * 0.1, 0) - * 0.1 - / (abs(pos.z - cloud_alt) / 500.0 + 0.2); - #endif - - // Keeping this because it's something I'm likely to reenable later - /* - #if (CLOUD_MODE >= CLOUD_MODE_HIGH) - // Try to calculate a reasonable approximation of the cloud normal - float cloud_tendency_x = cloud_tendency_at(pos.xy + vec2(100, 0)); - float cloud_tendency_y = cloud_tendency_at(pos.xy + vec2(0, 100)); - vec3 cloud_norm = vec3( - (cloud_tendency - cloud_tendency_x) * 4, - (cloud_tendency - cloud_tendency_y) * 4, - (pos.z - cloud_attr.x) / cloud_attr.y + 0.5 - ); - cloud_sun_access = mix(max(dot(-sun_dir.xyz, cloud_norm) - 1.0, 0.025), cloud_sun_access, 0.25); - cloud_moon_access = mix(max(dot(-moon_dir.xyz, cloud_norm) - 0.6, 0.025), cloud_moon_access, 0.25); - #endif - */ - - float mist_sun_access = exp(mist); + float mist_sun_access = max(1.0 - cloud_tendency * 8, 0.25); float mist_moon_access = mist_sun_access; sun_access = mix(cloud_sun_access, mist_sun_access, clamp(mist * 20000, 0, 1)); moon_access = mix(cloud_moon_access, mist_moon_access, clamp(mist * 20000, 0, 1)); @@ -258,6 +243,11 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of // `sample` is a reserved keyword vec4 sample_ = cloud_at(origin + dir * ldist * splay, ldist, emission, not_underground); + // DEBUG + // if (max_dist > ldist && max_dist < ldist * 1.02) { + // surf_color = vec3(1, 0, 0); + // } + vec2 density_integrals = max(sample_.zw, vec2(0)); float sun_access = max(sample_.x, 0); @@ -269,7 +259,7 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of float cloud_darken = pow(1.0 / (1.0 + cloud_scatter_factor), step); float global_darken = pow(1.0 / (1.0 + global_scatter_factor), step); // Proportion of light diffusely scattered instead of absorbed - float cloud_diffuse = 0.25; + float cloud_diffuse = 0.5; surf_color = // Attenuate light passing through the clouds diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index 46c3336668..dfb5a9e8e1 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -155,7 +155,7 @@ float magnetosphere = sin(time_of_day.x / (3600 * 24)); #endif #if (CLOUD_MODE > CLOUD_MODE_NONE) float emission_strength = clamp((magnetosphere - 0.3) * 1.3, 0, 1) * max(-moon_dir.z, 0); - #if (CLOUD_MODE > CLOUD_MODE_MEDIUM) + #if (CLOUD_MODE >= CLOUD_MODE_MEDIUM) float emission_br = abs(pow(fract(time_of_day.x * 0.000005) * 2 - 1, 2)); #else float emission_br = 0.5; diff --git a/assets/voxygen/texture/noise.png b/assets/voxygen/texture/noise.png index 75f4c0cba0..6deee0a90f 100644 --- a/assets/voxygen/texture/noise.png +++ b/assets/voxygen/texture/noise.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1473f41bb054629b6a3a1712f645c6a2d0a093aa81494c7abf59b70b0495053c -size 2957 +oid sha256:64892cf1730144f46b0b538b5a977bc1c365bceafc82e7db0a9ea59fe8a17da9 +size 29903 From 5cf3aefb87994919a840c0c68e539246ad759731 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 17 Dec 2022 14:57:55 +0000 Subject: [PATCH 2/3] Better storm clouds --- assets/voxygen/shaders/include/cloud/regular.glsl | 7 +++++-- assets/voxygen/shaders/include/point_glow.glsl | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/assets/voxygen/shaders/include/cloud/regular.glsl b/assets/voxygen/shaders/include/cloud/regular.glsl index 98fd74eaa5..636b7853a8 100644 --- a/assets/voxygen/shaders/include/cloud/regular.glsl +++ b/assets/voxygen/shaders/include/cloud/regular.glsl @@ -86,8 +86,11 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground #else - (billow_noise_2d((pos.xy + turb_offset.xy * 0.5) / 8000.0) - 0.5) #endif - #if (CLOUD_MODE >= CLOUD_MODE_LOW) - - (noise_3d((pos - turb_offset * 0.1) / 1500.0) - 0.5) * 0.5 + #if (CLOUD_MODE >= CLOUD_MODE_CLOUD_MODE_MINIMAL) + - (noise_3d((pos - turb_offset * 0.1) / 750.0) - 0.5) * 0.25 + #endif + #if (CLOUD_MODE >= CLOUD_MODE_CLOUD_MODE_HIGH) + - (billow_noise_3d((pos - turb_offset * 0.1) / 500.0) - 0.5) * 0.1 #endif ; diff --git a/assets/voxygen/shaders/include/point_glow.glsl b/assets/voxygen/shaders/include/point_glow.glsl index 8331e2b7ad..a283447a70 100644 --- a/assets/voxygen/shaders/include/point_glow.glsl +++ b/assets/voxygen/shaders/include/point_glow.glsl @@ -18,7 +18,7 @@ void apply_point_glow_light(Light L, vec3 wpos, vec3 dir, float max_dist, inout #if (CLOUD_MODE >= CLOUD_MODE_HIGH) vec3 _unused; float unused2; - float spread = 1.0 / (1.0 + cloud_at(nearest, 0.0, _unused, unused2).z * 0.005); + float spread = 1.0 / (1.0 + sqrt(cloud_at(nearest, 0.0, _unused, unused2).z) * 0.01); #else const float spread = 1.0; #endif From dcc47621060a1341a3b2b716b0d08ea017cdd3f3 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 17 Dec 2022 15:04:57 +0000 Subject: [PATCH 3/3] Fixed moon lighting of clouds --- assets/voxygen/shaders/include/cloud/regular.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/voxygen/shaders/include/cloud/regular.glsl b/assets/voxygen/shaders/include/cloud/regular.glsl index 636b7853a8..636a767f9f 100644 --- a/assets/voxygen/shaders/include/cloud/regular.glsl +++ b/assets/voxygen/shaders/include/cloud/regular.glsl @@ -120,7 +120,7 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground 10.0 ) + small_nz * 0.2; // Since we're assuming the sun/moon is always above (not always correct) it's the same for the moon - cloud_moon_access = 1.0 - cloud_sun_access; + cloud_moon_access = cloud_sun_access; } float mist_sun_access = max(1.0 - cloud_tendency * 8, 0.25);