Browse Source

Switch sky pass from using fullscreen quad to sky dome model

master
C. J. Howard 4 years ago
parent
commit
f7ec9dacc5
10 changed files with 150 additions and 20 deletions
  1. +1
    -1
      src/configuration.hpp.in
  2. +1
    -0
      src/game/biome.hpp
  3. +7
    -1
      src/game/bootloader.cpp
  4. +1
    -0
      src/game/game-context.hpp
  5. +3
    -1
      src/game/states/play-state.cpp
  6. +52
    -2
      src/game/systems/weather-system.cpp
  7. +3
    -0
      src/game/systems/weather-system.hpp
  8. +61
    -13
      src/renderer/passes/sky-pass.cpp
  9. +15
    -2
      src/renderer/passes/sky-pass.hpp
  10. +6
    -0
      src/resources/biome-loader.cpp

+ 1
- 1
src/configuration.hpp.in View File

@ -33,7 +33,7 @@ constexpr math::vector global_right = {1.0f, 0.0f, 0.0f};
#define MATERIAL_PASS_MAX_AMBIENT_LIGHT_COUNT 1
#define MATERIAL_PASS_MAX_POINT_LIGHT_COUNT 1
#define MATERIAL_PASS_MAX_DIRECTIONAL_LIGHT_COUNT 1
#define MATERIAL_PASS_MAX_DIRECTIONAL_LIGHT_COUNT 2
#define MATERIAL_PASS_MAX_SPOTLIGHT_COUNT 1
#define TERRAIN_PATCH_SIZE 200.0f
#define TERRAIN_PATCH_RESOLUTION 4

+ 1
- 0
src/game/biome.hpp View File

@ -46,6 +46,7 @@ struct biome
float wind_direction;
image* sky_palette;
image* sun_palette;
image* moon_palette;
image* ambient_palette;
image* shadow_palette;

+ 7
- 1
src/game/bootloader.cpp View File

@ -491,7 +491,7 @@ void setup_rendering(game_context* ctx)
ctx->overworld_shadow_map_pass = new shadow_map_pass(ctx->rasterizer, ctx->shadow_map_framebuffer, ctx->resource_manager);
ctx->overworld_shadow_map_pass->set_split_scheme_weight(0.75f);
ctx->overworld_clear_pass = new clear_pass(ctx->rasterizer, ctx->framebuffer_hdr);
ctx->overworld_clear_pass->set_cleared_buffers(false, true, true);
ctx->overworld_clear_pass->set_cleared_buffers(true, true, true);
ctx->overworld_sky_pass = new sky_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager);
ctx->app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx->overworld_sky_pass);
ctx->overworld_sky_pass->set_enabled(false);
@ -635,6 +635,10 @@ void setup_scenes(game_context* ctx)
ctx->sun_direct->set_intensity(0.0f);
ctx->sun_direct->update_tweens();
ctx->moon_light = new directional_light();
ctx->moon_light->set_intensity(0.0f);
ctx->moon_light->update_tweens();
ctx->subterrain_light = new point_light();
ctx->subterrain_light->set_color({1, 1, 1});
ctx->subterrain_light->set_intensity(1.0f);
@ -693,6 +697,7 @@ void setup_scenes(game_context* ctx)
ctx->overworld_scene->add_object(ctx->overworld_camera);
ctx->overworld_scene->add_object(ctx->sun_indirect);
ctx->overworld_scene->add_object(ctx->sun_direct);
ctx->overworld_scene->add_object(ctx->moon_light);
//ctx->overworld_scene->add_object(ctx->spotlight);
// Setup underworld scene
@ -861,6 +866,7 @@ void setup_systems(game_context* ctx)
ctx->weather_system = new weather_system(*ctx->ecs_registry);
ctx->weather_system->set_ambient_light(ctx->sun_indirect);
ctx->weather_system->set_sun_light(ctx->sun_direct);
ctx->weather_system->set_moon_light(ctx->moon_light);
ctx->weather_system->set_sky_pass(ctx->overworld_sky_pass);
ctx->weather_system->set_shadow_map_pass(ctx->overworld_shadow_map_pass);
ctx->weather_system->set_material_pass(ctx->overworld_material_pass);

+ 1
- 0
src/game/game-context.hpp View File

@ -180,6 +180,7 @@ struct game_context
camera* ui_camera;
ambient_light* sun_indirect;
directional_light* sun_direct;
directional_light* moon_light;
point_light* subterrain_light;
ambient_light* underworld_ambient_light;
billboard* splash_billboard;

+ 3
- 1
src/game/states/play-state.cpp View File

@ -85,15 +85,17 @@ void play_state_enter(game_context* ctx)
ctx->sun_direct->set_rotation(sun_rotation);
ctx->sun_direct->set_color(ctx->biome->sun_color);
ctx->sun_direct->set_intensity(ctx->biome->sun_intensity);
sky_pass* sky_pass = ctx->overworld_sky_pass;
sky_pass->set_enabled(true);
sky_pass->set_sky_model(ctx->resource_manager->load<model>("sky-dome.mdl"));
sky_pass->set_sun_angular_radius(ctx->biome->sun_angular_radius);
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_moon_palette(ctx->biome->moon_palette);
ctx->weather_system->set_shadow_palette(ctx->biome->shadow_palette);
ctx->weather_system->set_time_of_day(6.0f * 60.0f * 60.0f);

+ 52
- 2
src/game/systems/weather-system.cpp View File

@ -69,6 +69,11 @@ void weather_system::set_sun_light(directional_light* light)
void weather_system::set_moon_light(directional_light* light)
{
moon_light = light;
if (sky_pass)
{
sky_pass->set_moon_light(moon_light);
}
}
void weather_system::set_sky_pass(::sky_pass* pass)
@ -78,6 +83,7 @@ void weather_system::set_sky_pass(::sky_pass* pass)
if (sky_pass)
{
sky_pass->set_sun_light(sun_light);
sky_pass->set_moon_light(moon_light);
}
}
@ -102,8 +108,8 @@ void weather_system::set_material_pass(::material_pass* pass)
}
void weather_system::set_time_of_day(float t)
{
time_of_day = std::fmod(t, seconds_per_day);
{
time_of_day = std::fmod(seconds_per_day + fmod(t, seconds_per_day), seconds_per_day);
//sun_azimuth = 0.0f;
//sun_elevation = (time_of_day / seconds_per_day) * math::two_pi<float> - math::half_pi<float>;
@ -132,6 +138,14 @@ void weather_system::set_time_of_day(float t)
sun_light->set_rotation(sun_rotation);
}
if (moon_light)
{
math::quaternion<float> moon_azimuth_rotation = math::angle_axis(sun_azimuth, float3{0, 1, 0});
math::quaternion<float> moon_elevation_rotation = math::angle_axis(sun_elevation, float3{1, 0, 0});
math::quaternion<float> moon_rotation = math::normalize(moon_azimuth_rotation * moon_elevation_rotation);
moon_light->set_rotation(moon_rotation);
}
if (sky_pass)
{
float hour = time_of_day / (60.0f * 60.0f);
@ -151,11 +165,19 @@ void weather_system::set_time_of_day(float t)
float3 sun_color1 = sun_colors[(hour_index + 1) % sun_colors.size()];
float3 sun_color = math::lerp(sun_color0, sun_color1, t);
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, 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);
moon_light->set_color(moon_color);
moon_light->set_intensity(1.0f);
ambient_light->set_color(ambient_color);
sky_pass->set_sky_gradient(gradient);
@ -231,6 +253,34 @@ void weather_system::set_sun_palette(const ::image* image)
}
}
void weather_system::set_moon_palette(const ::image* image)
{
moon_palette = image;
if (moon_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};
moon_colors.push_back(color);
}
}
}
void weather_system::set_ambient_palette(const ::image* image)
{
ambient_palette = image;

+ 3
- 0
src/game/systems/weather-system.hpp View File

@ -49,6 +49,7 @@ public:
void set_sky_palette(const ::image* image);
void set_sun_palette(const ::image* image);
void set_moon_palette(const ::image* image);
void set_ambient_palette(const ::image* image);
void set_shadow_palette(const ::image* image);
@ -67,9 +68,11 @@ private:
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> moon_colors;
std::vector<float3> ambient_colors;
std::vector<std::array<float4, 4>> sky_gradients;
};

+ 61
- 13
src/renderer/passes/sky-pass.cpp View File

