Browse Source

Add configurable exposure to camera class

master
C. J. Howard 4 months ago
parent
commit
cdde99b948
11 changed files with 109 additions and 13 deletions
  1. +4
    -7
      src/ecs/systems/astronomy-system.cpp
  2. +7
    -0
      src/ecs/systems/camera-system.hpp
  3. +20
    -0
      src/ecs/systems/control-system.cpp
  4. +14
    -0
      src/ecs/systems/control-system.hpp
  5. +5
    -2
      src/game/bootloader.cpp
  6. +2
    -1
      src/game/states/play-state.cpp
  7. +1
    -1
      src/renderer/passes/material-pass.cpp
  8. +18
    -0
      src/renderer/passes/sky-pass.cpp
  9. +6
    -0
      src/renderer/passes/sky-pass.hpp
  10. +8
    -1
      src/scene/camera.cpp
  11. +24
    -1
      src/scene/camera.hpp

+ 4
- 7
src/ecs/systems/astronomy-system.cpp View File

@ -87,15 +87,12 @@ void astronomy_system::update(double t, double dt)
//sun_light->look_at({0, 0, 0}, {0, -1, 0}, {0, 0, 1});
// Set sun color
float factor = std::cos(spherical.y);
factor = 1.0f - factor * factor;
float correlated_temperature = math::lerp(3000.0f, 8000.0f, factor);
float correlated_temperature = 3000.0f + std::sin(spherical.y) * 5000.0f;
float3 correlated_color = math::type_cast<float>(astro::blackbody(correlated_temperature));
float intensity = math::lerp(100.0f, 1000.0f, factor);
sun_light->set_color(correlated_color);
// Set sun intensity (in lux)
float intensity = std::max(0.0, std::sin(spherical.y) * 108000.0f);
sun_light->set_intensity(intensity);

+ 7
- 0
src/ecs/systems/camera-system.hpp View File

@ -55,6 +55,8 @@ public:
const orbit_cam* get_orbit_cam() const;
orbit_cam* get_orbit_cam();
scene::camera* get_camera();
private:
virtual void handle_event(const mouse_moved_event& event);
@ -77,6 +79,11 @@ inline orbit_cam* camera_system::get_orbit_cam()
return &orbit_cam;
}
inline scene::camera* camera_system::get_camera()
{
return camera;
}
} // namespace ecs
#endif // ANTKEEPER_ECS_CAMERA_SYSTEM_HPP

+ 20
- 0
src/ecs/systems/control-system.cpp View File

@ -26,6 +26,7 @@
#include "ecs/commands.hpp"
#include "ecs/systems/camera-system.hpp"
#include "animation/orbit-cam.hpp"
#include <iostream>
namespace ecs {
@ -63,6 +64,8 @@ control_system::control_system(ecs::registry& registry):
control_set.add_control(&use_tool_control);
control_set.add_control(&fast_forward_control);
control_set.add_control(&rewind_control);
control_set.add_control(&exposure_increase_control);
control_set.add_control(&exposure_decrease_control);
// Set deadzone at 15% for all controls
const std::list<input::control*>* controls = control_set.get_controls();
@ -111,6 +114,23 @@ void control_system::update(double t, double dt)
if (rotate_cw_control.is_active())
camera_system->pan(-rotation_speed * dt * std::min<float>(1.0f, rotate_cw_control.get_current_value()));
// Exposure
if (camera_system->get_camera())
{
const float exposure = camera_system->get_camera()->get_exposure();
const float exposure_rate = 0.1f;
if (exposure_increase_control.is_active())
{
camera_system->get_camera()->set_exposure(exposure + exposure_rate);
std::cout << "exposure: " << (exposure + exposure_rate) << std::endl;
}
if (exposure_decrease_control.is_active())
{
camera_system->get_camera()->set_exposure(exposure - exposure_rate);
std::cout << "exposure: " << (exposure - exposure_rate) << std::endl;
}
}
// Move camera
float3 movement{0.0f, 0.0f, 0.0f};
if (move_right_control.is_active())

+ 14
- 0
src/ecs/systems/control-system.hpp View File

@ -86,6 +86,8 @@ public:
input::control* get_use_tool_control();
input::control* get_fast_forward_control();
input::control* get_rewind_control();
input::control* get_exposure_increase_control();
input::control* get_exposure_decrease_control();
private:
virtual void handle_event(const mouse_moved_event& event);
@ -118,6 +120,8 @@ private:
input::control use_tool_control;
input::control fast_forward_control;
input::control rewind_control;
input::control exposure_increase_control;
input::control exposure_decrease_control;
float zoom_speed;
float min_elevation;
@ -287,6 +291,16 @@ inline input::control* control_system::get_rewind_control()
return &rewind_control;
}
inline input::control* control_system::get_exposure_increase_control()
{
return &exposure_increase_control;
}
inline input::control* control_system::get_exposure_decrease_control()
{
return &exposure_decrease_control;
}
} // namespace ecs
#endif // ANTKEEPER_ECS_CONTROL_SYSTEM_HPP

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

