Browse Source

Add half z matrix projection functions

master
C. J. Howard 3 years ago
parent
commit
a11bca4ce2
7 changed files with 85 additions and 14 deletions
  1. +3
    -3
      src/game/bootloader.cpp
  2. +1
    -1
      src/game/states/play-state.cpp
  3. +56
    -3
      src/math/matrix-functions.hpp
  4. +13
    -3
      src/renderer/passes/material-pass.cpp
  5. +2
    -0
      src/renderer/passes/material-pass.hpp
  6. +7
    -2
      src/renderer/passes/shadow-map-pass.cpp
  7. +3
    -2
      src/scene/camera.cpp

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

@ -454,7 +454,7 @@ void setup_rendering(game_context* ctx)
ctx->framebuffer_hdr_color->set_wrapping(texture_wrapping::clamp, texture_wrapping::clamp);
ctx->framebuffer_hdr_color->set_filters(texture_min_filter::linear, texture_mag_filter::linear);
ctx->framebuffer_hdr_color->set_max_anisotropy(0.0f);
ctx->framebuffer_hdr_depth = new texture_2d(viewport_dimensions[0], viewport_dimensions[1], pixel_type::uint_32, pixel_format::ds);
ctx->framebuffer_hdr_depth = new texture_2d(viewport_dimensions[0], viewport_dimensions[1], pixel_type::float_32, pixel_format::ds);
ctx->framebuffer_hdr_depth->set_wrapping(texture_wrapping::clamp, texture_wrapping::clamp);
ctx->framebuffer_hdr_depth->set_filters(texture_min_filter::linear, texture_mag_filter::linear);
ctx->framebuffer_hdr_depth->set_max_anisotropy(0.0f);
@ -1179,7 +1179,7 @@ void setup_controls(game_context* ctx)
(
[ctx, time_scale]()
{
ctx->weather_system->set_time_scale(time_scale * 50.0f);
ctx->weather_system->set_time_scale(time_scale * 500.0f);
}
);
ctx->control_system->get_fast_forward_control()->set_deactivated_callback
@ -1193,7 +1193,7 @@ void setup_controls(game_context* ctx)
(
[ctx, time_scale]()
{
ctx->weather_system->set_time_scale(time_scale * -50.0f);
ctx->weather_system->set_time_scale(time_scale * -500.0f);
}
);
ctx->control_system->get_rewind_control()->set_deactivated_callback

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

@ -91,7 +91,7 @@ void play_state_enter(game_context* ctx)
sky_pass->set_sky_model(ctx->resource_manager->load<model>("sky-dome.mdl"));
ctx->weather_system->set_coordinates(ctx->biome->coordinates);
ctx->weather_system->set_time(2020, 10, 1, 6, 0, 0, -7.0);
ctx->weather_system->set_time(2020, 6, 1, 5, 0, 0, -7.0);
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);

+ 56
- 3
src/math/matrix-functions.hpp View File

