Browse Source

Make camera use reverse z projection for increased depth testing accuracy

master
C. J. Howard 4 years ago
parent
commit
de96e99c67
7 changed files with 36 additions and 18 deletions
  1. +3
    -0
      src/game/bootloader.cpp
  2. +17
    -2
      src/game/states/play-state.cpp
  3. +1
    -1
      src/game/systems/camera-system.cpp
  4. +2
    -2
      src/game/systems/vegetation-system.cpp
  5. +2
    -2
      src/math/matrix-functions.hpp
  6. +3
    -4
      src/renderer/passes/material-pass.cpp
  7. +8
    -7
      src/scene/camera.cpp

+ 3
- 0
src/game/bootloader.cpp View File

@ -495,10 +495,12 @@ void setup_rendering(game_context* ctx)
// Setup overworld compositor // Setup overworld compositor
ctx->overworld_shadow_map_clear_pass = new clear_pass(ctx->rasterizer, ctx->shadow_map_framebuffer); ctx->overworld_shadow_map_clear_pass = new clear_pass(ctx->rasterizer, ctx->shadow_map_framebuffer);
ctx->overworld_shadow_map_clear_pass->set_cleared_buffers(false, true, false); ctx->overworld_shadow_map_clear_pass->set_cleared_buffers(false, true, false);
ctx->overworld_shadow_map_clear_pass->set_clear_depth(1.0f);
ctx->overworld_shadow_map_pass = new shadow_map_pass(ctx->rasterizer, ctx->shadow_map_framebuffer, ctx->resource_manager); 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_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 = new clear_pass(ctx->rasterizer, ctx->framebuffer_hdr);
ctx->overworld_clear_pass->set_cleared_buffers(true, true, true); ctx->overworld_clear_pass->set_cleared_buffers(true, true, true);
ctx->overworld_clear_pass->set_clear_depth(0.0f);
ctx->overworld_sky_pass = new sky_pass(ctx->rasterizer, ctx->framebuffer_hdr, ctx->resource_manager); 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->app->get_event_dispatcher()->subscribe<mouse_moved_event>(ctx->overworld_sky_pass);
ctx->overworld_sky_pass->set_enabled(false); ctx->overworld_sky_pass->set_enabled(false);
@ -548,6 +550,7 @@ void setup_rendering(game_context* ctx)
// Setup UI camera compositor // Setup UI camera compositor
ctx->ui_clear_pass = new clear_pass(ctx->rasterizer, &ctx->rasterizer->get_default_framebuffer()); ctx->ui_clear_pass = new clear_pass(ctx->rasterizer, &ctx->rasterizer->get_default_framebuffer());
ctx->ui_clear_pass->set_cleared_buffers(false, true, false); ctx->ui_clear_pass->set_cleared_buffers(false, true, false);
ctx->ui_clear_pass->set_clear_depth(0.0f);
ctx->ui_material_pass = new material_pass(ctx->rasterizer, &ctx->rasterizer->get_default_framebuffer(), ctx->resource_manager); ctx->ui_material_pass = new material_pass(ctx->rasterizer, &ctx->rasterizer->get_default_framebuffer(), ctx->resource_manager);
ctx->ui_material_pass->set_fallback_material(ctx->fallback_material); ctx->ui_material_pass->set_fallback_material(ctx->fallback_material);
ctx->ui_compositor = new compositor(); ctx->ui_compositor = new compositor();

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

