Deferred renderer: add proper frustum culling
This commit is contained in:
parent
59888bd5eb
commit
0cf44f532a
1 changed files with 9 additions and 24 deletions
|
|
@ -20,6 +20,9 @@
|
|||
#include <psemek/geom/contains.hpp>
|
||||
|
||||
#include <psemek/cg/convex_hull_2d/graham.hpp>
|
||||
#include <psemek/cg/body/frustum.hpp>
|
||||
#include <psemek/cg/body/box.hpp>
|
||||
#include <psemek/cg/convex/separation.hpp>
|
||||
|
||||
#include <psemek/util/to_string.hpp>
|
||||
#include <psemek/util/hash.hpp>
|
||||
|
|
@ -966,20 +969,7 @@ void main()
|
|||
auto const camera_position = opts.camera->position();
|
||||
auto const camera_direction = opts.camera->direction();
|
||||
|
||||
geom::point<float, 3> camera_frustum_vertices[8];
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
geom::vector<float, 4> 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<float, 3> camera_frustum(camera_transform);
|
||||
|
||||
// Sort objects by mask & compute bbox
|
||||
|
||||
|
|
@ -994,7 +984,7 @@ void main()
|
|||
std::unordered_map<std::tuple<std::uint32_t, material const *>, objects_bucket> buckets;
|
||||
geom::box<float, 3> bbox;
|
||||
bool contains_near_clip = false;
|
||||
float camera_distance = -std::numeric_limits<float>::infinity();
|
||||
float camera_separation;
|
||||
};
|
||||
|
||||
geom::box<float, 3> all_bbox;
|
||||
|
|
@ -1052,16 +1042,11 @@ void main()
|
|||
{
|
||||
b.bbox = geom::expand(b.bbox, b.bbox.dimensions() / 64.f);
|
||||
|
||||
float dist = -std::numeric_limits<float>::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};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue