From 065f1804718b5ff5cca9f3956b257f73cbe1b64a Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Tue, 29 Sep 2020 01:10:32 -0700 Subject: [PATCH] Make weather system interpolate gradients based on elevation angles rather than time of day --- src/game/bootloader.cpp | 4 +-- src/game/systems/weather-system.cpp | 49 ++++++++++++++--------------- src/game/systems/weather-system.hpp | 14 +++++++-- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index bdaf865..b4ec105 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -1179,7 +1179,7 @@ void setup_controls(game_context* ctx) ( [ctx, time_scale]() { - ctx->weather_system->set_time_scale(time_scale * 500.0f); + ctx->weather_system->set_time_scale(time_scale * 50.0f); } ); ctx->control_system->get_fast_forward_control()->set_deactivated_callback @@ -1193,7 +1193,7 @@ void setup_controls(game_context* ctx) ( [ctx, time_scale]() { - ctx->weather_system->set_time_scale(time_scale * -500.0f); + ctx->weather_system->set_time_scale(time_scale * -50.0f); } ); ctx->control_system->get_rewind_control()->set_deactivated_callback diff --git a/src/game/systems/weather-system.cpp b/src/game/systems/weather-system.cpp index 33d33a5..36be504 100644 --- a/src/game/systems/weather-system.cpp +++ b/src/game/systems/weather-system.cpp @@ -150,8 +150,8 @@ void equatorial_to_horizontal(double right_ascension, double declination, double double horiz_y = y; double horiz_z = x * std::sin(math::half_pi - latitude) + z * std::cos(math::half_pi - latitude); - *azimuth = std::atan2(horiz_y, horiz_x) + math::pi; - *elevation = std::atan2(horiz_z, std::sqrt(horiz_x * horiz_x + horiz_y * horiz_y)); + *azimuth = math::wrap_radians(std::atan2(horiz_y, horiz_x) + math::pi); + *elevation = math::wrap_radians(std::atan2(horiz_z, std::sqrt(horiz_x * horiz_x + horiz_y * horiz_y))); } /** @@ -289,37 +289,39 @@ void weather_system::update(double t, double dt) std::size_t hour_index = static_cast(hour); float lerp_factor = hour - std::floor(hour); + + float sun_gradient_position = static_cast(std::max(0.0, ((sun_elevation + math::half_pi) / math::pi))); + float moon_gradient_position = static_cast(std::max(0.0, ((moon_elevation + math::half_pi) / math::pi))); + float sky_gradient_position = sun_gradient_position; + float ambient_gradient_position = sun_gradient_position; + if (sky_pass) { - const std::array& gradient0 = sky_gradients[hour_index]; - const std::array& gradient1 = sky_gradients[(hour_index + 1) % sky_gradients.size()]; + - std::array gradient; - for (int i = 0; i < 4; ++i) + //std::cout << "sungrad: " << (sun_gradient_position* static_cast(sky_gradients.size() - 1)) << std::endl; + //std::cout << "sunel: " << math::degrees(sun_elevation) << std::endl; + + std::array sky_gradient; { - gradient[i] = math::lerp(gradient0[i], gradient1[i], lerp_factor); + sky_gradient_position *= static_cast(sky_gradients.size() - 1); + int index0 = static_cast(sky_gradient_position) % sky_gradients.size(); + int index1 = (index0 + 1) % sky_gradients.size(); + sky_gradient_position -= std::floor(sky_gradient_position); + for (int i = 0; i < 4; ++i) + sky_gradient[i] = math::lerp(sky_gradients[index0][i], sky_gradients[index1][i], sky_gradient_position); } - float3 sun_color0 = sun_colors[hour_index]; - float3 sun_color1 = sun_colors[(hour_index + 1) % sun_colors.size()]; - float3 sun_color = math::lerp(sun_color0, sun_color1, lerp_factor); - - float3 moon_color0 = moon_colors[hour_index]; - float3 moon_color1 = moon_colors[(hour_index + 1) % moon_colors.size()]; - float3 moon_color = math::lerp(moon_color0, moon_color1, lerp_factor); - - float3 ambient_color0 = ambient_colors[hour_index]; - float3 ambient_color1 = ambient_colors[(hour_index + 1) % sun_colors.size()]; - float3 ambient_color = math::lerp(ambient_color0, ambient_color1, lerp_factor); + float3 sun_color = interpolate_gradient(sun_colors, sun_gradient_position); + float3 moon_color = interpolate_gradient(moon_colors, moon_gradient_position); + float3 ambient_color = interpolate_gradient(ambient_colors, ambient_gradient_position); sun_light->set_color(sun_color); - moon_light->set_color(moon_color); moon_light->set_intensity(1.0f); - ambient_light->set_color(ambient_color); - sky_pass->set_sky_gradient(gradient); + sky_pass->set_sky_gradient(sky_gradient); sky_pass->set_time_of_day(static_cast(hour * 60.0 * 60.0)); sky_pass->set_observer_coordinates(coordinates); sky_pass->set_sun_coordinates(sun_position, sun_az_el); @@ -342,10 +344,7 @@ void weather_system::update(double t, double dt) if (material_pass) { - float shadow_strength0 = shadow_strengths[hour_index]; - float shadow_strength1 = shadow_strengths[(hour_index + 1) % shadow_strengths.size()]; - float shadow_strength = math::lerp(shadow_strength0, shadow_strength1, lerp_factor); - + float shadow_strength = interpolate_gradient(shadow_strengths, sun_gradient_position); material_pass->set_shadow_strength(shadow_strength); } } diff --git a/src/game/systems/weather-system.hpp b/src/game/systems/weather-system.hpp index ef9fd3f..134f40d 100644 --- a/src/game/systems/weather-system.hpp +++ b/src/game/systems/weather-system.hpp @@ -57,10 +57,11 @@ public: void set_shadow_palette(const ::image* image); private: + template + static T interpolate_gradient(const std::vector& gradient, float position); + double jd; - float2 coordinates; - float time_scale; float3 sun_direction; ambient_light* ambient_light; @@ -82,4 +83,13 @@ private: std::vector> sky_gradients; }; +template +T weather_system::interpolate_gradient(const std::vector& gradient, float position) +{ + position *= static_cast(gradient.size() - 1); + int index0 = static_cast(position) % gradient.size(); + int index1 = (index0 + 1) % gradient.size(); + return math::lerp(gradient[index0], gradient[index1], position - std::floor(position)); +} + #endif // ANTKEEPER_WEATHER_SYSTEM_HPP