Browse Source

Switch sky pass back to using horizon and zenith colors for interpolation, improve palette loading in weather system

master
C. J. Howard 4 years ago
parent
commit
1f8c73f13c
5 changed files with 107 additions and 189 deletions
  1. +2
    -2
      src/game/bootloader.cpp
  2. +45
    -131
      src/game/systems/weather-system.cpp
  3. +5
    -18
      src/game/systems/weather-system.hpp
  4. +46
    -34
      src/renderer/passes/sky-pass.cpp
  5. +9
    -4
      src/renderer/passes/sky-pass.hpp

+ 2
- 2
src/game/bootloader.cpp View File

@ -1182,7 +1182,7 @@ void setup_controls(game_context* ctx)
( (
[ctx, time_scale]() [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 ctx->control_system->get_fast_forward_control()->set_deactivated_callback
@ -1196,7 +1196,7 @@ void setup_controls(game_context* ctx)
( (
[ctx, time_scale]() [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 ctx->control_system->get_rewind_control()->set_deactivated_callback

+ 45
- 131
src/game/systems/weather-system.cpp View File

@ -175,8 +175,6 @@ weather_system::weather_system(entt::registry& registry):
shadow_map_pass(nullptr), shadow_map_pass(nullptr),
material_pass(nullptr), material_pass(nullptr),
time_scale(1.0f), time_scale(1.0f),
sky_palette(nullptr),
shadow_palette(nullptr),
sun_direction{0.0f, -1.0f, 0.0f}, sun_direction{0.0f, -1.0f, 0.0f},
location{0.0f, 0.0f, 0.0f}, location{0.0f, 0.0f, 0.0f},
jd(0.0) 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); 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); 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<double>(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<float>(sun_azimuth), static_cast<float>(sun_elevation)}; float2 sun_az_el = float2{static_cast<float>(sun_azimuth), static_cast<float>(sun_elevation)};
math::quaternion<float> sun_azimuth_rotation = math::angle_axis(sun_az_el[0], float3{0, 1, 0}); math::quaternion<float> sun_azimuth_rotation = math::angle_axis(sun_az_el[0], float3{0, 1, 0});
math::quaternion<float> sun_elevation_rotation = math::angle_axis(sun_az_el[1], float3{-1, 0, 0}); math::quaternion<float> 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) if (sky_pass)
{ {
//std::cout << "sungrad: " << (sun_gradient_position* static_cast<float>(sky_gradients.size() - 1)) << std::endl;
//std::cout << "sunel: " << math::degrees(sun_elevation) << std::endl;
std::array<float4, 4> sky_gradient;
{
sky_gradient_position *= static_cast<float>(sky_gradients.size() - 1);
int index0 = static_cast<int>(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 sun_color = interpolate_gradient(sun_colors, sun_gradient_position);
float3 moon_color = interpolate_gradient(moon_colors, moon_gradient_position); float3 moon_color = interpolate_gradient(moon_colors, moon_gradient_position);
float3 ambient_color = interpolate_gradient(ambient_colors, ambient_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); moon_light->set_intensity(1.0f);
ambient_light->set_color(ambient_color); 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<float>(hour * 60.0 * 60.0)); sky_pass->set_time_of_day(static_cast<float>(hour * 60.0 * 60.0));
sky_pass->set_observer_location(location[0], location[1], location[2]); sky_pass->set_observer_location(location[0], location[1], location[2]);
sky_pass->set_sun_coordinates(sun_position, sun_az_el); 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) 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); 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) 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<const unsigned char*>(image->get_pixels());
for (unsigned int x = 0; x < w; ++x)
{
std::array<float4, 4> gradient;
for (unsigned int y = 0; y < std::min<unsigned int>(4, h); ++y)
{
unsigned int i = y * w * c + x * c;
float r = srgb_to_linear(static_cast<float>(pixels[i]) / 255.0f);
float g = srgb_to_linear(static_cast<float>(pixels[i + 1]) / 255.0f);
float b = srgb_to_linear(static_cast<float>(pixels[i + 2]) / 255.0f);
gradient[y] = {r, g, b, static_cast<float>(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) 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<const unsigned char*>(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<float>(pixels[i]) / 255.0f);
float g = srgb_to_linear(static_cast<float>(pixels[i + 1]) / 255.0f);
float b = srgb_to_linear(static_cast<float>(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) 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<float3>* 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<unsigned int>(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<const unsigned char*>(image->get_pixels());
const float* pixels = static_cast<const float*>(image->get_pixels());
for (unsigned int x = 0; x < w; ++x) for (unsigned int x = 0; x < w; ++x)
{ {
float3 color;
unsigned int y = 0;
unsigned int i = y * w * c + x * c; unsigned int i = y * w * c + x * c;
float r = srgb_to_linear(static_cast<float>(pixels[i]) / 255.0f);
float g = srgb_to_linear(static_cast<float>(pixels[i + 1]) / 255.0f);
float b = srgb_to_linear(static_cast<float>(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<const unsigned char*>(image->get_pixels()); const unsigned char* pixels = static_cast<const unsigned char*>(image->get_pixels());
for (unsigned int x = 0; x < w; ++x) for (unsigned int x = 0; x < w; ++x)
{ {
float3 color;
unsigned int y = 0;
unsigned int i = y * w * c + x * c; unsigned int i = y * w * c + x * c;
float r = srgb_to_linear(static_cast<float>(pixels[i]) / 255.0f); float r = srgb_to_linear(static_cast<float>(pixels[i]) / 255.0f);
float g = srgb_to_linear(static_cast<float>(pixels[i + 1]) / 255.0f); float g = srgb_to_linear(static_cast<float>(pixels[i + 1]) / 255.0f);
float b = srgb_to_linear(static_cast<float>(pixels[i + 2]) / 255.0f); float b = srgb_to_linear(static_cast<float>(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<float3>& 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<const unsigned char*>(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<float>(pixels[i]) / 255.0f);
shadow_strengths.push_back(r);
}
}
position *= static_cast<float>(gradient.size() - 1);
int index0 = static_cast<int>(position) % gradient.size();
int index1 = (index0 + 1) % gradient.size();
return math::lerp<float3>(gradient[index0], gradient[index1], position - std::floor(position));
} }

+ 5
- 18
src/game/systems/weather-system.hpp View File

@ -63,8 +63,8 @@ public:
void set_shadow_palette(const ::image* image); void set_shadow_palette(const ::image* image);
private: private:
template <typename T>
static T interpolate_gradient(const std::vector<T>& gradient, float position);
static void load_palette(std::vector<float3>* palette, const ::image* image, unsigned int row);
static float3 interpolate_gradient(const std::vector<float3>& gradient, float position);
double jd; double jd;
float3 location; float3 location;
@ -77,25 +77,12 @@ private:
sky_pass* sky_pass; sky_pass* sky_pass;
shadow_map_pass* shadow_map_pass; shadow_map_pass* shadow_map_pass;
material_pass* material_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<float3> sun_colors; std::vector<float3> sun_colors;
std::vector<float3> moon_colors; std::vector<float3> moon_colors;
std::vector<float3> ambient_colors; std::vector<float3> ambient_colors;
std::vector<float> shadow_strengths;
std::vector<std::array<float4, 4>> sky_gradients;
std::vector<float3> shadow_strengths;
std::vector<float3> horizon_colors;
std::vector<float3> zenith_colors;
}; };
template <typename T>
T weather_system::interpolate_gradient(const std::vector<T>& gradient, float position)
{
position *= static_cast<float>(gradient.size() - 1);
int index0 = static_cast<int>(position) % gradient.size();
int index1 = (index0 + 1) % gradient.size();
return math::lerp<T>(gradient[index0], gradient[index1], position - std::floor(position));
}
#endif // ANTKEEPER_WEATHER_SYSTEM_HPP #endif // ANTKEEPER_WEATHER_SYSTEM_HPP

+ 46
- 34
src/renderer/passes/sky-pass.cpp View File

@ -48,44 +48,20 @@ sky_pass::sky_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, r
sky_model(nullptr), sky_model(nullptr),
sky_material(nullptr), sky_material(nullptr),
sky_model_vao(nullptr), sky_model_vao(nullptr),
sky_shader_program(nullptr),
moon_model(nullptr), moon_model(nullptr),
moon_material(nullptr), moon_material(nullptr),
moon_model_vao(nullptr), moon_model_vao(nullptr),
moon_shader_program(nullptr), moon_shader_program(nullptr),
blue_noise_map(nullptr), blue_noise_map(nullptr),
observer_location{0.0f, 0.0f, 0.0f} 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() sky_pass::~sky_pass()
{} {}
void sky_pass::render(render_context* context) const void sky_pass::render(render_context* context) const
{ {
if (!sky_model_vao)
return;
rasterizer->use_framebuffer(*framebuffer); rasterizer->use_framebuffer(*framebuffer);
glDisable(GL_BLEND); 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); float2 sun_az_el = sun_az_el_tween.interpolate(context->alpha);
float3 moon_position = moon_position_tween.interpolate(context->alpha); float3 moon_position = moon_position_tween.interpolate(context->alpha);
float2 moon_az_el = moon_az_el_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 // Draw sky model
{ {
rasterizer->use_program(*shader_program);
rasterizer->use_program(*sky_shader_program);
// Upload shader parameters // Upload shader parameters
if (model_view_projection_input) if (model_view_projection_input)
model_view_projection_input->upload(model_view_projection); 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) if (mouse_input)
mouse_input->upload(mouse_position); mouse_input->upload(mouse_position);
if (resolution_input) 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_start_index = group->get_start_index();
sky_model_index_count = group->get_index_count(); 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 else
{ {
@ -253,11 +258,8 @@ void sky_pass::update_tweens()
moon_position_tween.update(); moon_position_tween.update();
moon_az_el_tween.update(); moon_az_el_tween.update();
time_of_day_tween.update(); time_of_day_tween.update();
}
void sky_pass::set_sky_gradient(const std::array<float4, 4>& gradient)
{
sky_gradient = gradient;
horizon_color_tween.update();
zenith_color_tween.update();
} }
void sky_pass::set_time_of_day(float time) 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); 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) void sky_pass::handle_event(const mouse_moved_event& event)
{ {
mouse_position = {static_cast<float>(event.x), static_cast<float>(event.y)}; mouse_position = {static_cast<float>(event.x), static_cast<float>(event.y)};

+ 9
- 4
src/renderer/passes/sky-pass.hpp View File

@ -50,7 +50,8 @@ public:
void update_tweens(); void update_tweens();
void set_sky_model(const model* model); void set_sky_model(const model* model);
void set_sky_gradient(const std::array<float4, 4>& gradient);
void set_horizon_color(const float3& color);
void set_zenith_color(const float3& color);
void set_time_of_day(float time); void set_time_of_day(float time);
void set_blue_noise_map(const texture_2d* texture); void set_blue_noise_map(const texture_2d* texture);
void set_time_tween(const tween<double>* time); void set_time_tween(const tween<double>* time);
@ -67,9 +68,10 @@ public:
private: private:
virtual void handle_event(const mouse_moved_event& event); 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* 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* mouse_input;
const shader_input* resolution_input; const shader_input* resolution_input;
const shader_input* time_input; const shader_input* time_input;
@ -106,7 +108,7 @@ private:
const texture_2d* blue_noise_map; const texture_2d* blue_noise_map;
float2 mouse_position; float2 mouse_position;
std::array<float4, 4> sky_gradient;
const tween<double>* time_tween; const tween<double>* time_tween;
float3 observer_location; float3 observer_location;
tween<float> time_of_day_tween; tween<float> time_of_day_tween;
@ -116,6 +118,9 @@ private:
tween<float2> sun_az_el_tween; tween<float2> sun_az_el_tween;
tween<float3> moon_position_tween; tween<float3> moon_position_tween;
tween<float2> moon_az_el_tween; tween<float2> moon_az_el_tween;
tween<float3> horizon_color_tween;
tween<float3> zenith_color_tween;
float moon_angular_radius; float moon_angular_radius;
float cos_moon_angular_radius; float cos_moon_angular_radius;
float sun_angular_radius; float sun_angular_radius;

Loading…
Cancel
Save