Browse Source

Add infinite ground render pass. Move camera exposure normaliztion factor into render context

master
C. J. Howard 2 years ago
parent
commit
77c418b7a8
12 changed files with 327 additions and 46 deletions
  1. +1
    -0
      CMakeLists.txt
  2. +1
    -1
      src/config.hpp.in
  3. +4
    -1
      src/game/context.hpp
  4. +11
    -5
      src/game/state/boot.cpp
  5. +32
    -17
      src/game/state/nuptial-flight.cpp
  6. +3
    -6
      src/game/world.cpp
  7. +3
    -0
      src/render/context.hpp
  8. +189
    -0
      src/render/passes/ground-pass.cpp
  9. +69
    -0
      src/render/passes/ground-pass.hpp
  10. +5
    -9
      src/render/passes/material-pass.cpp
  11. +7
    -6
      src/render/passes/sky-pass.cpp
  12. +2
    -1
      src/render/renderer.cpp

+ 1
- 0
CMakeLists.txt View File

@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.7)
option(VERSION_STRING "Project version string" "0.0.0") option(VERSION_STRING "Project version string" "0.0.0")
project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX) project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX)
# Find dependency packages # Find dependency packages

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

@ -56,7 +56,7 @@ constexpr float4 menu_inactive_color{1.0f, 1.0f, 1.0f, 0.5f};
constexpr float title_fade_in_duration = 1.0f; constexpr float title_fade_in_duration = 1.0f;
/// Duration of the fade out when quitting the game or returning to the main menu, in seconds. /// Duration of the fade out when quitting the game or returning to the main menu, in seconds.
constexpr float quit_fade_out_duration = 1.0f;
constexpr float quit_fade_out_duration = 0.5f;
/// Duration of the fade out when a new colony is started, in seconds. /// Duration of the fade out when a new colony is started, in seconds.
constexpr float new_colony_fade_out_duration = 1.0f; constexpr float new_colony_fade_out_duration = 1.0f;

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

