mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
ifcviewer: disable HiZ cull when camera has moved
HiZ from last frame encodes depth from last frame's viewpoint. When the camera moves, projecting a current-frame AABB through the stored VP answers 'was this occluded last frame?' rather than 'is it occluded now?' — a self-reinforcing feedback loop where objects culled in prior frames never appear in any depth buffer and stay permanently hidden at certain camera angles. Fix: require hiz_vp_ == current VP for the HiZ test to apply. HiZ still helps static views (kicks in one frame after camera stops) but no longer produces false occlusions during orbit. The correct fix for orbit coverage is a depth pre-pass feeding fresh HiZ — planned as part of Phase 3E GPU compute cull. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1388,7 +1388,21 @@ void ViewportWindow::cullModelCpu(ModelGpuData& m, const float planes[6][4],
|
||||
// HiZ occlusion is skipped entirely when the pick pass runs
|
||||
// (min_pixel_radius == 0 on that path), when the user disables it via
|
||||
// env var, or before the first pyramid has been built.
|
||||
const bool hiz_on = hizEnabled() && min_pixel_radius > 0.0f && hiz_vp_valid_;
|
||||
//
|
||||
// Crucially, HiZ is also skipped when the stored VP (hiz_vp_, captured at
|
||||
// the end of the previous frame) differs from this frame's VP — i.e.
|
||||
// whenever the camera has moved. The stored depth buffer encodes what
|
||||
// was visible from hiz_vp_'s viewpoint; projecting a current-frame AABB
|
||||
// through that VP answers "was this occluded LAST frame?", which is only
|
||||
// a correct proxy for "is this occluded NOW?" when the camera is static.
|
||||
// Orbiting past a wall would otherwise leave objects persistently culled
|
||||
// because prior frames' depth buffers only ever contained the wall (the
|
||||
// objects behind it were themselves HiZ-culled, never drawn, so never in
|
||||
// the buffer — a self-reinforcing feedback loop). On static views HiZ
|
||||
// kicks in after a single frame of lag.
|
||||
const QMatrix4x4 current_vp = proj_matrix_ * view_matrix_;
|
||||
const bool hiz_vp_matches = hiz_vp_valid_ && hiz_vp_ == current_vp;
|
||||
const bool hiz_on = hizEnabled() && min_pixel_radius > 0.0f && hiz_vp_matches;
|
||||
|
||||
// Hot path: read the AABB from the compact bvh_items array (28 B stride)
|
||||
// rather than the wide InstanceCpu (104 B stride). Most instances fail
|
||||
|
||||
Reference in New Issue
Block a user