@ -32,6 +32,7 @@
#include "rasterizer/texture-filter.hpp"
#include "renderer/vertex-attributes.hpp"
#include "renderer/render-context.hpp"
#include "renderer/model.hpp"
#include "scene/camera.hpp"
#include "scene/scene.hpp"
#include "scene/ambient-light.hpp"
@ -45,11 +46,15 @@ sky_pass::sky_pass(::rasterizer* rasterizer, const ::framebuffer* framebuffer, r
render_pass(rasterizer, framebuffer),
mouse_position({0.0f, 0.0f}),
sun_light(nullptr),
time_of_day(0.0f)
moon_light(nullptr),
time_of_day(0.0f),
sky_model(nullptr),
sky_model_vao(nullptr)
{
shader_program = resource_manager->load<::shader_program>("sky.glsl");
matrix_input = shader_program->get_input("matrix");
model_view_projection_input = shader_program->get_input("model_view_projection");
sun_direction_input = shader_program->get_input("sun_direction");
moon_direction_input = shader_program->get_input("moon_direction");
sun_angular_radius_input = shader_program->get_input("sun_angular_radius");
sun_angular_radius_input = shader_program->get_input("sun_angular_radius");
sun_color_input = shader_program->get_input("sun_color");
@ -91,38 +96,54 @@ sky_pass::~sky_pass()
void sky_pass::render(render_context* context) const
{
if (!sky_model_vao)
return;
rasterizer->use_framebuffer(*framebuffer);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDisable(GL_CULL_FACE);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
auto viewport = framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport));
float time = (time_tween) ? time_tween->interpolate(context->alpha) : 0.0f;
float2 resolution = {static_cast<float>(std::get<0>(viewport)), static_cast<float>(std::get<1>(viewport))};
float3 sun_direction = {0, -1, 0};
float3 sun_direction = {0, -1, 0};
if (sun_light)
{
sun_direction = sun_light->get_direction_tween().interpolate(context->alpha);
}
// Calculate matrix
float4x4 model_view = math::resize<4, 4>(math::resize<3, 3>(context->camera->get_view_tween().interpolate(context->alpha)));
float4x4 inverse_projection = math::inverse(context->camera->get_projection_tween().interpolate(context->alpha));
float4x4 matrix = math::inverse(model_view) * inverse_projection;
float3 moon_direction = {0, -1, 0};
if (moon_light)
{
moon_direction = moon_light->get_direction_tween().interpolate(context->alpha);
}
const ::camera& camera = *context->camera;
float clip_near = camera.get_clip_near_tween().interpolate(context->alpha);
float clip_far = camera.get_clip_far_tween().interpolate(context->alpha);
float3 model_scale = float3{1.0f, 1.0f, 1.0f} * (clip_near + clip_far) * 0.5f;
float4x4 model = math::scale(math::identity4x4<float>, model_scale);
float4x4 model_view = math::resize<4, 4>(math::resize<3, 3>(camera.get_view_tween().interpolate(context->alpha))) * model;
float4x4 projection = camera.get_projection_tween().interpolate(context->alpha);
float4x4 model_view_projection = projection * model_view;
// Change shader program
rasterizer->use_program(*shader_program);
// Upload shader parameters
if (matrix_input)
matrix_input->upload(matrix);
if (model_view_projection_input)
model_view_projection_input->upload(model_view_projection);
if (sun_direction_input)
sun_direction_input->upload(sun_direction);
if (moon_direction_input)
moon_direction_input->upload(moon_direction);
if (sun_angular_radius_input)
sun_angular_radius_input->upload(sun_angular_radius);
if (sun_color_input)
@ -138,8 +159,30 @@ void sky_pass::render(render_context* context) const
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);
// Draw sky model
rasterizer->draw_arrays(*sky_model_vao, sky_model_drawing_mode, sky_model_start_index, sky_model_index_count);
}
void sky_pass::set_sky_model(const model* model)
{
sky_model = model;
if (sky_model)
{
sky_model_vao = model->get_vertex_array();
const std::vector<model_group*>& groups = *model->get_groups();
for (model_group* group: groups)
{
sky_model_drawing_mode = group->get_drawing_mode();
sky_model_start_index = group->get_start_index();
sky_model_index_count = group->get_index_count();
}
}
else
{
sky_model_vao = nullptr;
}
}
void sky_pass::set_sun_angular_radius(float angle)
@ -157,6 +200,11 @@ void sky_pass::set_sun_light(const directional_light* light)
sun_light = light;
}
void sky_pass::set_moon_light(const directional_light* light)
{
moon_light = light;
}
void sky_pass::set_sky_gradient(const std::array<float4, 4>& gradient)
{
sky_gradient = gradient;

+ 15
- 2
src/renderer/passes/sky-pass.hpp View File

@ -33,6 +33,8 @@ class vertex_array;
class texture_2d;
class resource_manager;
class directional_light;
class model;
enum class drawing_mode;
/**
*
@ -45,21 +47,25 @@ public:
virtual ~sky_pass();
virtual void render(render_context* context) const final;
void set_sky_model(const model* model);
void set_sun_angular_radius(float angle);
void set_sun_color(const float3& color);
void set_sun_light(const directional_light* direction);
void set_sun_light(const directional_light* light);
void set_moon_light(const directional_light* light);
void set_sky_gradient(const std::array<float4, 4>& gradient);
void set_time_of_day(float time);
void set_time_tween(const tween<double>* time);
private:
virtual void handle_event(const mouse_moved_event& event);
shader_program* shader_program;
const shader_input* matrix_input;
const shader_input* model_view_projection_input;
const shader_input* sun_direction_input;
const shader_input* moon_direction_input;
const shader_input* sun_angular_radius_input;
const shader_input* sun_color_input;
const shader_input* sky_gradient_input;
@ -70,10 +76,17 @@ private:
vertex_buffer* quad_vbo;
vertex_array* quad_vao;
const model* sky_model;
const vertex_array* sky_model_vao;
drawing_mode sky_model_drawing_mode;
std::size_t sky_model_start_index;
std::size_t sky_model_index_count;
float sun_angular_radius;
float3 sun_color;
const directional_light* sun_light;
const directional_light* moon_light;
const texture_2d* sky_palette;
float2 mouse_position;
std::array<float4, 4> sky_gradient;

+ 6
- 0
src/resources/biome-loader.cpp View File

@ -113,6 +113,12 @@ biome* resource_loader::load(resource_manager* resource_manager, PHYSFS_F
biome->sun_palette = resource_manager->load<image>(sun_palette_filename);
}
std::string moon_palette_filename;
if (load_value(&moon_palette_filename, weather.value(), "moon_palette"))
{
biome->moon_palette = resource_manager->load<image>(moon_palette_filename);
}
std::string ambient_palette_filename;
if (load_value(&ambient_palette_filename, weather.value(), "ambient_palette"))
{

Loading…
Cancel
Save