@ -112,6 +112,7 @@ namespace render
class shadow_map_pass; class shadow_map_pass;
class simple_render_pass; class simple_render_pass;
class sky_pass; class sky_pass;
class ground_pass;
} }
namespace game { namespace game {
@ -208,10 +209,12 @@ struct context
render::clear_pass* surface_shadow_map_clear_pass; render::clear_pass* surface_shadow_map_clear_pass;
render::shadow_map_pass* surface_shadow_map_pass; render::shadow_map_pass* surface_shadow_map_pass;
render::clear_pass* surface_clear_pass; render::clear_pass* surface_clear_pass;
render::sky_pass* surface_sky_pass;
render::sky_pass* sky_pass;
render::material_pass* surface_material_pass; render::material_pass* surface_material_pass;
render::outline_pass* surface_outline_pass; render::outline_pass* surface_outline_pass;
render::compositor* surface_compositor; render::compositor* surface_compositor;
render::ground_pass* ground_pass;
// Scene utilities // Scene utilities
scene::collection* active_scene; scene::collection* active_scene;

+ 11
- 5
src/game/state/boot.cpp View File

@ -47,6 +47,7 @@
#include "render/passes/outline-pass.hpp" #include "render/passes/outline-pass.hpp"
#include "render/passes/shadow-map-pass.hpp" #include "render/passes/shadow-map-pass.hpp"
#include "render/passes/sky-pass.hpp" #include "render/passes/sky-pass.hpp"
#include "render/passes/ground-pass.hpp"
#include "render/passes/simple-pass.hpp" #include "render/passes/simple-pass.hpp"
#include "render/vertex-attribute.hpp" #include "render/vertex-attribute.hpp"
#include "render/compositor.hpp" #include "render/compositor.hpp"
@ -500,8 +501,12 @@ void boot::setup_rendering()
ctx.surface_clear_pass->set_cleared_buffers(true, true, true); ctx.surface_clear_pass->set_cleared_buffers(true, true, true);
ctx.surface_clear_pass->set_clear_depth(0.0f); ctx.surface_clear_pass->set_clear_depth(0.0f);
ctx.surface_sky_pass = new render::sky_pass(ctx.rasterizer, ctx.hdr_framebuffer, ctx.resource_manager);
ctx.app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx.surface_sky_pass);
ctx.sky_pass = new render::sky_pass(ctx.rasterizer, ctx.hdr_framebuffer, ctx.resource_manager);
ctx.sky_pass->set_enabled(false);
ctx.app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx.sky_pass);
ctx.ground_pass = new render::ground_pass(ctx.rasterizer, ctx.hdr_framebuffer, ctx.resource_manager);
ctx.ground_pass->set_enabled(false);
ctx.surface_material_pass = new render::material_pass(ctx.rasterizer, ctx.hdr_framebuffer, ctx.resource_manager); ctx.surface_material_pass = new render::material_pass(ctx.rasterizer, ctx.hdr_framebuffer, ctx.resource_manager);
ctx.surface_material_pass->set_fallback_material(ctx.fallback_material); ctx.surface_material_pass->set_fallback_material(ctx.fallback_material);
@ -517,7 +522,8 @@ void boot::setup_rendering()
ctx.surface_compositor->add_pass(ctx.surface_shadow_map_clear_pass); ctx.surface_compositor->add_pass(ctx.surface_shadow_map_clear_pass);
ctx.surface_compositor->add_pass(ctx.surface_shadow_map_pass); ctx.surface_compositor->add_pass(ctx.surface_shadow_map_pass);
ctx.surface_compositor->add_pass(ctx.surface_clear_pass); ctx.surface_compositor->add_pass(ctx.surface_clear_pass);
ctx.surface_compositor->add_pass(ctx.surface_sky_pass);
ctx.surface_compositor->add_pass(ctx.sky_pass);
ctx.surface_compositor->add_pass(ctx.ground_pass);
ctx.surface_compositor->add_pass(ctx.surface_material_pass); ctx.surface_compositor->add_pass(ctx.surface_material_pass);
//ctx.surface_compositor->add_pass(ctx.surface_outline_pass); //ctx.surface_compositor->add_pass(ctx.surface_outline_pass);
ctx.surface_compositor->add_pass(ctx.common_bloom_pass); ctx.surface_compositor->add_pass(ctx.common_bloom_pass);
@ -913,7 +919,7 @@ void boot::setup_systems()
// Setup astronomy system // Setup astronomy system
ctx.astronomy_system = new entity::system::astronomy(*ctx.entity_registry); ctx.astronomy_system = new entity::system::astronomy(*ctx.entity_registry);
ctx.astronomy_system->set_sky_pass(ctx.surface_sky_pass);
ctx.astronomy_system->set_sky_pass(ctx.sky_pass);
// Setup proteome system // Setup proteome system
ctx.proteome_system = new entity::system::proteome(*ctx.entity_registry); ctx.proteome_system = new entity::system::proteome(*ctx.entity_registry);
@ -1100,7 +1106,7 @@ void boot::setup_loop()
[&ctx = this->ctx](double t, double dt) [&ctx = this->ctx](double t, double dt)
{ {
// Update tweens // Update tweens
ctx.surface_sky_pass->update_tweens();
ctx.sky_pass->update_tweens();
ctx.surface_scene->update_tweens(); ctx.surface_scene->update_tweens();
ctx.underground_scene->update_tweens(); ctx.underground_scene->update_tweens();
ctx.ui_scene->update_tweens(); ctx.ui_scene->update_tweens();

+ 32
- 17
src/game/state/nuptial-flight.cpp View File

@ -20,9 +20,8 @@
#include "game/state/nuptial-flight.hpp" #include "game/state/nuptial-flight.hpp"
#include "game/state/pause-menu.hpp" #include "game/state/pause-menu.hpp"
#include "entity/archetype.hpp" #include "entity/archetype.hpp"
#include "entity/systems/astronomy.hpp"
#include "entity/systems/orbit.hpp"
#include "entity/systems/camera.hpp" #include "entity/systems/camera.hpp"
#include "entity/systems/astronomy.hpp"
#include "entity/components/observer.hpp" #include "entity/components/observer.hpp"
#include "entity/components/transform.hpp" #include "entity/components/transform.hpp"
#include "entity/components/terrain.hpp" #include "entity/components/terrain.hpp"
@ -37,8 +36,7 @@
#include "game/world.hpp" #include "game/world.hpp"
#include "application.hpp" #include "application.hpp"
#include "render/passes/clear-pass.hpp" #include "render/passes/clear-pass.hpp"
#include <memory>
#include <iostream>
#include "render/passes/ground-pass.hpp"
#include "state-machine.hpp" #include "state-machine.hpp"
#include "config.hpp" #include "config.hpp"
@ -53,6 +51,16 @@ nuptial_flight::nuptial_flight(game::context& ctx):
// Disable UI color clear // Disable UI color clear
ctx.ui_clear_pass->set_cleared_buffers(false, true, false); ctx.ui_clear_pass->set_cleared_buffers(false, true, false);
// Setup and enable sky pass
ctx.sky_pass->set_sky_model(ctx.resource_manager->load<render::model>("celestial-hemisphere.mdl"));
ctx.sky_pass->set_enabled(true);
// Setup and enable ground pass
render::model* terrestrial_hemisphere_model = ctx.resource_manager->load<render::model>("terrestrial-hemisphere.mdl");
(*terrestrial_hemisphere_model->get_groups())[0]->set_material(ctx.resource_manager->load<render::material>("scrub-terrestrial-hemisphere.mtl"));
ctx.ground_pass->set_ground_model(terrestrial_hemisphere_model);
ctx.ground_pass->set_enabled(true);
// Create world // Create world
game::world::create_stars(ctx); game::world::create_stars(ctx);
game::world::create_sun(ctx); game::world::create_sun(ctx);
@ -65,10 +73,6 @@ nuptial_flight::nuptial_flight(game::context& ctx):
// Freeze time // Freeze time
game::world::set_time_scale(ctx, 0.0); game::world::set_time_scale(ctx, 0.0);
// Switch to surface camera
ctx.underground_camera->set_active(false);
ctx.surface_camera->set_active(true);
// Find planet EID by name // Find planet EID by name
entity::id planet_eid = ctx.entities["planet"]; entity::id planet_eid = ctx.entities["planet"];
@ -77,9 +81,10 @@ nuptial_flight::nuptial_flight(game::context& ctx):
// ctx.entity_registry->remove<entity::component::terrain>(planet_eid); // ctx.entity_registry->remove<entity::component::terrain>(planet_eid);
// Enable clouds in sky pass // Enable clouds in sky pass
//ctx.surface_sky_pass->set_clouds_model(ctx.resource_manager->load<render::model>("cloud-plane.mdl"));
//ctx.sky_pass->set_clouds_model(ctx.resource_manager->load<render::model>("cloud-plane.mdl"));
// Create biome terrain component // Create biome terrain component
/*
entity::component::terrain biome_terrain; entity::component::terrain biome_terrain;
biome_terrain.max_lod = 18; biome_terrain.max_lod = 18;
biome_terrain.patch_material = ctx.resource_manager->load<render::material>("desert-terrain.mtl"); biome_terrain.patch_material = ctx.resource_manager->load<render::material>("desert-terrain.mtl");
@ -89,6 +94,7 @@ nuptial_flight::nuptial_flight(game::context& ctx):
}; };
// Replace planet terrain component with biome terrain component // Replace planet terrain component with biome terrain component
ctx.entity_registry->replace<entity::component::terrain>(planet_eid, biome_terrain); ctx.entity_registry->replace<entity::component::terrain>(planet_eid, biome_terrain);
*/
// Create observer // Create observer
entity::id observer_eid = ctx.entity_registry->create(); entity::id observer_eid = ctx.entity_registry->create();
@ -218,7 +224,7 @@ void nuptial_flight::setup_camera()
ctx.entity_registry->assign<entity::component::constraint_stack>(camera_eid, constraint_stack); ctx.entity_registry->assign<entity::component::constraint_stack>(camera_eid, constraint_stack);
} }
float ev100 = 14.5f;
float ev100 = 13.5f;
ctx.surface_camera->set_exposure(ev100); ctx.surface_camera->set_exposure(ev100);
} }
@ -229,11 +235,13 @@ void nuptial_flight::enable_controls()
entity::id target_eid = ctx.entities["surface_cam_target"]; entity::id target_eid = ctx.entities["surface_cam_target"];
entity::id three_dof_eid = ctx.entities["surface_cam_3dof"]; entity::id three_dof_eid = ctx.entities["surface_cam_3dof"];
const float min_elevation = 0.1f;
const float max_elevation = 100.0f;
const float slow_modifier = 0.25f; const float slow_modifier = 0.25f;
const float fast_modifier = 4.0f; const float fast_modifier = 4.0f;
const float dolly_speed = 20.0f;
const float dolly_speed = 5.0f;
const float truck_speed = dolly_speed; const float truck_speed = dolly_speed;
const float pedestal_speed = 30.0f;
const float pedestal_speed = 5.0f;
float mouse_tilt_sensitivity = 1.0f; float mouse_tilt_sensitivity = 1.0f;
float mouse_pan_sensitivity = 1.0f; float mouse_pan_sensitivity = 1.0f;
bool mouse_invert_tilt = false; bool mouse_invert_tilt = false;
@ -348,14 +356,17 @@ void nuptial_flight::enable_controls()
// Pedestal up // Pedestal up
ctx.controls["move_up"]->set_active_callback ctx.controls["move_up"]->set_active_callback
( (
[&ctx = this->ctx, target_eid, pedestal_speed, move_slow, move_fast, slow_modifier, fast_modifier](float value)
[&ctx = this->ctx, target_eid, pedestal_speed, move_slow, move_fast, slow_modifier, fast_modifier, max_elevation](float value)
{ {
if (move_slow->is_active()) if (move_slow->is_active())
value *= slow_modifier; value *= slow_modifier;
if (move_fast->is_active()) if (move_fast->is_active())
value *= fast_modifier; value *= fast_modifier;
const float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f};
float3 movement = {0.0f, pedestal_speed * value * (1.0f / 60.0f), 0.0f};
auto transform = entity::command::get_world_transform(*ctx.entity_registry, target_eid);
if (transform.translation.y + movement.y > max_elevation)
movement.y = max_elevation - transform.translation.y;
entity::command::translate(*ctx.entity_registry, target_eid, movement); entity::command::translate(*ctx.entity_registry, target_eid, movement);
} }
); );
@ -363,14 +374,18 @@ void nuptial_flight::enable_controls()
// Pedestal down // Pedestal down
ctx.controls["move_down"]->set_active_callback ctx.controls["move_down"]->set_active_callback
( (
[&ctx = this->ctx, target_eid, pedestal_speed, move_slow, move_fast, slow_modifier, fast_modifier](float value)
[&ctx = this->ctx, target_eid, pedestal_speed, move_slow, move_fast, slow_modifier, fast_modifier, min_elevation](float value)
{ {
if (move_slow->is_active()) if (move_slow->is_active())
value *= slow_modifier; value *= slow_modifier;
if (move_fast->is_active()) if (move_fast->is_active())
value *= fast_modifier; value *= fast_modifier;
const float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f};
float3 movement = {0.0f, -pedestal_speed * value * (1.0f / 60.0f), 0.0f};
auto transform = entity::command::get_world_transform(*ctx.entity_registry, target_eid);
if (transform.translation.y + movement.y < min_elevation)
movement.y = min_elevation - transform.translation.y;
entity::command::translate(*ctx.entity_registry, target_eid, movement); entity::command::translate(*ctx.entity_registry, target_eid, movement);
} }
); );

+ 3
- 6
src/game/world.cpp View File

@ -180,7 +180,7 @@ void create_stars(game::context& ctx)
stars_model_group->set_index_count(star_count); stars_model_group->set_index_count(star_count);
// Pass stars model to sky pass // Pass stars model to sky pass
ctx.surface_sky_pass->set_stars_model(stars_model);
ctx.sky_pass->set_stars_model(stars_model);
} }
void create_sun(game::context& ctx) void create_sun(game::context& ctx)
@ -224,13 +224,10 @@ void create_planet(game::context& ctx)
}; };
terrain.max_lod = 0; terrain.max_lod = 0;
terrain.patch_material = nullptr; terrain.patch_material = nullptr;
ctx.entity_registry->assign<entity::component::terrain>(planet_eid, terrain);
//ctx.entity_registry->assign<entity::component::terrain>(planet_eid, terrain);
// Pass planet to astronomy system as reference body // Pass planet to astronomy system as reference body
ctx.astronomy_system->set_reference_body(planet_eid); ctx.astronomy_system->set_reference_body(planet_eid);
// Load sky model
ctx.surface_sky_pass->set_sky_model(ctx.resource_manager->load<render::model>("sky-dome.mdl"));
} }
void create_moon(game::context& ctx) void create_moon(game::context& ctx)
@ -240,7 +237,7 @@ void create_moon(game::context& ctx)
ctx.entities["moon"] = moon_eid; ctx.entities["moon"] = moon_eid;
// Pass moon model to sky pass // Pass moon model to sky pass
ctx.surface_sky_pass->set_moon_model(ctx.resource_manager->load<render::model>("moon.mdl"));
ctx.sky_pass->set_moon_model(ctx.resource_manager->load<render::model>("moon.mdl"));
} }
void set_time(game::context& ctx, double t) void set_time(game::context& ctx, double t)

