From 1f8c73f13c5f856d5521e901276aa0a9c14105d6 Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Mon, 5 Oct 2020 21:18:59 -0700 Subject: [PATCH] Switch sky pass back to using horizon and zenith colors for interpolation, improve palette loading in weather system --- src/game/bootloader.cpp | 4 +- src/game/systems/weather-system.cpp | 176 +++++++--------------------- src/game/systems/weather-system.hpp | 23 +--- src/renderer/passes/sky-pass.cpp | 80 +++++++------ src/renderer/passes/sky-pass.hpp | 13 +- 5 files changed, 107 insertions(+), 189 deletions(-) diff --git a/src/game/bootloader.cpp b/src/game/bootloader.cpp index 65c46f1..a0a0894 100644 --- a/src/game/bootloader.cpp +++ b/src/game/bootloader.cpp @@ -1182,7 +1182,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 @@ -1196,7 +1196,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 6945e72..935c44b 100644 --- a/src/game/systems/weather-system.cpp +++ b/src/game/systems/weather-system.cpp @@ -175,8 +175,6 @@ weather_system::weather_system(entt::registry& registry): shadow_map_pass(nullptr), material_pass(nullptr), time_scale(1.0f), - sky_palette(nullptr), - shadow_palette(nullptr), sun_direction{0.0f, -1.0f, 0.0f}, location{0.0f, 0.0f, 0.0f}, jd(0.0) @@ -252,18 +250,6 @@ void weather_system::update(double t, double dt) ecliptic_to_equatorial(moon_longitude, moon_latitude, ecl, &moon_right_ascension, &moon_declination); equatorial_to_horizontal(moon_right_ascension, moon_declination, lmst, latitude, &moon_azimuth, &moon_elevation); - /* - std::cout.precision(10); - std::cout << std::fixed; - //std::cout << "gmst: " << math::degrees(gmst) << std::endl; - std::cout << "JD: " << jd << std::endl; - std::cout << "PST: " << pst_time << std::endl; - std::cout << "AZ: " << math::degrees(sun_azimuth) << std::endl; - std::cout << "EL: " << math::degrees(sun_elevation) << std::endl; - std::cout << "DEC: " << math::degrees(sun_declination) << std::endl; - //std::cout << "eOT: " << eot << std::endl; - */ - float2 sun_az_el = float2{static_cast(sun_azimuth), static_cast(sun_elevation)}; math::quaternion sun_azimuth_rotation = math::angle_axis(sun_az_el[0], float3{0, 1, 0}); math::quaternion sun_elevation_rotation = math::angle_axis(sun_az_el[1], float3{-1, 0, 0}); @@ -297,21 +283,8 @@ void weather_system::update(double t, double dt) if (sky_pass) { - - - //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; - { - 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 horizon_color = interpolate_gradient(horizon_colors, sun_gradient_position); + float3 zenith_color = interpolate_gradient(zenith_colors, sun_gradient_position); 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); @@ -321,7 +294,8 @@ void weather_system::update(double t, double dt) moon_light->set_intensity(1.0f); ambient_light->set_color(ambient_color); - sky_pass->set_sky_gradient(sky_gradient); + sky_pass->set_horizon_color(horizon_color); + sky_pass->set_zenith_color(zenith_color); sky_pass->set_time_of_day(static_cast(hour * 60.0 * 60.0)); sky_pass->set_observer_location(location[0], location[1], location[2]); sky_pass->set_sun_coordinates(sun_position, sun_az_el); @@ -344,7 +318,7 @@ void weather_system::update(double t, double dt) if (material_pass) { - float shadow_strength = interpolate_gradient(shadow_strengths, sun_gradient_position); + float shadow_strength = interpolate_gradient(shadow_strengths, sun_gradient_position).x; material_pass->set_shadow_strength(shadow_strength); } } @@ -413,135 +387,75 @@ void weather_system::set_time_scale(float scale) void weather_system::set_sky_palette(const ::image* image) { - sky_palette = image; - if (sky_palette) - { - unsigned int w = image->get_width(); - unsigned int h = image->get_height(); - unsigned int c = image->get_channels(); - const unsigned char* pixels = static_cast(image->get_pixels()); - - for (unsigned int x = 0; x < w; ++x) - { - std::array gradient; - - for (unsigned int y = 0; y < std::min(4, h); ++y) - { - unsigned int i = y * w * c + x * c; - float r = srgb_to_linear(static_cast(pixels[i]) / 255.0f); - float g = srgb_to_linear(static_cast(pixels[i + 1]) / 255.0f); - float b = srgb_to_linear(static_cast(pixels[i + 2]) / 255.0f); - - gradient[y] = {r, g, b, static_cast(y) * (1.0f / 3.0f)}; - } - - sky_gradients.push_back(gradient); - } - } + load_palette(&horizon_colors, image, 0); + load_palette(&zenith_colors, image, 1); } void weather_system::set_sun_palette(const ::image* image) { - sun_palette = image; - if (sun_palette) - { - unsigned int w = image->get_width(); - unsigned int h = image->get_height(); - unsigned int c = image->get_channels(); - const unsigned char* pixels = static_cast(image->get_pixels()); - - for (unsigned int x = 0; x < w; ++x) - { - float3 color; - - unsigned int y = 0; - - unsigned int i = y * w * c + x * c; - float r = srgb_to_linear(static_cast(pixels[i]) / 255.0f); - float g = srgb_to_linear(static_cast(pixels[i + 1]) / 255.0f); - float b = srgb_to_linear(static_cast(pixels[i + 2]) / 255.0f); - - color = {r, g, b}; - - sun_colors.push_back(color); - } - } + load_palette(&sun_colors, image, 0); } void weather_system::set_moon_palette(const ::image* image) { - moon_palette = image; - if (moon_palette) + load_palette(&moon_colors, image, 0); +} + +void weather_system::set_ambient_palette(const ::image* image) +{ + load_palette(&ambient_colors, image, 0); +} + +void weather_system::set_shadow_palette(const ::image* image) +{ + load_palette(&shadow_strengths, image, 0); +} + +void weather_system::load_palette(std::vector* palette, const ::image* image, unsigned int row) +{ + unsigned int w = image->get_width(); + unsigned int h = image->get_height(); + unsigned int c = image->get_channels(); + unsigned int y = std::min(row, h - 1); + + palette->clear(); + + if (image->is_hdr()) { - unsigned int w = image->get_width(); - unsigned int h = image->get_height(); - unsigned int c = image->get_channels(); - const unsigned char* pixels = static_cast(image->get_pixels()); + const float* pixels = static_cast(image->get_pixels()); for (unsigned int x = 0; x < w; ++x) { - float3 color; - - unsigned int y = 0; - unsigned int i = y * w * c + x * c; - float r = srgb_to_linear(static_cast(pixels[i]) / 255.0f); - float g = srgb_to_linear(static_cast(pixels[i + 1]) / 255.0f); - float b = srgb_to_linear(static_cast(pixels[i + 2]) / 255.0f); - - color = {r, g, b}; - moon_colors.push_back(color); + float r = pixels[i]; + float g = pixels[i + 1]; + float b = pixels[i + 2]; + + palette->push_back(float3{r, g, b}); } } -} - -void weather_system::set_ambient_palette(const ::image* image) -{ - ambient_palette = image; - if (ambient_palette) + else { - unsigned int w = image->get_width(); - unsigned int h = image->get_height(); - unsigned int c = image->get_channels(); const unsigned char* pixels = static_cast(image->get_pixels()); for (unsigned int x = 0; x < w; ++x) { - float3 color; - - unsigned int y = 0; - unsigned int i = y * w * c + x * c; + float r = srgb_to_linear(static_cast(pixels[i]) / 255.0f); float g = srgb_to_linear(static_cast(pixels[i + 1]) / 255.0f); float b = srgb_to_linear(static_cast(pixels[i + 2]) / 255.0f); - - color = {r, g, b}; - ambient_colors.push_back(color); + palette->push_back(float3{r, g, b}); } } } -void weather_system::set_shadow_palette(const ::image* image) +float3 weather_system::interpolate_gradient(const std::vector& gradient, float position) { - shadow_palette = image; - if (shadow_palette) - { - unsigned int w = image->get_width(); - unsigned int h = image->get_height(); - unsigned int c = image->get_channels(); - const unsigned char* pixels = static_cast(image->get_pixels()); - - for (unsigned int x = 0; x < w; ++x) - { - unsigned int y = 0; - - unsigned int i = y * w * c + x * c; - float r = 1.0f - (static_cast(pixels[i]) / 255.0f); - - shadow_strengths.push_back(r); - } - } + 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)); } diff --git a/src/game/systems/weather-system.hpp b/src/game/systems/weather-system.hpp index 39698e3..dd54cd9 100644 --- a/src/game/systems/weather-system.hpp +++ b/src/game/systems/weather-system.hpp @@ -63,8 +63,8 @@ public: void set_shadow_palette(const ::image* image); private: - template - static T interpolate_gradient(const std::vector& gradient, float position); + static void load_palette(std::vector* palette, const ::image* image, unsigned int row); + static float3 interpolate_gradient(const std::vector& gradient, float position); double jd; float3 location; @@ -77,25 +77,12 @@ private: sky_pass* sky_pass; shadow_map_pass* shadow_map_pass; material_pass* material_pass; - const image* sky_palette; - const image* sun_palette; - const image* moon_palette; - const image* ambient_palette; - const image* shadow_palette; std::vector sun_colors; std::vector moon_colors; std::vector ambient_colors; - std::vector shadow_strengths; - std::vector> sky_gradients; + std::vector shadow_strengths; + std::vector horizon_colors; + std::vector zenith_colors; }; -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 diff --git a/src/renderer/passes/sky-pass.cpp b/src/renderer/passes/sky-pass.cpp index bdc353f..16a3b6a 100644 --- a/src/renderer/passes/sky-pass.cpp +++ b/src/renderer/passes/sky-pass.cpp @@ -48,44 +48,20 @@ sky_pass::sky_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, r sky_model(nullptr), sky_material(nullptr), sky_model_vao(nullptr), + sky_shader_program(nullptr), moon_model(nullptr), moon_material(nullptr), moon_model_vao(nullptr), moon_shader_program(nullptr), blue_noise_map(nullptr), observer_location{0.0f, 0.0f, 0.0f} -{ - shader_program = resource_manager->load<::shader_program>("sky.glsl"); - model_view_projection_input = shader_program->get_input("model_view_projection"); - sky_gradient_input = shader_program->get_input("sky_gradient"); - mouse_input = shader_program->get_input("mouse"); - resolution_input = shader_program->get_input("resolution"); - time_input = shader_program->get_input("time"); - time_of_day_input = shader_program->get_input("time_of_day"); - blue_noise_map_input = shader_program->get_input("blue_noise_map"); - observer_location_input = shader_program->get_input("observer_location"); - sun_position_input = shader_program->get_input("sun_position"); - sun_az_el_input = shader_program->get_input("sun_az_el"); - moon_position_input = shader_program->get_input("moon_position"); - moon_az_el_input = shader_program->get_input("moon_az_el"); - julian_day_input = shader_program->get_input("julian_day"); - cos_moon_angular_radius_input = shader_program->get_input("cos_moon_angular_radius"); - cos_sun_angular_radius_input = shader_program->get_input("cos_sun_angular_radius"); - - sky_gradient[0] = {1.0, 0.0f, 0.0f, 0.0f}; - sky_gradient[1] = {0.0, 1.0f, 0.0f, 0.333f}; - sky_gradient[2] = {0.0, 0.0f, 1.0f, 0.667f}; - sky_gradient[3] = {1.0, 1.0f, 0.0f, 1.0f}; -} +{} sky_pass::~sky_pass() {} void sky_pass::render(render_context* context) const { - if (!sky_model_vao) - return; - rasterizer->use_framebuffer(*framebuffer); glDisable(GL_BLEND); @@ -116,16 +92,20 @@ void sky_pass::render(render_context* context) const float2 sun_az_el = sun_az_el_tween.interpolate(context->alpha); float3 moon_position = moon_position_tween.interpolate(context->alpha); float2 moon_az_el = moon_az_el_tween.interpolate(context->alpha); + float3 horizon_color = horizon_color_tween.interpolate(context->alpha); + float3 zenith_color = zenith_color_tween.interpolate(context->alpha); // Draw sky model { - rasterizer->use_program(*shader_program); + rasterizer->use_program(*sky_shader_program); // Upload shader parameters if (model_view_projection_input) model_view_projection_input->upload(model_view_projection); - if (sky_gradient_input) - sky_gradient_input->upload(0, &sky_gradient[0], 4); + if (horizon_color_input) + horizon_color_input->upload(horizon_color); + if (zenith_color_input) + zenith_color_input->upload(zenith_color); if (mouse_input) mouse_input->upload(mouse_position); if (resolution_input) @@ -202,6 +182,31 @@ void sky_pass::set_sky_model(const model* model) sky_model_start_index = group->get_start_index(); sky_model_index_count = group->get_index_count(); } + + if (sky_material) + { + sky_shader_program = sky_material->get_shader_program(); + + if (sky_shader_program) + { + model_view_projection_input = sky_shader_program->get_input("model_view_projection"); + horizon_color_input = sky_shader_program->get_input("horizon_color"); + zenith_color_input = sky_shader_program->get_input("zenith_color"); + mouse_input = sky_shader_program->get_input("mouse"); + resolution_input = sky_shader_program->get_input("resolution"); + time_input = sky_shader_program->get_input("time"); + time_of_day_input = sky_shader_program->get_input("time_of_day"); + blue_noise_map_input = sky_shader_program->get_input("blue_noise_map"); + observer_location_input = sky_shader_program->get_input("observer_location"); + sun_position_input = sky_shader_program->get_input("sun_position"); + sun_az_el_input = sky_shader_program->get_input("sun_az_el"); + moon_position_input = sky_shader_program->get_input("moon_position"); + moon_az_el_input = sky_shader_program->get_input("moon_az_el"); + julian_day_input = sky_shader_program->get_input("julian_day"); + cos_moon_angular_radius_input = sky_shader_program->get_input("cos_moon_angular_radius"); + cos_sun_angular_radius_input = sky_shader_program->get_input("cos_sun_angular_radius"); + } + } } else { @@ -253,11 +258,8 @@ void sky_pass::update_tweens() moon_position_tween.update(); moon_az_el_tween.update(); time_of_day_tween.update(); -} - -void sky_pass::set_sky_gradient(const std::array& gradient) -{ - sky_gradient = gradient; + horizon_color_tween.update(); + zenith_color_tween.update(); } void sky_pass::set_time_of_day(float time) @@ -309,6 +311,16 @@ void sky_pass::set_sun_angular_radius(float radius) cos_sun_angular_radius = std::cos(sun_angular_radius); } +void sky_pass::set_horizon_color(const float3& color) +{ + horizon_color_tween[1] = color; +} + +void sky_pass::set_zenith_color(const float3& color) +{ + zenith_color_tween[1] = color; +} + void sky_pass::handle_event(const mouse_moved_event& event) { mouse_position = {static_cast(event.x), static_cast(event.y)}; diff --git a/src/renderer/passes/sky-pass.hpp b/src/renderer/passes/sky-pass.hpp index 8b7aac8..fdab240 100644 --- a/src/renderer/passes/sky-pass.hpp +++ b/src/renderer/passes/sky-pass.hpp @@ -50,7 +50,8 @@ public: void update_tweens(); void set_sky_model(const model* model); - void set_sky_gradient(const std::array& gradient); + void set_horizon_color(const float3& color); + void set_zenith_color(const float3& color); void set_time_of_day(float time); void set_blue_noise_map(const texture_2d* texture); void set_time_tween(const tween* time); @@ -67,9 +68,10 @@ public: private: virtual void handle_event(const mouse_moved_event& event); - shader_program* shader_program; + shader_program* sky_shader_program; const shader_input* model_view_projection_input; - const shader_input* sky_gradient_input; + const shader_input* horizon_color_input; + const shader_input* zenith_color_input; const shader_input* mouse_input; const shader_input* resolution_input; const shader_input* time_input; @@ -106,7 +108,7 @@ private: const texture_2d* blue_noise_map; float2 mouse_position; - std::array sky_gradient; + const tween* time_tween; float3 observer_location; tween time_of_day_tween; @@ -116,6 +118,9 @@ private: tween sun_az_el_tween; tween moon_position_tween; tween moon_az_el_tween; + tween horizon_color_tween; + tween zenith_color_tween; + float moon_angular_radius; float cos_moon_angular_radius; float sun_angular_radius;