mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improved cloud visuals and performance
This commit is contained in:
parent
c90be1b56c
commit
94c0e3749e
@ -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 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
|
float billow_noise_3d(vec3 pos) {
|
||||||
// for computing light access.
|
return abs(noise_3d(pos) - 0.5) * 2.0;
|
||||||
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_2d(vec2 pos) {
|
||||||
;
|
return abs(noise_2d(pos) - 0.5) * 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns vec4(r, g, b, density)
|
// 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)
|
// Mist sits close to the ground in valleys (TODO: use base_alt to put it closer to water)
|
||||||
float mist_min_alt = 0.5;
|
float mist_min_alt = 0.5;
|
||||||
#if (CLOUD_MODE >= CLOUD_MODE_MEDIUM)
|
#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
|
#endif
|
||||||
mist_min_alt = view_distance.z * 1.5 * (1.0 + mist_min_alt * 0.5) + alt * 0.5 + 250;
|
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;
|
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);
|
//vec2 cloud_attr = get_cloud_heights(wind_pos.xy);
|
||||||
float sun_access = 0.0;
|
float sun_access = 0.0;
|
||||||
float moon_access = 0.0;
|
float moon_access = 0.0;
|
||||||
float cloud_sun_access = clamp((pos.z - cloud_alt) / 1500 + 0.5, 0, 1);
|
float cloud_sun_access = clamp((pos.z - cloud_alt) / 1500 + 0.5, 0, 1);
|
||||||
float cloud_moon_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
|
// 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)
|
// Turbulence (small variations in clouds/mist)
|
||||||
const float turb_speed = -1.0; // Turbulence goes the opposite way
|
const float turb_speed = -1.0; // Turbulence goes the opposite way
|
||||||
vec3 turb_offset = vec3(1, 1, 0) * time_of_day.x * turb_speed;
|
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_DENSITY = 10000.0;
|
||||||
const float CLOUD_ALT_VARI_WIDTH = 100000.0;
|
const float CLOUD_ALT_VARI_WIDTH = 100000.0;
|
||||||
const float CLOUD_ALT_VARI_SCALE = 5000.0;
|
const float CLOUD_ALT_VARI_SCALE = 5000.0;
|
||||||
|
|
||||||
cloud_broad_a = cloud_broad(wind_pos + sun_dir.xyz * 250);
|
float small_nz = 0.0
|
||||||
cloud_broad_b = cloud_broad(wind_pos - sun_dir.xyz * 250);
|
#if (CLOUD_MODE >= CLOUD_MODE_MEDIUM)
|
||||||
cloud = cloud_tendency + cloud_tendency * (0.0
|
- (billow_noise_3d((pos + turb_offset * 0.5) / 8000.0) - 0.5)
|
||||||
+ 24 * (cloud_broad_a + cloud_broad_b) * 0.5
|
#else
|
||||||
#if (CLOUD_MODE >= CLOUD_MODE_MINIMAL)
|
- (billow_noise_2d((pos.xy + turb_offset.xy * 0.5) / 8000.0) - 0.5)
|
||||||
+ 4 * (noise_3d((wind_pos + turb_offset) / 2000.0 / cloud_scale) - 0.5)
|
|
||||||
#endif
|
#endif
|
||||||
#if (CLOUD_MODE >= CLOUD_MODE_LOW)
|
#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
|
#endif
|
||||||
#if (CLOUD_MODE >= CLOUD_MODE_HIGH)
|
;
|
||||||
+ 0.75 * (noise_3d(wind_pos / 500.0 / cloud_scale) - 0.5)
|
|
||||||
#endif
|
// Sample twice to allow for self-shadowing
|
||||||
) * 0.1;
|
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));
|
||||||
cloud = pow(max(cloud, 0), 3) * sign(cloud);
|
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));
|
||||||
cloud *= CLOUD_DENSITY * sqrt(cloud_tendency + 0.001) * falloff(abs(pos.z - cloud_alt) / CLOUD_DEPTH);
|
|
||||||
|
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)
|
// 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
|
// 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_sun_access = clamp(
|
||||||
// Cloud density gradient
|
0.7
|
||||||
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)))
|
+ pow(abs(cloud_p1 - cloud_p0), 0.5) * sign(cloud_p1 - cloud_p0) * 0.5
|
||||||
#if (CLOUD_MODE >= CLOUD_MODE_HIGH)
|
+ (pos.z - cloud_alt) / CLOUD_DEPTH * 0.4
|
||||||
// More noise
|
- pow(cloud * 10000000.0, 0.2) * 0.0075
|
||||||
+ 0.01 * (noise_3d(wind_pos / 500) / cloud_scale - 0.5)
|
,
|
||||||
#endif
|
0.15,
|
||||||
) * 15.0 - 1.5) * 1.5, min(cloud_tendency * 10, 1));
|
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
|
// 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 = 1.0 - cloud_sun_access;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (CLOUD_MODE >= CLOUD_MODE_LOW)
|
float mist_sun_access = max(1.0 - cloud_tendency * 8, 0.25);
|
||||||
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_moon_access = mist_sun_access;
|
float mist_moon_access = mist_sun_access;
|
||||||
sun_access = mix(cloud_sun_access, mist_sun_access, clamp(mist * 20000, 0, 1));
|
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));
|
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
|
// `sample` is a reserved keyword
|
||||||
vec4 sample_ = cloud_at(origin + dir * ldist * splay, ldist, emission, not_underground);
|
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));
|
vec2 density_integrals = max(sample_.zw, vec2(0));
|
||||||
|
|
||||||
float sun_access = max(sample_.x, 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 cloud_darken = pow(1.0 / (1.0 + cloud_scatter_factor), step);
|
||||||
float global_darken = pow(1.0 / (1.0 + global_scatter_factor), step);
|
float global_darken = pow(1.0 / (1.0 + global_scatter_factor), step);
|
||||||
// Proportion of light diffusely scattered instead of absorbed
|
// Proportion of light diffusely scattered instead of absorbed
|
||||||
float cloud_diffuse = 0.25;
|
float cloud_diffuse = 0.5;
|
||||||
|
|
||||||
surf_color =
|
surf_color =
|
||||||
// Attenuate light passing through the clouds
|
// Attenuate light passing through the clouds
|
||||||
|
@ -155,7 +155,7 @@ float magnetosphere = sin(time_of_day.x / (3600 * 24));
|
|||||||
#endif
|
#endif
|
||||||
#if (CLOUD_MODE > CLOUD_MODE_NONE)
|
#if (CLOUD_MODE > CLOUD_MODE_NONE)
|
||||||
float emission_strength = clamp((magnetosphere - 0.3) * 1.3, 0, 1) * max(-moon_dir.z, 0);
|
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));
|
float emission_br = abs(pow(fract(time_of_day.x * 0.000005) * 2 - 1, 2));
|
||||||
#else
|
#else
|
||||||
float emission_br = 0.5;
|
float emission_br = 0.5;
|
||||||
|
BIN
assets/voxygen/texture/noise.png
(Stored with Git LFS)
BIN
assets/voxygen/texture/noise.png
(Stored with Git LFS)
Binary file not shown.
Loading…
Reference in New Issue
Block a user