@ -119,6 +119,7 @@ void play_state_enter(game_context* ctx)
ecs::archetype* lens_light_cone_archetype = resource_manager->load<ecs::archetype>("lens-light-cone.ent"); ecs::archetype* lens_light_cone_archetype = resource_manager->load<ecs::archetype>("lens-light-cone.ent");
ecs::archetype* ant_head_archetype = resource_manager->load<ecs::archetype>("ant-head.ent"); ecs::archetype* ant_head_archetype = resource_manager->load<ecs::archetype>("ant-head.ent");
ecs::archetype* dandelion_plant_archetype = resource_manager->load<ecs::archetype>("dandelion-plant.ent"); ecs::archetype* dandelion_plant_archetype = resource_manager->load<ecs::archetype>("dandelion-plant.ent");
ecs::archetype* grassland_road_archetype = resource_manager->load<ecs::archetype>("grassland-road.ent");
// Create tools // Create tools
forceps_archetype->assign(ecs_registry, ctx->forceps_entity); forceps_archetype->assign(ecs_registry, ctx->forceps_entity);
@ -158,6 +159,20 @@ void play_state_enter(game_context* ctx)
// Activate brush tool // Activate brush tool
ctx->tool_system->set_active_tool(ctx->brush_entity); ctx->tool_system->set_active_tool(ctx->brush_entity);
// Create background
for (int i = 0; i < 4; ++i)
{
auto road_entity = grassland_road_archetype->create(ecs_registry);
auto& transform = ecs_registry.get<ecs::transform_component>(road_entity);
math::quaternion<float> rotation = math::angle_axis(math::half_pi<float> * static_cast<float>(i), float3{0, 1, 0});
float3 translation = rotation * float3{0, 0, 1600.0f};
transform.local = math::identity_transform<float>;
transform.local.rotation = rotation;
transform.local.translation = translation;
}
// Create ant-hill // Create ant-hill
auto ant_hill_entity = ant_hill_archetype->create(ecs_registry); auto ant_hill_entity = ant_hill_archetype->create(ecs_registry);
@ -165,7 +180,7 @@ void play_state_enter(game_context* ctx)
// Generate pebbles // Generate pebbles
float pebble_radius = 300.0f; float pebble_radius = 300.0f;
int pebble_count = 100;
int pebble_count = 20;
for (int i = 0; i < pebble_count; ++i) for (int i = 0; i < pebble_count; ++i)
{ {
float x = math::random(-pebble_radius, pebble_radius); float x = math::random(-pebble_radius, pebble_radius);
@ -189,7 +204,7 @@ void play_state_enter(game_context* ctx)
auto nest_entity = nest_archetype->create(ecs_registry); auto nest_entity = nest_archetype->create(ecs_registry);
// Create terrain // Create terrain
int terrain_radius = 2;
int terrain_radius = 8;
for (int x = -terrain_radius; x <= terrain_radius; ++x) for (int x = -terrain_radius; x <= terrain_radius; ++x)
{ {
for (int z = -terrain_radius; z <= terrain_radius; ++z) for (int z = -terrain_radius; z <= terrain_radius; ++z)

+ 1
- 1
src/game/systems/camera-system.cpp View File

@ -39,7 +39,7 @@ camera_system::camera_system(entt::registry& registry):
orbit_cam.set_focal_distance_limits({2.0f, 200.0f}); orbit_cam.set_focal_distance_limits({2.0f, 200.0f});
orbit_cam.set_fov_limits({math::radians(80.0f), math::radians(35.0f)}); orbit_cam.set_fov_limits({math::radians(80.0f), math::radians(35.0f)});
orbit_cam.set_clip_near_limits({0.1f, 5.0f}); orbit_cam.set_clip_near_limits({0.1f, 5.0f});
orbit_cam.set_clip_far_limits({100.0f, 2000.0f});
orbit_cam.set_clip_far_limits({5000.0f, 5000.0f});
orbit_cam.set_target_focal_point({0.0f, 0.0f, 0.0f}); orbit_cam.set_target_focal_point({0.0f, 0.0f, 0.0f});
orbit_cam.set_target_azimuth(0.0f); orbit_cam.set_target_azimuth(0.0f);

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

@ -39,8 +39,8 @@ vegetation_system::vegetation_system(entt::registry& registry):
vegetation_density(1.0f), vegetation_density(1.0f),
vegetation_model(nullptr) vegetation_model(nullptr)
{ {
registry.on_construct<terrain_component>().connect<&vegetation_system::on_terrain_construct>(this);
registry.on_destroy<terrain_component>().connect<&vegetation_system::on_terrain_destroy>(this);
//registry.on_construct<terrain_component>().connect<&vegetation_system::on_terrain_construct>(this);
//registry.on_destroy<terrain_component>().connect<&vegetation_system::on_terrain_destroy>(this);
} }
vegetation_system::~vegetation_system() vegetation_system::~vegetation_system()

+ 2
- 2
src/math/matrix-functions.hpp View File

@ -660,8 +660,8 @@ matrix perspective(T vertical_fov, T aspect_ratio, T z_near, T z_far)
{{ {{
{f / aspect_ratio, T(0), T(0), T(0)}, {f / aspect_ratio, T(0), T(0), T(0)},
{T(0), f, T(0), T(0)}, {T(0), f, T(0), T(0)},
{T(0), T(0), (z_near + z_far) / (z_near - z_far), T(-1)},
{T(0), T(0), (T(2) * z_near * z_far) / (z_near - z_far), T(0)}
{T(0), T(0), (z_far + z_near) / (z_near - z_far), T(-1)},
{T(0), T(0), (T(2) * z_far * z_near) / (z_near - z_far), T(0)}
}}; }};
} }

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

@ -106,9 +106,8 @@ void material_pass::render(render_context* context) const
glDisable(GL_BLEND); glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
glDepthFunc(GL_GREATER);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
@ -354,7 +353,7 @@ void material_pass::render(render_context* context) const
if (material_flags & MATERIAL_FLAG_DECAL) if (material_flags & MATERIAL_FLAG_DECAL)
{ {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthFunc(GL_GEQUAL);
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
@ -367,7 +366,7 @@ void material_pass::render(render_context* context) const
else else
{ {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthFunc(GL_GREATER);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
glStencilMask(0); glStencilMask(0);

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

@ -40,16 +40,16 @@ static float4x4 interpolate_projection(const camera* camera, const float4x4& x,
camera->get_clip_right_tween().interpolate(a), camera->get_clip_right_tween().interpolate(a),
camera->get_clip_bottom_tween().interpolate(a), camera->get_clip_bottom_tween().interpolate(a),
camera->get_clip_top_tween().interpolate(a), camera->get_clip_top_tween().interpolate(a),
camera->get_clip_near_tween().interpolate(a),
camera->get_clip_far_tween().interpolate(a));
camera->get_clip_far_tween().interpolate(a),
camera->get_clip_near_tween().interpolate(a));
} }
else else
{ {
return math::perspective( return math::perspective(
camera->get_fov_tween().interpolate(a), camera->get_fov_tween().interpolate(a),
camera->get_aspect_ratio_tween().interpolate(a), camera->get_aspect_ratio_tween().interpolate(a),
camera->get_clip_near_tween().interpolate(a),
camera->get_clip_far_tween().interpolate(a));
camera->get_clip_far_tween().interpolate(a),
camera->get_clip_near_tween().interpolate(a));
} }
} }
@ -94,7 +94,8 @@ float3 camera::unproject(const float3& window, const float4& viewport) const
result[0] = ((window[0] - viewport[0]) / viewport[2]) * 2.0f - 1.0f; result[0] = ((window[0] - viewport[0]) / viewport[2]) * 2.0f - 1.0f;
result[1] = ((window[1] - viewport[1]) / viewport[3]) * 2.0f - 1.0f; result[1] = ((window[1] - viewport[1]) / viewport[3]) * 2.0f - 1.0f;
//result[2] = window[2] * 2.0f - 1.0f; z: [-1, 1] //result[2] = window[2] * 2.0f - 1.0f; z: [-1, 1]
result[2] = window[2]; // z: [0, 1]
//result[2] = window[2]; // z: [0, 1]
result[2] = 1.0f - window[2]; // z: [1, 0]
result[3] = 1.0f; result[3] = 1.0f;
result = math::inverse(view_projection[1]) * result; result = math::inverse(view_projection[1]) * result;
@ -111,7 +112,7 @@ void camera::set_perspective(float fov, float aspect_ratio, float clip_near, flo
this->clip_near[1] = clip_near; this->clip_near[1] = clip_near;
this->clip_far[1] = clip_far; this->clip_far[1] = clip_far;
projection[1] = math::perspective_half_z(fov, aspect_ratio, clip_near, clip_far);
projection[1] = math::perspective_half_z(fov, aspect_ratio, clip_far, clip_near);
// Recalculate view-projection matrix // Recalculate view-projection matrix
view_projection[1] = projection[1] * view[1]; view_projection[1] = projection[1] * view[1];
@ -131,7 +132,7 @@ void camera::set_orthographic(float clip_left, float clip_right, float clip_bott
this->clip_near[1] = clip_near; this->clip_near[1] = clip_near;
this->clip_far[1] = clip_far; this->clip_far[1] = clip_far;
projection[1] = math::ortho(clip_left, clip_right, clip_bottom, clip_top, clip_near, clip_far);
projection[1] = math::ortho_half_z(clip_left, clip_right, clip_bottom, clip_top, clip_far, clip_near);
// Recalculate view-projection matrix // Recalculate view-projection matrix
view_projection[1] = projection[1] * view[1]; view_projection[1] = projection[1] * view[1];

Loading…
Cancel
Save