+ 3
- 0
src/render/context.hpp View File

@ -56,6 +56,9 @@ struct context
/// Near clipping plane of the camera /// Near clipping plane of the camera
geom::plane<float> clip_near; geom::plane<float> clip_near;
/// Camera exposure normalization factor.
float exposure;
/// Collection of scene objects being rendered. /// Collection of scene objects being rendered.
const scene::collection* collection; const scene::collection* collection;

+ 189
- 0
src/render/passes/ground-pass.cpp View File

@ -0,0 +1,189 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "render/passes/ground-pass.hpp"
#include "resources/resource-manager.hpp"
#include "resources/string-table.hpp"
#include "gl/rasterizer.hpp"
#include "gl/framebuffer.hpp"
#include "gl/shader-program.hpp"
#include "gl/shader-input.hpp"
#include "gl/vertex-buffer.hpp"
#include "gl/vertex-array.hpp"
#include "gl/vertex-attribute.hpp"
#include "gl/drawing-mode.hpp"
#include "gl/texture-2d.hpp"
#include "gl/texture-wrapping.hpp"
#include "gl/texture-filter.hpp"
#include "render/vertex-attribute.hpp"
#include "render/context.hpp"
#include "render/model.hpp"
#include "render/material.hpp"
#include "scene/camera.hpp"
#include "scene/collection.hpp"
#include "scene/directional-light.hpp"
#include "scene/ambient-light.hpp"
#include "utility/fundamental-types.hpp"
#include "color/color.hpp"
#include "math/interpolation.hpp"
#include <cmath>
#include <stdexcept>
#include <glad/glad.h>
namespace render {
ground_pass::ground_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffer, resource_manager* resource_manager):
pass(rasterizer, framebuffer),
ground_model(nullptr),
ground_model_vao(nullptr),
ground_material(nullptr),
shader_program(nullptr)
{}
ground_pass::~ground_pass()
{}
void ground_pass::render(const render::context& ctx, render::queue& queue) const
{
if (!ground_model)
return;
rasterizer->use_framebuffer(*framebuffer);
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
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));
float2 resolution = {static_cast<float>(std::get<0>(viewport)), static_cast<float>(std::get<1>(viewport))};
const scene::camera& camera = *ctx.camera;
float clip_near = camera.get_clip_near_tween().interpolate(ctx.alpha);
float clip_far = camera.get_clip_far_tween().interpolate(ctx.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 view = math::resize<4, 4>(math::resize<3, 3>(camera.get_view_tween().interpolate(ctx.alpha)));
float4x4 model_view = view * model;
float4x4 projection = camera.get_projection_tween().interpolate(ctx.alpha);
//float4x4 view_projection = projection * view;
float4x4 model_view_projection = projection * model_view;
float3 ambient_light_color = {0.0f, 0.0f, 0.0f};
float3 directional_light_color = {0.0f, 0.0f, 0.0f};
float3 directional_light_direction = {0.0f, 0.0f, 0.0f};
// Collect lights
const std::list<scene::object_base*>* lights = ctx.collection->get_objects(scene::light::object_type_id);
for (const scene::object_base* object: *lights)
{
// Skip inactive lights
if (!object->is_active())
continue;
const scene::light* light = static_cast<const scene::light*>(object);
switch (light->get_light_type())
{
// Add ambient light
case scene::light_type::ambient:
{
// Pre-expose light
ambient_light_color = light->get_scaled_color_tween().interpolate(ctx.alpha) * ctx.exposure;
break;
}
// Add directional light
case scene::light_type::directional:
{
const scene::directional_light* directional_light = static_cast<const scene::directional_light*>(light);
// Pre-expose light
directional_light_color = light->get_scaled_color_tween().interpolate(ctx.alpha) * ctx.exposure;
directional_light_direction = static_cast<const scene::directional_light*>(light)->get_direction_tween().interpolate(ctx.alpha);
break;
}
default:
break;
}
}
// Draw ground
rasterizer->use_program(*shader_program);
if (model_view_projection_input)
model_view_projection_input->upload(model_view_projection);
if (camera_position_input)
camera_position_input->upload(ctx.camera_transform.translation);
if (directional_light_colors_input)
directional_light_colors_input->upload(0, &directional_light_color, 1);
if (directional_light_directions_input)
directional_light_directions_input->upload(0, &directional_light_direction, 1);
if (ambient_light_colors_input)
ambient_light_colors_input->upload(0, &ambient_light_color, 1);
ground_material->upload(ctx.alpha);
rasterizer->draw_arrays(*ground_model_vao, ground_model_drawing_mode, ground_model_start_index, ground_model_index_count);
}
void ground_pass::set_ground_model(const model* model)
{
ground_model = model;
if (ground_model)
{
ground_model_vao = model->get_vertex_array();
const std::vector<model_group*>& groups = *model->get_groups();
for (model_group* group: groups)
{
ground_material = group->get_material();
ground_model_drawing_mode = group->get_drawing_mode();
ground_model_start_index = group->get_start_index();
ground_model_index_count = group->get_index_count();
}
if (ground_material)
{
shader_program = ground_material->get_shader_program();
if (shader_program)
{
model_view_projection_input = shader_program->get_input("model_view_projection");
camera_position_input = shader_program->get_input("camera.position");
directional_light_colors_input = shader_program->get_input("directional_light_colors");
directional_light_directions_input = shader_program->get_input("directional_light_directions");
ambient_light_colors_input = shader_program->get_input("ambient_light_colors");
}
}
}
else
{
ground_model_vao = nullptr;
}
}
} // namespace render

