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_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_filters(texture_min_filter::linear, texture_mag_filter::linear);
ctx->framebuffer_hdr_color->set_max_anisotropy(0.0f); 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_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_filters(texture_min_filter::linear, texture_mag_filter::linear);
ctx->framebuffer_hdr_depth->set_max_anisotropy(0.0f); ctx->framebuffer_hdr_depth->set_max_anisotropy(0.0f);
@ -1179,7 +1179,7 @@ void setup_controls(game_context* ctx)
( (
[ctx, time_scale]() [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 ctx->control_system->get_fast_forward_control()->set_deactivated_callback
@ -1193,7 +1193,7 @@ void setup_controls(game_context* ctx)
( (
[ctx, time_scale]() [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 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")); 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_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_sky_palette(ctx->biome->sky_palette);
ctx->weather_system->set_sun_palette(ctx->biome->sun_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_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); 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 left Signed distance to the left clipping plane.
* @param right Signed distance to the right 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> template <class T>
matrix<T, 4, 4> ortho(T left, T right, T bottom, T top, T z_near, T z_far); 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. * 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); 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 vertical_fov Vertical field of view angle, in radians.
* @param aspect_ratio Aspect ratio which determines the horizontal field of view. * @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> template <class T>
matrix<T, 4, 4> perspective(T vertical_fov, T aspect_ratio, T z_near, T z_far); 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. * 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> template <class T>
matrix<T, 2, 2> outer_product(const vector<T, 2>& c, const vector<T, 2>& r) 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)}, {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_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)} {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> 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) 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); glCullFace(GL_BACK);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
glStencilMask(0x00); glStencilMask(0x00);
// For half-z buffer
glDepthRange(-1.0f, 1.0f);
auto viewport = framebuffer->get_dimensions(); auto viewport = framebuffer->get_dimensions();
rasterizer->set_viewport(0, 0, std::get<0>(viewport), std::get<1>(viewport)); 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;
float4x4 model_view; float4x4 model_view;
float3x3 normal_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; 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); parameters->model_view_projection->upload(model_view_projection);
if (parameters->normal_model_view) if (parameters->normal_model_view)
parameters->normal_model_view->upload(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 // Draw geometry
if (operation.instance_count) 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->view_projection = program->get_input("view_projection");
parameters->model_view_projection = program->get_input("model_view_projection"); parameters->model_view_projection = program->get_input("model_view_projection");
parameters->normal_model_view = program->get_input("normal_model_view"); 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_count = program->get_input("ambient_light_count");
parameters->ambient_light_colors = program->get_input("ambient_light_colors"); parameters->ambient_light_colors = program->get_input("ambient_light_colors");
parameters->point_light_count = program->get_input("point_light_count"); 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* view_projection;
const shader_input* model_view_projection; const shader_input* model_view_projection;
const shader_input* normal_model_view; 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_count;
const shader_input* ambient_light_colors; 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 // Disable face culling
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
// For half-z buffer
//glDepthRange(-1.0f, 1.0f);
// Get camera // Get camera
const ::camera& camera = *context->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 forward = light_transform.rotation * global_forward;
float3 up = light_transform.rotation * global_up; float3 up = light_transform.rotation * global_up;
float4x4 light_view = math::look_at(light_transform.translation, light_transform.translation + forward, 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; float4x4 light_view_projection = light_projection * light_view;
// Get the camera's view matrix // 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 // Calculate projection matrix for view camera subfrustum
const float subfrustum_near = split_distances[i]; const float subfrustum_near = split_distances[i];
const float subfrustum_far = split_distances[i + 1]; 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 // Calculate view camera subfrustum
view_frustum<float> subfrustum(subfrustum_projection * camera_view); 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.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.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 = 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 // Quantize scale
float scale_quantizer = 64.0f; 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.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.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.min_point.z * scale.z;
//offset.z = (cropping_bounds.max_point.z + cropping_bounds.min_point.z) * scale.z * -0.5f;
// Quantize offset // Quantize offset
float half_shadow_map_resolution = static_cast<float>(shadow_map_resolution) * 0.5f; 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; float4 result;
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;
//result[2] = window[2] * 2.0f - 1.0f; z: [-1, 1]
result[2] = window[2]; // z: [0, 1]
result[3] = 1.0f; result[3] = 1.0f;
result = math::inverse(view_projection[1]) * result; 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_near[1] = clip_near;
this->clip_far[1] = clip_far; 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 // Recalculate view-projection matrix
view_projection[1] = projection[1] * view[1]; view_projection[1] = projection[1] * view[1];

Loading…
Cancel
Save