From 39c0c578693193403bf55340720f6b4c2d8ab72f Mon Sep 17 00:00:00 2001 From: "C. J. Howard" Date: Fri, 25 Sep 2020 00:38:06 -0700 Subject: [PATCH] Add ambient palette and sun palette --- src/game/biome.hpp | 2 + src/game/states/play-state.cpp | 2 + src/game/systems/weather-system.cpp | 75 +++++++++++++++++++++++++++-- src/game/systems/weather-system.hpp | 6 +++ src/renderer/passes/sky-pass.cpp | 11 ++++- src/renderer/passes/sky-pass.hpp | 3 ++ src/resources/biome-loader.cpp | 12 +++++ 7 files changed, 107 insertions(+), 4 deletions(-) diff --git a/src/game/biome.hpp b/src/game/biome.hpp index d280bb4..0ceb063 100644 --- a/src/game/biome.hpp +++ b/src/game/biome.hpp @@ -45,6 +45,8 @@ struct biome float wind_speed; float wind_direction; image* sky_palette; + image* sun_palette; + image* ambient_palette; image* shadow_palette; // Traits diff --git a/src/game/states/play-state.cpp b/src/game/states/play-state.cpp index 0226c0b..801e16e 100644 --- a/src/game/states/play-state.cpp +++ b/src/game/states/play-state.cpp @@ -92,6 +92,8 @@ void play_state_enter(game_context* ctx) sky_pass->set_sun_color(ctx->biome->sun_color * ctx->biome->sun_intensity); ctx->weather_system->set_sky_palette(ctx->biome->sky_palette); + ctx->weather_system->set_sun_palette(ctx->biome->sun_palette); + ctx->weather_system->set_ambient_palette(ctx->biome->ambient_palette); ctx->weather_system->set_shadow_palette(ctx->biome->shadow_palette); ctx->weather_system->set_time_of_day(6.0f * 60.0f * 60.0f); diff --git a/src/game/systems/weather-system.cpp b/src/game/systems/weather-system.cpp index 69814d6..e580a48 100644 --- a/src/game/systems/weather-system.cpp +++ b/src/game/systems/weather-system.cpp @@ -19,6 +19,7 @@ #include "game/systems/weather-system.hpp" #include "scene/directional-light.hpp" +#include "scene/ambient-light.hpp" #include "renderer/passes/sky-pass.hpp" #include "renderer/passes/shadow-map-pass.hpp" #include "renderer/passes/material-pass.hpp" @@ -134,10 +135,10 @@ void weather_system::set_time_of_day(float t) if (sky_pass) { float hour = time_of_day / (60.0f * 60.0f); - std::size_t gradient_index = static_cast(hour); + std::size_t hour_index = static_cast(hour); - const std::array& gradient0 = sky_gradients[gradient_index]; - const std::array& gradient1 = sky_gradients[(gradient_index + 1) % sky_gradients.size()]; + const std::array& gradient0 = sky_gradients[hour_index]; + const std::array& gradient1 = sky_gradients[(hour_index + 1) % sky_gradients.size()]; float t = hour - std::floor(hour); std::array gradient; @@ -146,7 +147,19 @@ void weather_system::set_time_of_day(float t) gradient[i] = math::lerp(gradient0[i], gradient1[i], t); } + 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, t); + + 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, t); + + sun_light->set_color(sun_color); + ambient_light->set_color(ambient_color); + sky_pass->set_sky_gradient(gradient); + sky_pass->set_time_of_day(time_of_day); } shadow_light = sun_light; @@ -190,6 +203,62 @@ void weather_system::set_sky_palette(const ::image* image) } } +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); + } + } +} + +void weather_system::set_ambient_palette(const ::image* image) +{ + ambient_palette = image; + if (ambient_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}; + + ambient_colors.push_back(color); + } + } +} + void weather_system::set_shadow_palette(const ::image* image) { shadow_palette = image; diff --git a/src/game/systems/weather-system.hpp b/src/game/systems/weather-system.hpp index 718dcb3..644fb3a 100644 --- a/src/game/systems/weather-system.hpp +++ b/src/game/systems/weather-system.hpp @@ -48,6 +48,8 @@ public: void set_time_scale(float scale); void set_sky_palette(const ::image* image); + void set_sun_palette(const ::image* image); + void set_ambient_palette(const ::image* image); void set_shadow_palette(const ::image* image); private: @@ -64,7 +66,11 @@ private: shadow_map_pass* shadow_map_pass; material_pass* material_pass; const image* sky_palette; + const image* sun_palette; + const image* ambient_palette; const image* shadow_palette; + std::vector sun_colors; + std::vector ambient_colors; std::vector> sky_gradients; }; diff --git a/src/renderer/passes/sky-pass.cpp b/src/renderer/passes/sky-pass.cpp index 860057e..04e8857 100644 --- a/src/renderer/passes/sky-pass.cpp +++ b/src/renderer/passes/sky-pass.cpp @@ -44,7 +44,8 @@ sky_pass::sky_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, resource_manager* resource_manager): render_pass(rasterizer, framebuffer), mouse_position({0.0f, 0.0f}), - sun_light(nullptr) + sun_light(nullptr), + time_of_day(0.0f) { shader_program = resource_manager->load<::shader_program>("sky.glsl"); matrix_input = shader_program->get_input("matrix"); @@ -56,6 +57,7 @@ sky_pass::sky_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, r 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"); const float vertex_data[] = { @@ -133,6 +135,8 @@ void sky_pass::render(render_context* context) const resolution_input->upload(resolution); if (time_input) time_input->upload(time); + if (time_of_day_input) + time_of_day_input->upload(time_of_day); // Draw quad rasterizer->draw_arrays(*quad_vao, drawing_mode::triangles, 0, 6); @@ -158,6 +162,11 @@ void sky_pass::set_sky_gradient(const std::array& gradient) sky_gradient = gradient; } +void sky_pass::set_time_of_day(float time) +{ + time_of_day = time; +} + void sky_pass::set_time_tween(const tween* time) { this->time_tween = time; diff --git a/src/renderer/passes/sky-pass.hpp b/src/renderer/passes/sky-pass.hpp index 6586dd4..0296565 100644 --- a/src/renderer/passes/sky-pass.hpp +++ b/src/renderer/passes/sky-pass.hpp @@ -49,6 +49,7 @@ public: void set_sun_color(const float3& color); void set_sun_light(const directional_light* direction); void set_sky_gradient(const std::array& gradient); + void set_time_of_day(float time); void set_time_tween(const tween* time); @@ -65,6 +66,7 @@ private: const shader_input* mouse_input; const shader_input* resolution_input; const shader_input* time_input; + const shader_input* time_of_day_input; vertex_buffer* quad_vbo; vertex_array* quad_vao; @@ -76,6 +78,7 @@ private: float2 mouse_position; std::array sky_gradient; const tween* time_tween; + float time_of_day; }; #endif // ANTKEEPER_SKY_PASS_HPP diff --git a/src/resources/biome-loader.cpp b/src/resources/biome-loader.cpp index f869898..0ff8cad 100644 --- a/src/resources/biome-loader.cpp +++ b/src/resources/biome-loader.cpp @@ -107,6 +107,18 @@ biome* resource_loader::load(resource_manager* resource_manager, PHYSFS_F biome->sky_palette = resource_manager->load(sky_palette_filename); } + std::string sun_palette_filename; + if (load_value(&sun_palette_filename, weather.value(), "sun_palette")) + { + biome->sun_palette = resource_manager->load(sun_palette_filename); + } + + std::string ambient_palette_filename; + if (load_value(&ambient_palette_filename, weather.value(), "ambient_palette")) + { + biome->ambient_palette = resource_manager->load(ambient_palette_filename); + } + std::string shadow_palette_filename; if (load_value(&shadow_palette_filename, weather.value(), "shadow_palette")) {