Improved cloud scale

This commit is contained in:
Joshua Barretto 2024-02-09 21:56:24 +00:00
parent f1ee52b2cc
commit 9f48a855c4
5 changed files with 13 additions and 14 deletions

View File

@ -16,7 +16,7 @@ float billow_noise_2d(vec2 pos) {
}
// Returns vec4(r, g, b, density)
vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground) {
vec4 cloud_at(vec3 pos, float dist, vec3 dir, out vec3 emission, out float not_underground) {
#ifdef EXPERIMENTAL_CURVEDWORLD
pos.z += pow(distance(pos.xy, focus_pos.xy + focus_off.xy) * 0.05, 2);
#endif
@ -30,7 +30,7 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground
// bright, because it has to travel through an infinite amount of atmosphere. This doesn't happen in reality
// because the earth has curvature and so there is an upper bound on the amount of atmosphere that a sunset must
// travel through. We 'simulate' this by fading out the atmosphere density with distance.
float flat_earth_hack = 1.0 / (1.0 + dist * 0.0001);
float flat_earth_hack = max(0.0, 1.0 - dist * 0.00003 * pow(max(0.0, dir.z), 0.2));
float air = 0.025 * clamp((atmosphere_alt - pos.z) / 20000, 0, 1) * flat_earth_hack;
float alt = alt_at(pos.xy - focus_off.xy);
@ -95,8 +95,8 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground
;
// 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_p0 = noise_3d((wind_pos + vec3(0, 0, small_nz) * 150 - sun_dir.xyz * 150) * vec3(0.55, 0.55, 1) / (cloud_scale * 20000.0));
float cloud_p1 = noise_3d((wind_pos + vec3(0, 0, small_nz) * 150 + sun_dir.xyz * 150) * vec3(0.55, 0.55, 1) / (cloud_scale * 20000.0));
float cloud_factor = pow(max(((cloud_p0 + cloud_p1) * 0.5
- 0.5
@ -112,8 +112,8 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground
// Basically, just throw together a few values that roughly approximate this term and come up with an average
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(abs(cloud_p1 - cloud_p0), 0.5) * sign(cloud_p1 - cloud_p0) * 0.75
+ (pos.z - cloud_alt) / CLOUD_DEPTH * 0.2
- pow(cloud * 10000000.0, 0.2) * 0.0075
,
0.15,
@ -182,7 +182,6 @@ vec4 cloud_at(vec3 pos, float dist, out vec3 emission, out float not_underground
#endif
const float STEP_SCALE = DIST_CAP / (10.0 * float(QUALITY));
const float CAST_DIST_CAP = 1000000;
float step_to_dist(float step, float quality) {
return pow(step, 2) * STEP_SCALE / quality;
@ -198,7 +197,7 @@ float dist_to_step(float dist, float quality) {
vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, float max_dist, const float quality) {
// Limit the marching distance to reduce maximum jumps
max_dist = min(max_dist, CAST_DIST_CAP);
max_dist = min(max_dist, DIST_CAP);
origin.xyz += focus_off.xyz;
@ -245,7 +244,7 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, float max_dist, con
float not_underground; // Used to prevent sunlight leaking underground
vec3 pos = origin + dir * ldist * splay;
// `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, dir, emission, not_underground);
// DEBUG
// if (max_dist > ldist && max_dist < ldist * 1.02) {

View File

@ -64,7 +64,7 @@
// An arbitrary value that represents a very far distance (at least as far as the player should be able to see) without
// being too far that we end up with precision issues (used in clouds and elsewhere).
#define DIST_CAP 50000
#define DIST_CAP 500000
/* Constants expected to be defined automatically by configuration: */

View File

@ -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 + sqrt(max(cloud_at(nearest, 0.0, _unused, unused2).z, 0.0)) * 0.01);
float spread = 1.0 / (1.0 + sqrt(max(cloud_at(nearest, 0.0, dir, _unused, unused2).z, 0.0)) * 0.01);
#else
const float spread = 1.0;
#endif

View File

@ -130,7 +130,7 @@ void main() {
voxel_norm = normalize(mix(side_norm, top_norm, max(cam_dir.z, 0.0)));
#else
#ifdef EXPERIMENTAL_PROCEDURALLODDETAIL
float nz_offset = floor((noise_2d(round(f_pos.xy + focus_off.xy) * 0.01) - 0.5) * 3.0 / max(f_norm.z, 0.01));
float nz_offset = floor((noise_2d((floor(f_pos.xy) + focus_off.xy) * 0.01) - 0.5) * 3.0 / max(f_norm.z, 0.01));
#else
const float nz_offset = 0.0;
#endif

View File

@ -119,7 +119,7 @@ impl WeatherSim {
let time_scale = 100_000.0;
let spos = (pos / space_scale).with_z(time / time_scale);
let avg_scale = 20_000.0;
let avg_scale = 30_000.0;
let avg_delay = 250_000.0;
let pressure = ((base_nz
.get((pos / avg_scale).with_z(time / avg_delay).into_array())
@ -135,7 +135,7 @@ impl WeatherSim {
- self.consts[point].humidity * 0.6;
const RAIN_CLOUD_THRESHOLD: f32 = 0.25;
cell.cloud = (1.0 - pressure).max(0.0) * 0.5;
cell.cloud = (1.0 - pressure).max(0.0).powi(2) * 4.0;
cell.rain = ((1.0 - pressure - RAIN_CLOUD_THRESHOLD).max(0.0)
* self.consts[point].humidity
* 2.5)