@ -166,7 +166,7 @@ template
vector<T, 4> mul(const matrix<T, 4, 4>& m, const vector<T, 4>& v);
/**
* Creates an orthographic projection matrix.
* Creates an orthographic projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively.
*
* @param left Signed distance to the left clipping plane.
* @param right Signed distance to the right clipping plane.
@ -179,6 +179,20 @@ vector mul(const matrix& m, const vector& v);
template <class T>
matrix<T, 4, 4> ortho(T left, T right, T bottom, T top, T z_near, T z_far);
/**
* Creates an orthographic projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively.
*
* @param left Signed distance to the left clipping plane.
* @param right Signed distance to the right clipping plane.
* @param bottom Signed distance to the bottom clipping plane.
* @param top Signed distance to the top clipping plane.
* @param z_near Signed distance to the near clipping plane.
* @param z_far Signed distance to the far clipping plane.
* @return Orthographic projection matrix.
*/
template <class T>
matrix<T, 4, 4> ortho_half_z(T left, T right, T bottom, T top, T z_near, T z_far);
/**
* Calculates the outer product of a pair of vectors.
*
@ -197,7 +211,7 @@ template
matrix<T, 4, 4> outer_product(const vector<T, 4>& c, const vector<T, 4> r);
/**
* Creates a perspective projection matrix.
* Creates a perspective projection matrix which will transform the near and far clipping planes to `[-1, 1]`, respectively.
*
* @param vertical_fov Vertical field of view angle, in radians.
* @param aspect_ratio Aspect ratio which determines the horizontal field of view.
@ -208,6 +222,18 @@ matrix outer_product(const vector& c, const vector r);
template <class T>
matrix<T, 4, 4> perspective(T vertical_fov, T aspect_ratio, T z_near, T z_far);
/**
* Creates a perspective projection matrix which will transform the near and far clipping planes to `[0, 1]`, respectively.
*
* @param vertical_fov Vertical field of view angle, in radians.
* @param aspect_ratio Aspect ratio which determines the horizontal field of view.
* @param z_near Distance to the near clipping plane.
* @param z_far Distance to the far clipping plane.
* @return Perspective projection matrix.
*/
template <class T>
matrix<T, 4, 4> perspective_half_z(T vertical_fov, T aspect_ratio, T z_near, T z_far);
/**
* Resizes a matrix. Any new elements will be set to `1` if in the diagonal, and `0` otherwise.
*
@ -579,6 +605,18 @@ matrix ortho(T left, T right, T bottom, T top, T z_near, T z_far)
}};
}
template <class T>
matrix<T, 4, 4> ortho_half_z(T left, T right, T bottom, T top, T z_near, T z_far)
{
return
{{
{T(2) / (right - left), T(0), T(0), T(0)},
{T(0), T(2) / (top - bottom), T(0), T(0)},
{T(0), T(0), T(-1) / (z_far - z_near), T(0)},
{-((right + left) / (right - left)), -((top + bottom) / (top - bottom)), -z_near / (z_far - z_near), T(1)}
}};
}
template <class T>
matrix<T, 2, 2> outer_product(const vector<T, 2>& c, const vector<T, 2>& r)
{
@ -622,11 +660,26 @@ matrix perspective(T vertical_fov, T aspect_ratio, T z_near, T z_far)
{{
{f / aspect_ratio, T(0), T(0), T(0)},
{T(0), f, T(0), T(0)},
{T(0), T(0), (z_far + z_near) / (z_near - z_far), T(-1)},
{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)}
}};
}
template <class T>
matrix<T, 4, 4> perspective_half_z(T vertical_fov, T aspect_ratio, T z_near, T z_far)
{
T half_fov = vertical_fov * T(0.5);
T f = std::cos(half_fov) / std::sin(half_fov);
return
{{
{f / aspect_ratio, T(0), T(0), T(0)},
{T(0), f, T(0), T(0)},
{T(0), T(0), z_far / (z_near - z_far), T(-1)},
{T(0), T(0), -(z_far * z_near) / (z_far - z_near), T(0)}
}};
}
template <std::size_t N1, std::size_t M1, class T, std::size_t N0, std::size_t M0>
matrix<T, N1, M1> resize(const matrix<T, N0, M0>& m)
{

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

@ -113,6 +113,9 @@ void material_pass::render(render_context* context) const
glCullFace(GL_BACK);
glDisable(GL_STENCIL_TEST);
glStencilMask(0x00);
// For half-z buffer
glDepthRange(-1.0f, 1.0f);
auto viewport = framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport));
@ -128,9 +131,10 @@ void material_pass::render(render_context* context) const
float4x4 model;
float4x4 model_view;
float3x3 normal_model_view;
float2 clip_depth;
clip_depth[0] = context->camera->get_clip_near_tween().interpolate(context->alpha);
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);
int active_material_flags = 0;
@ -488,6 +492,10 @@ void material_pass::render(render_context* context) const
parameters->model_view_projection->upload(model_view_projection);
if (parameters->normal_model_view)
parameters->normal_model_view->upload(normal_model_view);
if (parameters->clip_depth)
parameters->clip_depth->upload(clip_depth);
if (parameters->log_depth_coef)
parameters->log_depth_coef->upload(log_depth_coef);
// Draw geometry
if (operation.instance_count)
@ -533,6 +541,8 @@ const material_pass::parameter_set* material_pass::load_parameter_set(const shad
parameters->view_projection = program->get_input("view_projection");
parameters->model_view_projection = program->get_input("model_view_projection");
parameters->normal_model_view = program->get_input("normal_model_view");
parameters->clip_depth = program->get_input("clip_depth");
parameters->log_depth_coef = program->get_input("log_depth_coef");
parameters->ambient_light_count = program->get_input("ambient_light_count");
parameters->ambient_light_colors = program->get_input("ambient_light_colors");
parameters->point_light_count = program->get_input("point_light_count");

+ 2
- 0
src/renderer/passes/material-pass.hpp View File

@ -77,6 +77,8 @@ private:
const shader_input* view_projection;
const shader_input* model_view_projection;
const shader_input* normal_model_view;
const shader_input* clip_depth;
const shader_input* log_depth_coef;
const shader_input* ambient_light_count;
const shader_input* ambient_light_colors;

+ 7
- 2
src/renderer/passes/shadow-map-pass.cpp View File

@ -107,6 +107,9 @@ void shadow_map_pass::render(render_context* context) const
// Disable face culling
glDisable(GL_CULL_FACE);
// For half-z buffer
//glDepthRange(-1.0f, 1.0f);
// Get camera
const ::camera& camera = *context->camera;
@ -137,7 +140,7 @@ void shadow_map_pass::render(render_context* context) const
float3 forward = light_transform.rotation * global_forward;
float3 up = light_transform.rotation * global_up;
float4x4 light_view = math::look_at(light_transform.translation, light_transform.translation + forward, up);
float4x4 light_projection = math::ortho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
float4x4 light_projection = math::ortho_half_z(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
float4x4 light_view_projection = light_projection * light_view;
// Get the camera's view matrix
@ -161,7 +164,7 @@ void shadow_map_pass::render(render_context* context) const
// Calculate projection matrix for view camera subfrustum
const float subfrustum_near = split_distances[i];
const float subfrustum_far = split_distances[i + 1];
float4x4 subfrustum_projection = math::perspective(camera.get_fov(), camera.get_aspect_ratio(), subfrustum_near, subfrustum_far);
float4x4 subfrustum_projection = math::perspective_half_z(camera.get_fov(), camera.get_aspect_ratio(), subfrustum_near, subfrustum_far);
// Calculate view camera subfrustum
view_frustum<float> subfrustum(subfrustum_projection * camera_view);
@ -186,6 +189,7 @@ void shadow_map_pass::render(render_context* context) const
scale.x = 2.0f / (cropping_bounds.max_point.x - cropping_bounds.min_point.x);
scale.y = 2.0f / (cropping_bounds.max_point.y - cropping_bounds.min_point.y);
scale.z = 1.0f / (cropping_bounds.max_point.z - cropping_bounds.min_point.z);
//scale.z = 2.0f / (cropping_bounds.max_point.z - cropping_bounds.min_point.z);
// Quantize scale
float scale_quantizer = 64.0f;
@ -197,6 +201,7 @@ void shadow_map_pass::render(render_context* context) const
offset.x = (cropping_bounds.max_point.x + cropping_bounds.min_point.x) * scale.x * -0.5f;
offset.y = (cropping_bounds.max_point.y + cropping_bounds.min_point.y) * scale.y * -0.5f;
offset.z = -cropping_bounds.min_point.z * scale.z;
//offset.z = (cropping_bounds.max_point.z + cropping_bounds.min_point.z) * scale.z * -0.5f;
// Quantize offset
float half_shadow_map_resolution = static_cast<float>(shadow_map_resolution) * 0.5f;

+ 3
- 2
src/scene/camera.cpp View File

@ -93,7 +93,8 @@ float3 camera::unproject(const float3& window, const float4& viewport) const
float4 result;
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[2] = window[2] * 2.0f - 1.0f;
//result[2] = window[2] * 2.0f - 1.0f; z: [-1, 1]
result[2] = window[2]; // z: [0, 1]
result[3] = 1.0f;
result = math::inverse(view_projection[1]) * result;
@ -110,7 +111,7 @@ void camera::set_perspective(float fov, float aspect_ratio, float clip_near, flo
this->clip_near[1] = clip_near;
this->clip_far[1] = clip_far;
projection[1] = math::perspective(fov, aspect_ratio, clip_near, clip_far);
projection[1] = math::perspective_half_z(fov, aspect_ratio, clip_near, clip_far);
// Recalculate view-projection matrix
view_projection[1] = projection[1] * view[1];

Loading…
Cancel
Save