@ -1059,6 +1059,9 @@ void setup_controls(game_context* ctx)
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_fast_forward_control(), nullptr, input::scancode::dot));
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_rewind_control(), nullptr, input::scancode::comma));
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_exposure_increase_control(), nullptr, input::scancode::right_brace));
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_exposure_decrease_control(), nullptr, input::scancode::left_brace));
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_equip_brush_control(), nullptr, input::scancode::one));
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_equip_twig_control(), nullptr, input::scancode::two));
@ -1067,8 +1070,8 @@ void setup_controls(game_context* ctx)
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_equip_lens_control(), nullptr, input::scancode::five));
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_equip_marker_control(), nullptr, input::scancode::six));
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_next_marker_control(), nullptr, input::scancode::right_brace));
ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_previous_marker_control(), nullptr, input::scancode::left_brace));
//ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_next_marker_control(), nullptr, input::scancode::right_brace));
//ctx->input_event_router->add_mapping(input::key_mapping(ctx->control_system->get_previous_marker_control(), nullptr, input::scancode::left_brace));
ctx->input_event_router->add_mapping(input::mouse_button_mapping(ctx->control_system->get_use_tool_control(), nullptr, 1));
ctx->control_system->get_use_tool_control()->set_activated_callback

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

@ -95,7 +95,7 @@ void play_state_enter(game_context* ctx)
sky_pass->set_sky_model(ctx->resource_manager->load<model>("sky-dome.mdl"));
sky_pass->set_moon_model(ctx->resource_manager->load<model>("moon.mdl"));
sky_pass->set_horizon_color({0.1f, 0.1f, 0.1f});
sky_pass->set_horizon_color({1.1f, 1.1f, 1.1f});
sky_pass->set_zenith_color({0.0f, 0.0f, 0.0f});
sky_pass->set_time_of_day(0.0f);
sky_pass->set_julian_day(0.0f);
@ -105,6 +105,7 @@ void play_state_enter(game_context* ctx)
sky_pass->set_sun_coordinates({0, 1, 0}, {0, 3.1415f / 2.0f});
sky_pass->set_moon_coordinates({1, 0, 0}, {0, 0});
sky_pass->set_moon_rotation(math::identity_quaternion<float>);
sky_pass->set_sky_gradient(resource_manager->load<gl::texture_2d>("sky-gradient.tex"), resource_manager->load<gl::texture_2d>("sky-gradient2.tex"));

+ 1
- 1
src/renderer/passes/material-pass.cpp View File

@ -136,7 +136,7 @@ void material_pass::render(render_context* context) const
clip_depth[1] = context->camera->get_clip_far_tween().interpolate(context->alpha);
float log_depth_coef = 2.0f / std::log2(clip_depth[1] + 1.0f);
float camera_exposure = std::exp2(-7.0f);
float camera_exposure = std::exp2(context->camera->get_exposure_tween().interpolate(context->alpha));
int active_material_flags = 0;

+ 18
- 0
src/renderer/passes/sky-pass.cpp View File