+ 69
- 0
src/render/passes/ground-pass.hpp View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_RENDER_GROUND_PASS_HPP
#define ANTKEEPER_RENDER_GROUND_PASS_HPP
#include "render/pass.hpp"
#include "utility/fundamental-types.hpp"
#include "animation/tween.hpp"
#include "gl/shader-program.hpp"
#include "gl/shader-input.hpp"
#include "gl/vertex-buffer.hpp"
#include "gl/vertex-array.hpp"
#include "gl/drawing-mode.hpp"
class resource_manager;
namespace render {
class material;
class model;
/**
*
*/
class ground_pass: public pass
{
public:
ground_pass(gl::rasterizer* rasterizer, const gl::framebuffer* framebuffer, resource_manager* resource_manager);
virtual ~ground_pass();
virtual void render(const render::context& ctx, render::queue& queue) const final;
void set_ground_model(const model* model);
private:
gl::shader_program* shader_program;
const gl::shader_input* model_view_projection_input;
const gl::shader_input* camera_position_input;
const gl::shader_input* directional_light_colors_input;
const gl::shader_input* directional_light_directions_input;
const gl::shader_input* ambient_light_colors_input;
const model* ground_model;
const material* ground_material;
const gl::vertex_array* ground_model_vao;
gl::drawing_mode ground_model_drawing_mode;
std::size_t ground_model_start_index;
std::size_t ground_model_index_count;
};
} // namespace render
#endif // ANTKEEPER_RENDER_GROUND_PASS_HPP

