From a76f15dd9f91d4f7d68cbf0051cfbf9101bdf66b Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 23 Mar 2021 13:37:14 +0000 Subject: [PATCH] Softer and faster clouds with more verticality --- assets/voxygen/shaders/fluid-frag/shiny.glsl | 2 +- .../shaders/include/cloud/regular.glsl | 165 ++++++++++-------- assets/voxygen/shaders/include/sky.glsl | 35 ++-- assets/voxygen/shaders/lod-terrain-frag.glsl | 2 +- assets/voxygen/shaders/particle-vert.glsl | 2 +- assets/voxygen/texture/noise.png | Bin 9532 -> 3340 bytes world/src/sim2/mod.rs | 2 +- 7 files changed, 110 insertions(+), 98 deletions(-) diff --git a/assets/voxygen/shaders/fluid-frag/shiny.glsl b/assets/voxygen/shaders/fluid-frag/shiny.glsl index b73dc24393..0c5865394b 100644 --- a/assets/voxygen/shaders/fluid-frag/shiny.glsl +++ b/assets/voxygen/shaders/fluid-frag/shiny.glsl @@ -179,7 +179,7 @@ void main() { // Squared to account for prior saturation. float f_light = 1.0;// pow(f_light, 1.5); vec3 reflect_color = get_sky_color(/*reflect_ray_dir*/beam_view_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true); - reflect_color = get_cloud_color(reflect_color, reflect_ray_dir, cam_pos.xyz, time_of_day.x, 100000.0, 0.25); + reflect_color = get_cloud_color(reflect_color, reflect_ray_dir, cam_pos.xyz, time_of_day.x, 100000.0, 0.1); reflect_color *= f_light; // /*const */vec3 water_color = srgb_to_linear(vec3(0.2, 0.5, 1.0)); // /*const */vec3 water_color = srgb_to_linear(vec3(0.8, 0.9, 1.0)); diff --git a/assets/voxygen/shaders/include/cloud/regular.glsl b/assets/voxygen/shaders/include/cloud/regular.glsl index 0e02b3116f..08b69bff69 100644 --- a/assets/voxygen/shaders/include/cloud/regular.glsl +++ b/assets/voxygen/shaders/include/cloud/regular.glsl @@ -1,37 +1,36 @@ #include #include -const float CLOUD_THRESHOLD = 0.27; -const float CLOUD_SCALE = 5.0; -const float CLOUD_DENSITY = 150.0; - -vec2 get_cloud_heights(vec2 pos) { - const float CLOUD_HALF_WIDTH = 300; - const float CLOUD_HEIGHT_VARIATION = 1500.0; - float cloud_alt = CLOUD_AVG_ALT + (texture(t_noise, pos.xy * 0.00005).x - 0.5) * CLOUD_HEIGHT_VARIATION; - #if (CLOUD_MODE > CLOUD_MODE_MINIMAL) - cloud_alt += (texture(t_noise, pos.xy * 0.001).x - 0.5) * 0.1 * CLOUD_HEIGHT_VARIATION; - #endif - return vec2(cloud_alt, CLOUD_HALF_WIDTH); +float falloff(float x) { + return pow(max(x > 0.577 ? (0.3849 / x - 0.1) : (0.9 - x * x), 0.0), 4); } float emission_strength = clamp((sin(time_of_day.x / (3600 * 24)) - 0.8) / 0.1, 0, 1); +// 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(40000.0), 30000.0) / cloud_scale + 1000.0) - 0.5) + ; +} + // Returns vec4(r, g, b, density) vec4 cloud_at(vec3 pos, float dist, out vec3 emission) { // Natural attenuation of air (air naturally attenuates light that passes through it) // Simulate the atmosphere thinning as you get higher. Not physically accurate, but then // it can't be since Veloren's world is flat, not spherical. - float air = 0.00035 * clamp((10000.0 - pos.z) / 7000, 0, 1); + float atmosphere_alt = CLOUD_AVG_ALT * 4.0; + float air = 0.0000025 * clamp((atmosphere_alt - pos.z) / 7000, 0, 1); // 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_LOW) - mist_min_alt = (texture(t_noise, pos.xy * 0.00015).x - 0.5) * 1.25 + 0.5; + #if (CLOUD_MODE >= CLOUD_MODE_MEDIUM) + mist_min_alt = (texture(t_noise, pos.xy / 50000.0).x - 0.5) * 1.5 + 0.5; #endif - mist_min_alt *= 250; + mist_min_alt = view_distance.z * 1.5 * (1.0 + mist_min_alt * 0.5); const float MIST_FADE_HEIGHT = 500; - float mist = 0.00125 * pow(clamp(1.0 - (pos.z - mist_min_alt) / MIST_FADE_HEIGHT, 0.0, 1), 4.0) / (1.0 + pow(1.0 + dist / 20000.0, 2.0)); + float mist = 0.00025 * pow(clamp(1.0 - (pos.z - mist_min_alt) / MIST_FADE_HEIGHT, 0.0, 1), 4.0) / (1.0 + pow(1.0 + dist / 20000.0, 2.0)); vec3 wind_pos = vec3(pos.xy + wind_offset, pos.z); @@ -39,54 +38,76 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission) { float cloud_tendency = cloud_tendency_at(pos.xy); float cloud = 0; - vec2 cloud_attr = get_cloud_heights(wind_pos.xy); - float cloud_factor = 0.0; - float turb_noise = 0.0; + //vec2 cloud_attr = get_cloud_heights(wind_pos.xy); float sun_access = 0.0; float moon_access = 0.0; float cloud_sun_access = 0.0; 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 (cloud_tendency > 0 || mist > 0.0) { + if ((pos.z < CLOUD_AVG_ALT + 15000.0 && cloud_tendency > 0.0) || mist > 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; + mist *= 0.5 + + 4 * (noise_2d(wind_pos.xy / 20000) - 0.5) + + 1 * (noise_3d(wind_pos / 1000) - 0.5); + + const float CLOUD_DEPTH = 4000.0; + const float CLOUD_DENSITY = 5.0; + const float CLOUD_ALT_VARI_WIDTH = 100000.0; + const float CLOUD_ALT_VARI_SCALE = 5000.0; + float cloud_alt = CLOUD_AVG_ALT + (noise_3d(wind_pos / CLOUD_ALT_VARI_WIDTH) - 0.5) * CLOUD_ALT_VARI_SCALE; + + 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 + (0.0 + + 24 * (cloud_broad_a + cloud_broad_b) * 0.5 #if (CLOUD_MODE >= CLOUD_MODE_MINIMAL) - turb_noise = noise_3d((wind_pos + turb_offset) * 0.001) - 0.5; + + 4 * (noise_3d(wind_pos / 2000.0 / cloud_scale) - 0.5) #endif - #if (CLOUD_MODE >= CLOUD_MODE_MEDIUM) - turb_noise += (noise_3d((wind_pos + turb_offset * 0.3) * 0.004) - 0.5) * 0.35; + #if (CLOUD_MODE >= CLOUD_MODE_LOW) + + 1 * (noise_3d(wind_pos / 250.0 / cloud_scale) - 0.5) #endif #if (CLOUD_MODE >= CLOUD_MODE_HIGH) - turb_noise += (noise_3d((wind_pos + turb_offset * 0.3) * 0.01) - 0.5) * 0.125; + + 1 * (noise_3d(wind_pos / 50.0 / cloud_scale) - 0.5) #endif - mist *= 1.0 + turb_noise; - - cloud_factor = 0.25 * (1.0 - pow(min(abs(pos.z - cloud_attr.x) / (cloud_attr.y * pow(max(cloud_tendency * 20.0, 0), 0.5)), 1.0), 1.0)); - float cloud_flat = min(cloud_tendency, 0.07) * 0.05; - cloud_flat *= (1.0 + turb_noise * 7.0 * max(0, 1.0 - cloud_factor * 5)); - cloud = cloud_flat * pow(cloud_factor, 2) * 20; + ) * 0.01; + cloud = pow(cloud, 2) * sign(cloud); + cloud *= CLOUD_DENSITY * (cloud_tendency * 100) * falloff(abs(pos.z - cloud_alt) / CLOUD_DEPTH); // What proportion of sunlight is *not* being blocked by nearby cloud? (approximation) - cloud_sun_access = clamp((pos.z - cloud_attr.x + turb_noise * 250.0) * 0.002 + 0.35, 0, 1); - // Since we're assuming the sun/moon is always above (not always correct) it's the same for the moon - cloud_moon_access = sun_access; - + // Basically, just throw together a few values that roughly approximate this term and come up with an average + cloud_sun_access = (clamp(( + // 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) - // 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) / 250 + turb_noise + 0.5 - ); - cloud_sun_access = mix(max(dot(-sun_dir.xyz, cloud_norm) + 0.0, 0.025), cloud_sun_access, 0.25); - cloud_moon_access = mix(max(dot(-moon_dir.xyz, cloud_norm) + 0.35, 0.025), cloud_moon_access, 0.25); + // More noise + + 0.01 * (noise_3d(wind_pos / 500) / cloud_scale - 0.5) #endif + ) * 6.0 - 0.7, -0.95, 1) + 1.0); + // 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; } - float mist_sun_access = 0.5 + turb_noise * 0.5; + // 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 = noise_2d(wind_pos.xy / 10000); 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)); @@ -104,21 +125,15 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission) { if (emission_strength <= 0.0) { emission = vec3(0); } else { - float z = clamp(pos.z, 0, 10000); - float emission_alt = 4000.0; - #if (CLOUD_MODE >= CLOUD_MODE_LOW) - emission_alt += (noise_3d(vec3(wind_pos.xy * 0.00003 + cloud_tendency * 0.2, time_of_day.x * 0.0001)) - 0.5) * 6000; - #endif - #if (CLOUD_MODE >= CLOUD_MODE_HIGH) - emission_alt += (noise_3d(vec3(wind_pos.xy * 0.0005 + cloud_tendency * 0.2, emission_alt * 0.0001 + time_of_day.x * 0.0005)) - 0.5) * 1000; - #endif - float tail = (texture(t_noise, wind_pos.xy * 0.00005).x - 0.5) * 10 + (z - emission_alt) * 0.001; - vec3 emission_col = vec3(0.6 + tail * 0.6, 1.0, 0.3 + tail * 0.2); - float emission_nz = max(texture(t_noise, wind_pos.xy * 0.00003).x - 0.6, 0) / (10.0 + abs(z - emission_alt) / 40); + float z = clamp(pos.z, 0, CLOUD_AVG_ALT * 2.0 + 5000.0); + float emission_alt = CLOUD_AVG_ALT * 2.0 - 3000.0 + (noise_3d(vec3(wind_pos.xy * 0.0001 + cloud_tendency * 0.2, time_of_day.x * 0.0002)) - 0.5) * 6000; #if (CLOUD_MODE >= CLOUD_MODE_MEDIUM) - emission_nz *= (1.0 + (noise_3d(vec3(wind_pos.xy * 0.05, time_of_day.x * 0.15) * 0.004) - 0.5) * 4.0); + emission_alt += (noise_3d(vec3(wind_pos.xy * 0.0005 + cloud_tendency * 0.2, emission_alt * 0.0001 + time_of_day.x * 0.001)) - 0.5) * 1000; #endif - emission = emission_col * emission_nz * emission_strength * max(sun_dir.z, 0) * 20; + float tail = (texture(t_noise, wind_pos.xy * 0.00005).x - 0.5) * 5 + (z - emission_alt) * 0.001; + vec3 emission_col = vec3(0.8 + tail * 1.5, 0.5 - tail * 0.2, 0.3 + tail * 0.2); + float emission_nz = max(texture(t_noise, wind_pos.xy * 0.00003).x - 0.6, 0) / (10.0 + abs(z - emission_alt) / 80); + emission = emission_col * emission_nz * emission_strength * max(sun_dir.z, 0) * 500000 / (1000.0 + abs(z - emission_alt)); } // We track vapor density and air density separately. Why? Because photons will ionize particles in air @@ -138,11 +153,11 @@ const float DIST_CAP = 50000; #elif (CLOUD_MODE == CLOUD_MODE_HIGH) const uint QUALITY = 50u; #elif (CLOUD_MODE == CLOUD_MODE_MEDIUM) - const uint QUALITY = 30u; + const uint QUALITY = 24u; #elif (CLOUD_MODE == CLOUD_MODE_LOW) - const uint QUALITY = 16u; + const uint QUALITY = 12u; #elif (CLOUD_MODE == CLOUD_MODE_MINIMAL) - const uint QUALITY = 5u; + const uint QUALITY = 4u; #endif const float STEP_SCALE = DIST_CAP / (10.0 * float(QUALITY)); @@ -175,11 +190,14 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of splay += (texture(t_noise, vec2(atan2(dir.x, dir.y) * 2 / PI, dir.z) * 5.0 - time_of_day * 0.00005).x - 0.5) * 0.075 / (1.0 + pow(dir.z, 2) * 10); #endif + /* const float RAYLEIGH = 0.25; */ + const vec3 RAYLEIGH = vec3(0.001, 1.3, 5.0); + // Proportion of sunlight that get scattered back into the camera by clouds - float sun_scatter = max(dot(-dir, sun_dir.xyz), 0.5); - float moon_scatter = max(dot(-dir, moon_dir.xyz), 0.5); - vec3 sky_color = get_sky_color(); + float sun_scatter = pow(dot(-dir, sun_dir.xyz) * 0.5 + 0.5, 2) + 0.25; + float moon_scatter = pow(dot(-dir, moon_dir.xyz) * 0.5 + 0.5, 2) + 0.25; float net_light = get_sun_brightness() + get_moon_brightness(); + vec3 sky_color = RAYLEIGH * net_light; float cdist = max_dist; float ldist = cdist; @@ -196,22 +214,21 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of float sun_access = sample.x; float moon_access = sample.y; - float scatter_factor = 1.0 - 1.0 / (1.0 + density_integrals.x); - - const float RAYLEIGH = 0.25; + float cloud_scatter_factor = 1.0 - 1.0 / (1.0 + clamp(density_integrals.x, 0, 1)); + float global_scatter_factor = 1.0 - 1.0 / (1.0 + clamp(density_integrals.y, 0, 1)); surf_color = // Attenuate light passing through the clouds - surf_color * (1.0 - scatter_factor) + + surf_color * (1.0 - cloud_scatter_factor - global_scatter_factor) + // This is not rayleigh scattering, but it's good enough for our purposes (only considers sun) - (1.0 - surf_color) * net_light * sky_color * density_integrals.y * RAYLEIGH + + (1.0 - surf_color) * net_light * sky_color * density_integrals.y + // Add the directed light light scattered into the camera by the clouds - get_sun_color() * sun_scatter * sun_access * scatter_factor * get_sun_brightness() + - get_moon_color() * moon_scatter * moon_access * scatter_factor * get_moon_brightness() + + get_sun_color() * sun_scatter * (sun_access * cloud_scatter_factor + global_scatter_factor) * get_sun_brightness() + + get_moon_color() * moon_scatter * moon_access * cloud_scatter_factor * get_moon_brightness() + emission * density_integrals.y + // Global illumination (uniform scatter from the sky) - sky_color * sun_access * scatter_factor * get_sun_brightness() + - sky_color * moon_access * scatter_factor * get_moon_brightness(); + (sun_access * cloud_scatter_factor + sky_color * global_scatter_factor) * get_sun_brightness() + + (moon_access * cloud_scatter_factor + sky_color * global_scatter_factor) * get_moon_brightness(); } return surf_color; diff --git a/assets/voxygen/shaders/include/sky.glsl b/assets/voxygen/shaders/include/sky.glsl index b614efbd7f..082ddc7b74 100644 --- a/assets/voxygen/shaders/include/sky.glsl +++ b/assets/voxygen/shaders/include/sky.glsl @@ -76,17 +76,16 @@ vec3 glow_light(vec3 pos) { // return normalize(-vec3(sin(moon_angle_rad), 0.0, cos(moon_angle_rad) - 0.5)); //} -float CLOUD_AVG_ALT = view_distance.z + 0.75 * view_distance.w; +float CLOUD_AVG_ALT = view_distance.z + 1.25 * view_distance.w; const float wind_speed = 0.25; vec2 wind_offset = vec2(time_of_day.x * wind_speed); +float cloud_scale = view_distance.z / 150.0; + float cloud_tendency_at(vec2 pos) { - float nz = texture(t_noise, (pos + wind_offset) * 0.000075).x - 0.5; - nz = clamp(nz, 0, 1); - #if (CLOUD_MODE >= CLOUD_MODE_MEDIUM) - nz += (texture(t_noise, (pos + wind_offset) * 0.00035).x - 0.5) * 0.15; - #endif + float nz = texture(t_noise, (pos + wind_offset) / 60000.0 / cloud_scale).x - 0.3; + nz = pow(clamp(nz, 0, 1), 4); return nz; } @@ -101,7 +100,7 @@ float cloud_shadow(vec3 pos, vec3 light_dir) { float fade = 1.0 - clamp((length(xy_offset) - FADE_RANGE.x) / (FADE_RANGE.y - FADE_RANGE.x), 0, 1); float cloud = cloud_tendency_at(pos.xy + focus_off.xy - xy_offset); - cloud = cloud * 2.0; + cloud = cloud * 15.0; return clamp(1 - fade * cloud * 1.65, 0, 1); #endif @@ -112,7 +111,7 @@ float get_sun_brightness(/*vec3 sun_dir*/) { } float get_moon_brightness(/*vec3 moon_dir*/) { - return max(-moon_dir.z + 0.6, 0.0) * 0.2; + return max(-moon_dir.z + 0.6, 0.0) * 0.01; } vec3 get_sun_color(/*vec3 sun_dir*/) { @@ -142,7 +141,7 @@ vec3 get_sky_color(/*vec3 sun_dir*/) { } vec3 get_moon_color(/*vec3 moon_dir*/) { - return vec3(0.05, 0.05, 0.6); + return vec3(0.05, 0.05, 1.6); } DirectionalLight get_sun_info(vec4 _dir, float shade_frac/*, vec4 light_pos[2]*/, /*vec4 sun_pos*/vec3 f_pos) { @@ -413,7 +412,7 @@ float is_star_at(vec3 dir) { //return 0.0; - return 1.0 / (1.0 + pow(dist * 1000, 8)); + return 0.25 / (1.0 + pow(dist * 750, 8)); } vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_features, float refractionIndex) { @@ -434,7 +433,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q } // Sun - const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 3.0; + const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 4.0; vec3 sun_halo_color = mix( SUN_HALO_DUSK, @@ -442,7 +441,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q max(-sun_dir.z, 0.0) ); - vec3 sun_halo = sun_halo_color * 16 * pow(max(dot(dir, -sun_dir), 0), 8.0); + vec3 sun_halo = sun_halo_color * 16 * pow(max(dot(dir, -sun_dir), 0), 20.0); vec3 sun_surf = vec3(0); if (with_features) { float angle = 0.00035; @@ -455,7 +454,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q const vec3 MOON_HALO_COLOR = vec3(0.015, 0.015, 0.05) * 25; vec3 moon_halo_color = MOON_HALO_COLOR; - vec3 moon_halo = moon_halo_color * pow(max(dot(dir, -moon_dir), 0), 500.0); + vec3 moon_halo = moon_halo_color * 4 * pow(max(dot(dir, -moon_dir), 0), 4000.0); vec3 moon_surf = vec3(0); if (with_features) { float angle = 0.00035; @@ -465,6 +464,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q // Replaced all clamp(sun_dir, 0, 1) with max(sun_dir, 0) because sun_dir is calculated from sin and cos, which are never > 1 + /* vec3 sky_top = mix( mix( SKY_DUSK_TOP + star / (1.0 + moon_surf * 100.0), @@ -503,14 +503,9 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q sky_top, max(dir.z, 0) ); + */ - // Approximate distance to fragment - float f_dist = distance(origin, f_pos); - - if (f_dist > 5000.0) { - sky_color += sun_light + moon_light; - } - return sky_color; + return star + sun_light + moon_light; } vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars) { diff --git a/assets/voxygen/shaders/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index defb468ec7..1fe702656c 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -648,7 +648,7 @@ void main() { float passthrough = dot(faceforward(f_norm, f_norm, cam_to_frag), -cam_to_frag); vec3 reflect_color = get_sky_color(reflect_ray, time_of_day.x, f_pos, vec3(-100000), 0.125, true); - reflect_color = get_cloud_color(reflect_color, reflect_ray, cam_pos.xyz, time_of_day.x, 100000.0, 0.25); + reflect_color = get_cloud_color(reflect_color, reflect_ray, cam_pos.xyz, time_of_day.x, 100000.0, 0.1); const float REFLECTANCE = 0.5; surf_color = illuminate(max_light, view_dir, f_col * emitted_light, reflect_color * REFLECTANCE + water_color * reflected_light); diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 1e632c8ff0..e19bb3eb34 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -294,7 +294,7 @@ void main() { ); } else if (inst_mode == SNOW) { float height = mix(-4, 60, pow(start_end(1, 0), 3)); - float wind_speed = (inst_pos.z - 250) * 0.025; + float wind_speed = (inst_pos.z - 2000) * 0.025; vec3 offset = linear_motion(vec3(0), vec3(1, 1, 0) * wind_speed); float end_alt = alt_at(start_pos.xy + offset.xy); attr = Attr( diff --git a/assets/voxygen/texture/noise.png b/assets/voxygen/texture/noise.png index 1ffcbb1be0dab9b57ba1f0e79b26e548b10b33a4..9beb9aa59a1b0acf0598cc41e283f9d2e8e964dd 100644 GIT binary patch delta 3303 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