@ -52,6 +52,8 @@ sky_pass::sky_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffe
moon_model_vao(nullptr),
moon_shader_program(nullptr),
blue_noise_map(nullptr),
sky_gradient(nullptr),
sky_gradient2(nullptr),
observer_location{0.0f, 0.0f, 0.0f},
time_tween(nullptr),
time_of_day_tween(0.0, math::lerp<float, float>),
@ -92,6 +94,7 @@ void sky_pass::render(render_context* context) const
float4x4 model_view = view * model;
float4x4 projection = camera.get_projection_tween().interpolate(context->alpha);
float4x4 model_view_projection = projection * model_view;
float exposure = std::exp2(camera.get_exposure_tween().interpolate(context->alpha));
float time_of_day = time_of_day_tween.interpolate(context->alpha);
float julian_day = julian_day_tween.interpolate(context->alpha);
@ -123,6 +126,10 @@ void sky_pass::render(render_context* context) const
time_of_day_input->upload(time_of_day);
if (blue_noise_map_input)
blue_noise_map_input->upload(blue_noise_map);
if (sky_gradient_input && sky_gradient)
sky_gradient_input->upload(sky_gradient);
if (sky_gradient2_input && sky_gradient2)
sky_gradient2_input->upload(sky_gradient2);
if (observer_location_input)
observer_location_input->upload(observer_location);
if (sun_position_input)
@ -139,6 +146,8 @@ void sky_pass::render(render_context* context) const
cos_moon_angular_radius_input->upload(cos_moon_angular_radius);
if (cos_sun_angular_radius_input)
cos_sun_angular_radius_input->upload(cos_sun_angular_radius);
if (exposure_input)
exposure_input->upload(exposure);
sky_material->upload(context->alpha);
@ -209,6 +218,8 @@ void sky_pass::set_sky_model(const model* model)
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");
sky_gradient_input = sky_shader_program->get_input("sky_gradient");
sky_gradient2_input = sky_shader_program->get_input("sky_gradient2");
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");
@ -217,6 +228,7 @@ void sky_pass::set_sky_model(const model* model)
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");
exposure_input = sky_shader_program->get_input("camera.exposure");
}
}
}
@ -289,6 +301,12 @@ void sky_pass::set_blue_noise_map(const gl::texture_2d* texture)
blue_noise_map = texture;
}
void sky_pass::set_sky_gradient(const gl::texture_2d* texture, const gl::texture_2d* texture2)
{
sky_gradient = texture;
sky_gradient2 = texture2;
}
void sky_pass::set_julian_day(float jd)
{
julian_day_tween[1] = jd;

+ 6
- 0
src/renderer/passes/sky-pass.hpp View File

@ -55,6 +55,7 @@ public:
void set_zenith_color(const float3& color);
void set_time_of_day(float time);
void set_blue_noise_map(const gl::texture_2d* texture);
void set_sky_gradient(const gl::texture_2d* texture, const gl::texture_2d* texture2);
void set_time_tween(const tween<double>* time);
void set_moon_model(const model* model);
@ -87,6 +88,9 @@ private:
const gl::shader_input* julian_day_input;
const gl::shader_input* cos_sun_angular_radius_input;
const gl::shader_input* cos_moon_angular_radius_input;
const gl::shader_input* sky_gradient_input;
const gl::shader_input* sky_gradient2_input;
const gl::shader_input* exposure_input;
gl::shader_program* moon_shader_program;
const gl::shader_input* moon_model_view_projection_input;
@ -109,6 +113,8 @@ private:
std::size_t moon_model_index_count;
const gl::texture_2d* blue_noise_map;
const gl::texture_2d* sky_gradient;
const gl::texture_2d* sky_gradient2;
float2 mouse_position;
float3 observer_location;

+ 8
- 1
src/scene/camera.cpp View File

@ -74,7 +74,8 @@ camera::camera():
aspect_ratio(1.0f, math::lerp<float, float>),
view(math::identity4x4<float>, std::bind(&interpolate_view, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
projection(math::identity4x4<float>, std::bind(&interpolate_projection, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
view_projection(math::identity4x4<float>, std::bind(&interpolate_view_projection, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3))
view_projection(math::identity4x4<float>, std::bind(&interpolate_view_projection, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)),
exposure(0.0f, math::lerp<float, float>)
{}
float3 camera::project(const float3& object, const float4& viewport) const
@ -143,6 +144,11 @@ void camera::set_orthographic(float clip_left, float clip_right, float clip_bott
view_frustum.set_matrix(view_projection[1]);
}
void camera::set_exposure(float exposure)
{
this->exposure[1] = exposure;
}
void camera::set_compositor(::compositor* compositor)
{
this->compositor = compositor;
@ -167,6 +173,7 @@ void camera::update_tweens()
view.update();
projection.update();
view_projection.update();
exposure.update();
}
void camera::transformed()

+ 24
- 1
src/scene/camera.hpp View File

@ -78,9 +78,17 @@ public:
*/
void set_orthographic(float clip_left, float clip_right, float clip_bottom, float clip_top, float clip_near, float clip_far);
/**
* Sets the camera's exposure.
*
* @param exposure Exposure factor.
*/
void set_exposure(float exposure);
void set_compositor(compositor* compositor);
void set_composite_index(int index);
virtual const bounding_volume_type& get_bounds() const;
float is_orthographic() const;
@ -104,6 +112,9 @@ public:
/// Returns the camera's view frustum.
const view_frustum_type& get_view_frustum() const;
/// Returns the camera's exposure.
float get_exposure() const;
const compositor* get_compositor() const;
compositor* get_compositor();
@ -120,6 +131,7 @@ public:
const tween<float4x4>& get_view_tween() const;
const tween<float4x4>& get_projection_tween() const;
const tween<float4x4>& get_view_projection_tween() const;
const tween<float>& get_exposure_tween() const;
/// @copydoc object_base::update_tweens();
virtual void update_tweens();
@ -141,6 +153,7 @@ private:
tween<float4x4> view;
tween<float4x4> projection;
tween<float4x4> view_projection;
tween<float> exposure;
view_frustum_type view_frustum;
};
@ -214,6 +227,12 @@ inline const typename camera::view_frustum_type& camera::get_view_frustum() cons
return view_frustum;
}
inline float camera::get_exposure() const
{
return exposure[1];
}
inline const compositor* camera::get_compositor() const
{
return compositor;
@ -284,7 +303,11 @@ inline const tween& camera::get_view_projection_tween() const
return view_projection;
}
inline const tween<float>& camera::get_exposure_tween() const
{
return exposure;
}
} // namespace scene
#endif // ANTKEEPER_SCENE_CAMERA_HPP

Loading…
Cancel
Save