From 0cf44f532a3d8c83e0e24858cd5303d5daf84b6d Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 12 Dec 2020 20:49:50 +0300 Subject: [PATCH] Deferred renderer: add proper frustum culling --- libs/gfx/source/renderer/deferred.cpp | 33 ++++++++------------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/libs/gfx/source/renderer/deferred.cpp b/libs/gfx/source/renderer/deferred.cpp index 02247c6e..f2511c4d 100644 --- a/libs/gfx/source/renderer/deferred.cpp +++ b/libs/gfx/source/renderer/deferred.cpp @@ -20,6 +20,9 @@ #include #include +#include +#include +#include #include #include @@ -966,20 +969,7 @@ void main() auto const camera_position = opts.camera->position(); auto const camera_direction = opts.camera->direction(); - geom::point camera_frustum_vertices[8]; - - for (int i = 0; i < 8; ++i) - { - geom::vector p; - p[0] = (i & 1) ? 1.f : -1.f; - p[1] = (i & 2) ? 1.f : -1.f; - p[2] = (i & 4) ? 1.f : -1.f; - p[3] = 1.f; - - geom::gauss(camera_transform, p); - - camera_frustum_vertices[i] = geom::as_point(p); - } + cg::frustum camera_frustum(camera_transform); // Sort objects by mask & compute bbox @@ -994,7 +984,7 @@ void main() std::unordered_map, objects_bucket> buckets; geom::box bbox; bool contains_near_clip = false; - float camera_distance = -std::numeric_limits::infinity(); + float camera_separation; }; geom::box all_bbox; @@ -1052,16 +1042,11 @@ void main() { b.bbox = geom::expand(b.bbox, b.bbox.dimensions() / 64.f); - float dist = -std::numeric_limits::infinity(); - for (int c = 0; c < 8; ++c) - { - dist = std::max(dist, dot(b.bbox.corner(c & 1, (c & 2) >> 1, (c & 4) >> 1) - camera_position, camera_direction)); - } - b.camera_distance = dist; + b.camera_separation = cg::separation(camera_frustum, cg::box{b.bbox}).second; b.contains_near_clip = true; for (int i = 0; i < 4; ++i) - b.contains_near_clip &= geom::contains(b.bbox, camera_frustum_vertices[i]); + b.contains_near_clip &= geom::contains(b.bbox, camera_frustum.vertices[i]); for (auto & p : b.buckets) { @@ -1078,7 +1063,7 @@ void main() { auto const & b = bins.data()[bi]; - if (clip_by_camera && b.camera_distance < 0.f) continue; + if (clip_by_camera && b.camera_separation > 0.f) continue; bool const bin_use_occlusion = clip_by_camera && !b.contains_near_clip && !b.buckets.empty() && use_occlusion; @@ -1248,7 +1233,7 @@ void main() if (b.buckets.empty()) continue; if (b.contains_near_clip) continue; - if (b.camera_distance < 0.f) continue; + if (b.camera_separation > 0.f) continue; impl().occlusion_pass_program["u_box_min"] = geom::vector{b.bbox[0].min, b.bbox[1].min, b.bbox[2].min}; impl().occlusion_pass_program["u_box_max"] = geom::vector{b.bbox[0].max, b.bbox[1].max, b.bbox[2].max};