+ 5
- 9
src/render/passes/material-pass.cpp View File

@ -132,10 +132,6 @@ void material_pass::render(const render::context& ctx, render::queue& queue) con
clip_depth[0] = ctx.camera->get_clip_near_tween().interpolate(ctx.alpha); clip_depth[0] = ctx.camera->get_clip_near_tween().interpolate(ctx.alpha);
clip_depth[1] = ctx.camera->get_clip_far_tween().interpolate(ctx.alpha); clip_depth[1] = ctx.camera->get_clip_far_tween().interpolate(ctx.alpha);
float log_depth_coef = 2.0f / std::log2(clip_depth[1] + 1.0f); float log_depth_coef = 2.0f / std::log2(clip_depth[1] + 1.0f);
float camera_exposure = std::exp2(-ctx.camera->get_exposure_tween().interpolate(ctx.alpha));
//float camera_exposure = ctx.camera->get_exposure_tween().interpolate(ctx.alpha);
int active_material_flags = 0; int active_material_flags = 0;
const gl::shader_program* active_shader_program = nullptr; const gl::shader_program* active_shader_program = nullptr;
@ -165,7 +161,7 @@ void material_pass::render(const render::context& ctx, render::queue& queue) con
if (ambient_light_count < max_ambient_light_count) if (ambient_light_count < max_ambient_light_count)
{ {
// Pre-expose light // Pre-expose light
ambient_light_colors[ambient_light_count] = light->get_scaled_color_tween().interpolate(ctx.alpha) * camera_exposure;
ambient_light_colors[ambient_light_count] = light->get_scaled_color_tween().interpolate(ctx.alpha) * ctx.exposure;
++ambient_light_count; ++ambient_light_count;
} }
break; break;
@ -177,7 +173,7 @@ void material_pass::render(const render::context& ctx, render::queue& queue) con
if (point_light_count < max_point_light_count) if (point_light_count < max_point_light_count)
{ {
// Pre-expose light // Pre-expose light
point_light_colors[point_light_count] = light->get_scaled_color_tween().interpolate(ctx.alpha) * camera_exposure;
point_light_colors[point_light_count] = light->get_scaled_color_tween().interpolate(ctx.alpha) * ctx.exposure;
float3 position = light->get_transform_tween().interpolate(ctx.alpha).translation; float3 position = light->get_transform_tween().interpolate(ctx.alpha).translation;
point_light_positions[point_light_count] = position; point_light_positions[point_light_count] = position;
@ -196,7 +192,7 @@ void material_pass::render(const render::context& ctx, render::queue& queue) con
const scene::directional_light* directional_light = static_cast<const scene::directional_light*>(light); const scene::directional_light* directional_light = static_cast<const scene::directional_light*>(light);
// Pre-expose light // Pre-expose light
directional_light_colors[directional_light_count] = light->get_scaled_color_tween().interpolate(ctx.alpha) * camera_exposure;
directional_light_colors[directional_light_count] = light->get_scaled_color_tween().interpolate(ctx.alpha) * ctx.exposure;
float3 direction = static_cast<const scene::directional_light*>(light)->get_direction_tween().interpolate(ctx.alpha); float3 direction = static_cast<const scene::directional_light*>(light)->get_direction_tween().interpolate(ctx.alpha);
directional_light_directions[directional_light_count] = direction; directional_light_directions[directional_light_count] = direction;
@ -236,7 +232,7 @@ void material_pass::render(const render::context& ctx, render::queue& queue) con
const scene::spot_light* spot_light = static_cast<const scene::spot_light*>(light); const scene::spot_light* spot_light = static_cast<const scene::spot_light*>(light);
// Pre-expose light // Pre-expose light
spot_light_colors[spot_light_count] = light->get_scaled_color_tween().interpolate(ctx.alpha) * camera_exposure;
spot_light_colors[spot_light_count] = light->get_scaled_color_tween().interpolate(ctx.alpha) * ctx.exposure;
float3 position = light->get_transform_tween().interpolate(ctx.alpha).translation; float3 position = light->get_transform_tween().interpolate(ctx.alpha).translation;
spot_light_positions[spot_light_count] = position; spot_light_positions[spot_light_count] = position;
@ -447,7 +443,7 @@ void material_pass::render(const render::context& ctx, render::queue& queue) con
if (parameters->camera_position) if (parameters->camera_position)
parameters->camera_position->upload(camera_position); parameters->camera_position->upload(camera_position);
if (parameters->camera_exposure) if (parameters->camera_exposure)
parameters->camera_exposure->upload(camera_exposure);
parameters->camera_exposure->upload(ctx.exposure);
if (parameters->view) if (parameters->view)
parameters->view->upload(view); parameters->view->upload(view);
if (parameters->view_projection) if (parameters->view_projection)

+ 7
- 6
src/render/passes/sky-pass.cpp View File

@ -105,8 +105,6 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
float4x4 projection = camera.get_projection_tween().interpolate(ctx.alpha); float4x4 projection = camera.get_projection_tween().interpolate(ctx.alpha);
float4x4 view_projection = projection * view; float4x4 view_projection = projection * view;
float4x4 model_view_projection = projection * model_view; float4x4 model_view_projection = projection * model_view;
float exposure = std::exp2(-camera.get_exposure_tween().interpolate(ctx.alpha));
//float exposure = camera.get_exposure_tween().interpolate(ctx.alpha);
// Interpolate observer altitude // Interpolate observer altitude
float observer_altitude = observer_altitude_tween.interpolate(ctx.alpha); float observer_altitude = observer_altitude_tween.interpolate(ctx.alpha);
@ -141,7 +139,7 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
if (time_input) if (time_input)
time_input->upload(ctx.t); time_input->upload(ctx.t);
if (exposure_input) if (exposure_input)
exposure_input->upload(exposure);
exposure_input->upload(ctx.exposure);
if (observer_altitude_input) if (observer_altitude_input)
observer_altitude_input->upload(observer_altitude); observer_altitude_input->upload(observer_altitude);
@ -149,8 +147,11 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
sun_direction_input->upload(sun_direction); sun_direction_input->upload(sun_direction);
if (sun_angular_radius_input) if (sun_angular_radius_input)
sun_angular_radius_input->upload(sun_angular_radius); sun_angular_radius_input->upload(sun_angular_radius);
// Pre-exposure sun color
if (sun_color_input) if (sun_color_input)
sun_color_input->upload(sun_color_outer);
sun_color_input->upload(sun_color_outer * ctx.exposure);
if (scale_height_rm_input) if (scale_height_rm_input)
scale_height_rm_input->upload(scale_height_rm); scale_height_rm_input->upload(scale_height_rm);
if (rayleigh_scattering_input) if (rayleigh_scattering_input)
@ -181,7 +182,7 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
if (cloud_camera_position_input) if (cloud_camera_position_input)
cloud_camera_position_input->upload(ctx.camera_transform.translation); cloud_camera_position_input->upload(ctx.camera_transform.translation);
if (cloud_camera_exposure_input) if (cloud_camera_exposure_input)
cloud_camera_exposure_input->upload(exposure);
cloud_camera_exposure_input->upload(ctx.exposure);
cloud_material->upload(ctx.alpha); cloud_material->upload(ctx.alpha);
@ -210,7 +211,7 @@ void sky_pass::render(const render::context& ctx, render::queue& queue) const
if (star_distance_input) if (star_distance_input)
star_distance_input->upload(star_distance); star_distance_input->upload(star_distance);
if (star_exposure_input) if (star_exposure_input)
star_exposure_input->upload(exposure);
star_exposure_input->upload(ctx.exposure);
star_material->upload(ctx.alpha); star_material->upload(ctx.alpha);

+ 2
- 1
src/render/renderer.cpp View File

@ -97,7 +97,8 @@ void renderer::render(float t, float dt, float alpha, const scene::collection& c
ctx.camera_transform = camera->get_transform_tween().interpolate(alpha); ctx.camera_transform = camera->get_transform_tween().interpolate(alpha);
ctx.camera_forward = ctx.camera_transform.rotation * config::global_forward; ctx.camera_forward = ctx.camera_transform.rotation * config::global_forward;
ctx.camera_up = ctx.camera_transform.rotation * config::global_up; ctx.camera_up = ctx.camera_transform.rotation * config::global_up;
ctx.clip_near = camera->get_view_frustum().get_near(); ///< TODO: tween this
ctx.clip_near = camera->get_view_frustum().get_near(); ///< @TODO: tween this
ctx.exposure = std::exp2(-camera->get_exposure_tween().interpolate(alpha));
// Create render queue // Create render queue
render::queue queue; render::queue queue;

Loading…
Cancel
Save