From 23f153c38dcb90834b16566dc81c8c609f7dd5ba Mon Sep 17 00:00:00 2001 From: lisyarus Date: Mon, 15 Dec 2025 13:19:23 +0300 Subject: [PATCH] Weather simulation experiments wip --- examples/heightmap_seed_0.png | Bin 0 -> 7837 bytes examples/heightmap_seed_1.png | Bin 0 -> 7595 bytes examples/heightmap_seed_2.png | Bin 0 -> 7371 bytes examples/heightmap_seed_3.png | Bin 0 -> 7506 bytes examples/weather.cpp | 78 +++++++++++++++++++++++----------- 5 files changed, 54 insertions(+), 24 deletions(-) create mode 100644 examples/heightmap_seed_0.png create mode 100644 examples/heightmap_seed_1.png create mode 100644 examples/heightmap_seed_2.png create mode 100644 examples/heightmap_seed_3.png diff --git a/examples/heightmap_seed_0.png b/examples/heightmap_seed_0.png new file mode 100644 index 0000000000000000000000000000000000000000..0b246c8182336dd9318fcb28ac35954a5df5c4b8 GIT binary patch literal 7837 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 literal 0 HcmV?d00001 diff --git a/examples/heightmap_seed_1.png b/examples/heightmap_seed_1.png new file mode 100644 index 0000000000000000000000000000000000000000..5275a52b8a2581772fec4206fbf9f729a6e88784 GIT binary patch literal 7595 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 literal 0 HcmV?d00001 diff --git a/examples/heightmap_seed_2.png b/examples/heightmap_seed_2.png new file mode 100644 index 0000000000000000000000000000000000000000..34a0206d991cecb4d7045d3884099652f1ce3479 GIT binary patch literal 7371 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 literal 0 HcmV?d00001 diff --git a/examples/heightmap_seed_3.png b/examples/heightmap_seed_3.png new file mode 100644 index 0000000000000000000000000000000000000000..7f591c9e3e9dd269aef295899aa786fa38d73841 GIT binary patch literal 7506 zcmeHKc{tST+y5G4jSPj6r7>Exj9G1S>?Vw;WNEX_@*T!D!;CdCC{!pa5lK1JK_%ok zSt3P+h!#t`tR+hJ;{A>~ozDCIuIs(db-nL@=R4Ok&;7lh`~E!l^Lg&)o_P-M*k&y& zy-FGY09mRHWhc}NgiR9q0tTE-l%cL2+)ZUssT%>I60#J510s+lfSSlpGE77i5QTK{ zP*Z?pp^dPu5)oVKlOS33yL=LowZGfIAQ>+L17x8-8)^hdUJ3PuP-7>2o2wR*g^%RY z#|Dyw$ba_MRQnw$f({<1Lo|T=aRgm5o@NK!1`#!jQ- z4{K64)W&cw$aR_{A|-Z-c`d4{tF^p2)UX(6Ft|8Y(_VT4hv}U^&T@V|7x%D#=)QY+ zp5&JA}CoefL&gbWXpvj^(h$sYBroG1u3J3^)hu-ZB<4wED>E z+aV`esWa5-75S;OvUeBnZT|9+^!xDb?mK@B7gcZ#2Uf~u;fV!noIdAglC2Hi+qy}^ zK5UT6m%0|gYjt{-XlwX~T4Fr8_zDy*0%;oOzKRvSTcPK%^*iO6oyY21B z4357Jjme>dI${1?A)A1aX&9Hr@CErOI_Sj?Fh-A6-9)3Sgu-!Fhi4l_nC;gTU)sK%mEOD23@WAtullPx(x zAc~|z(!pW2gt0>iXcK9aQ4o_w-bu0g4gtLxqrLfjE*Xmr4Gq-^CF*d3ys&sfLqjZ% zfF%$xkOhVp9>AxCVFGwsLWpk|6p+UVVsrUyP5?@XNuzUu`Nn88G>-Z+K7X#g{SWv6 z-gg!tKCodlE*7tY!}|MUfA-+^OClYs^OK!3=T2hEEA+myoN@WVq$ffw7KyW|Ct{WnWKoAno2e~V2xvb3C^ z1A*Ls;Qr0}&$TZZLss_oWD187EDVoIF-8mLCo?$=Hj}(05{U#BQ5O$lSPVl$42h(# zk1;UNr(+Ba=mrc>kEn+y(tm=Y2JrZ_00t<8g1~jy5RNWGpGGHvEDXtzp^qWy>5?#p zpsoSNP}dN|;h1zLi=q1y#P%RIl$A8UpQ92&F(D{JkVRk_=;ASSf`KlEM8|;`8jeK5 z5OwwR^@vO&NsmEWf?_hrR-7Pz8nm5kf0`GFbd2Oaq|A)9!8JzYILJkC(pK$k!y=>28n0tWG*OcY`+6}F`j;kJ;W z#X!W;gn0@9Ea{=OkS&8i8lMy7#NqfEqkojdAH(+0abnW=GzyImLZCm2q|={8aube7 z#(fK42xre>vRUE(o3-%ppo}1UXv=NbJZS##CDpeR

6Td;9k4$6h*0DAdxSAk!G% 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, 2> & result, float scale) { - auto noise_1 = make_perlin(rng, 3, 6, 2.f); - auto noise_2 = make_perlin(rng, 3, 6, 2.f); + auto noise_1 = make_perlin(rng, 4, 6, 2.f); + auto noise_2 = make_perlin(rng, 4, 6, 2.f); for (int y = 0; y < result.height(); ++y) { @@ -61,31 +61,34 @@ struct weather_app { static constexpr int N = 128; + const bool static_mode = true; + const float dt = 20.f; - const float viscosity = 0.f; + const float viscosity = static_mode ? 0.005f : 0.f; const float advection_magnification = 1.f; const float temperature_diffusion = 0.001f; - const float cooling = 0.1f / 300.f; + const float cooling = 0.01f / 300.f; const float cooling_factor = std::exp(- cooling * dt); const float heating = 323.f * (std::exp(cooling * dt) - 1.f) / dt; const float coriolis = 0.f; const float coriolis_bands = 2.f; const float friction = 0.f; - const float slope_force = 4.f; + const float slope_force = 0.05f; const float vorticity_confinement = 0.f; - const float evaporation = 0.01f; + const float elevation_temperature_drop = 30.f; + const float evaporation = 1.0f; const float max_humidity_factor = 100.f; - const float precipitation_factor = 0.0003f; + const float precipitation_factor = 0.0001f; const float force_field_amplitude = 0.00005f; - const float random_forces = 1.f; + const float random_forces = 0.25f * (static_mode ? 0.f : 1.f); const float force_field_switch_duration = 720.f * 7.5f; // 7.5 days const int force_field_switch_frames = std::round(force_field_switch_duration / dt); // const float friction_factor = 1.f - std::exp(- friction * dt); const bool periodic_x = true; - random::generator rng{random::device{}}; - // random::generator rng{0, 0}; + // random::generator rng{random::device{}}; + random::generator rng{0, 0}; gfx::pixmap_rgba biomes_map; @@ -146,9 +149,6 @@ struct weather_app float latitude = (N * 0.5f - y) * 2.f / N; velocity_(x, y) = random_velocity(rng) * 0.f + 0.f * math::vector{-std::cos(0.5f * float(math::pi) * latitude * coriolis_bands), 0.f}; temperature_(x, y) = expected_temperature_at(y); - - float max_humidity = std::max(0.f, temperature_(x, y) - 223.f) * max_humidity_factor; - humidity_(x, y) = max_humidity + dt * evaporation * std::max(0.f, temperature_(x, y) - 273.f) * (1.f - precipitation_factor * dt) / precipitation_factor / dt; } } @@ -167,6 +167,28 @@ struct weather_app } } + auto heightmap = gfx::read_image(io::file_istream{std::filesystem::path{PSEMEK_EXAMPLES_DIR} / "heightmap_seed_3.png"}); + + for (int y = 0; y < N; ++y) + { + for (int x = 0; x < N; ++x) + { + terrain_(x, y) = ((heightmap(x, y) / 255.f) * 2048.f - 512.f) / 1024.f; + } + } + + for (int y = 0; y < N; ++y) + { + for (int x = 0; x < N; ++x) + { + if (terrain_(x, y) > 0.f) + continue; + + float max_humidity = std::max(0.f, temperature_(x, y) - 223.f) * max_humidity_factor; + humidity_(x, y) = max_humidity + dt * evaporation * std::max(0.f, temperature_(x, y) - 273.f) * (1.f - precipitation_factor * dt) / precipitation_factor / dt; + } + } + make_force_field(rng, force_field_main_, 0.5f); make_force_field(rng, force_field_next_, 0.5f); @@ -249,7 +271,7 @@ struct weather_app float max_humidity = std::max(0.f, temperature_(x, y) - 223.f) * max_humidity_factor; float discharge = std::max(0.f, humidity_(x, y) - max_humidity) * precipitation_factor * dt; humidity_(x, y) -= discharge; - precipitation_(x, y) = discharge; + precipitation_(x, y) = discharge / dt; } } @@ -373,8 +395,8 @@ struct weather_app // velocity_(x, y) *= std::min(1.f, slope_factor); // velocity_(x, y) -= terrain_gradient * slope_force * dt; - [[maybe_unused]] float slope_factor = std::exp(- dt * slope_force * std::pow(math::length(terrain_gradient), 4.f)); - // [[maybe_unused]] float slope_factor = std::exp(- dt * slope_force * std::pow(std::max(0.f, terrain_(x, y)), 1.f)); + // [[maybe_unused]] float slope_factor = std::exp(- dt * slope_force * std::pow(math::length(terrain_gradient), 4.f)); + [[maybe_unused]] float slope_factor = std::exp(- dt * slope_force * std::pow(std::max(0.f, terrain_(x, y)), 1.f)); velocity_(x, y) *= slope_factor; // Directional external force @@ -465,7 +487,7 @@ struct weather_app { if (!periodic_x) { - float left_boundary_flow = 0.f;//0.01f * std::sin((i * 1.f / N) * float(math::pi) * 4.f); + float left_boundary_flow = 0.01f;//0.01f * std::sin((i * 1.f / N) * float(math::pi) * 4.f); float right_boundary_flow = -left_boundary_flow; velocity_(1, i)[0] = left_boundary_flow; @@ -476,6 +498,9 @@ struct weather_app } velocity_(i, 0)[1] = -velocity_(i, 1)[1]; velocity_(i, N-2)[1] = -velocity_(i, N-2)[1]; + + velocity_(i, 1)[0] = 0.01f; + velocity_(i, N-2)[0] = 0.01f; } // Uncomment to visualize the force field @@ -505,8 +530,13 @@ struct weather_app { for (int x = 0; x < N; ++x) { - float t = 1.f / frame_; + // float t = 1.f / frame_; // float t = 1.f / std::min(8192, frame_); + float t = 1.f / std::min(86400.f / dt, frame_); // year average + + if (static_mode) + t = 1.f; + average_temperature_(x, y) = math::lerp(average_temperature_(x, y), temperature_(x, y), t); average_precipitation_(x, y) = math::lerp(average_precipitation_(x, y), precipitation_(x, y), t); } @@ -610,7 +640,7 @@ struct weather_app auto map_biome = [this](float temperature, float precipitation) { auto x = math::clamp(math::unlerp({ -3.f, 3.f}, precipitation) * biomes_map.width() , {0, biomes_map.width() - 1}); - auto y = math::clamp(math::unlerp({-10.f, 40.f}, temperature ) * biomes_map.height(), {0, biomes_map.height() - 1}); + auto y = math::clamp(math::unlerp({-10.f, 30.f}, temperature ) * biomes_map.height(), {0, biomes_map.height() - 1}); return gfx::to_colorf(biomes_map(x, y)); }; @@ -633,10 +663,10 @@ struct weather_app else { if (terrain_(x, y) <= 0.f) - color = map_color(4.f * terrain_(x, y), {0.f, 0.f, 0.125f, 1.f}, {0.f, 1.f, 1.5f, 1.f}); + color = map_color(8.f * terrain_(x, y), {0.f, 0.f, 0.125f, 1.f}, {0.f, 1.f, 1.5f, 1.f}); else { - float temperature = average_temperature_(x, y) - 273.f - std::max(0.f, terrain_(x, y)) * 6.5f; + float temperature = average_temperature_(x, y) - 273.f - std::max(0.f, terrain_(x, y)) * elevation_temperature_drop; // float precipitation = (std::log10(std::max(1e-9f, average_precipitation_(x, y))) + 3.f) * 2.f; // float precipitation = std::pow(average_precipitation_(x, y) * 125.f, 2.f) * 8.f; float precipitation = std::log2(std::max(1e-9f, average_precipitation_(x, y))); @@ -652,7 +682,7 @@ struct weather_app (terrain_(x, y + 1) - terrain_(x, y - 1)) / 2.f, }; - auto terrain_normal = math::normalized(math::vector{-terrain_gradient[0], -terrain_gradient[1], 0.5f}); + auto terrain_normal = math::normalized(math::vector{-terrain_gradient[0], -terrain_gradient[1], 0.125f}); float lightness = 0.5f + 0.5f * math::dot(terrain_normal, math::normalized(math::vector{1.f, 2.f, 3.f})); @@ -673,13 +703,13 @@ struct weather_app color = gfx::blend(color, map_color(10000.f * pressure_(x, y), {0.f, 0.f, 1.f, 0.75f}, {1.f, 0.f, 0.f, 0.75f})); if (show_water_vapor_) - color = gfx::blend(color, map_color(humidity_(x, y) * 0.001f, {0.f, 1.f, 1.f, -0.75f}, {0.f, 1.f, 1.f, 0.75f})); + color = gfx::blend(color, map_color(humidity_(x, y) * 0.00001f, {0.f, 1.f, 1.f, -0.75f}, {0.f, 1.f, 1.f, 0.75f})); if (show_precipitation_) { // color = gfx::blend(color, map_color(precipitation_(x, y), {1.f, 1.f, 1.f, -1.f}, {1.f, 1.f, 1.f, 1.f})); - float alpha = 2.f / (1.f + std::exp(- precipitation_(x, y))) - 1.f; + float alpha = 2.f / (1.f + std::exp(- 0.1f * precipitation_(x, y))) - 1.f; gfx::color_4f cloud_color{1.f, 1.f, 1.f, alpha * 0.875f};