@@ -41,8 +41,6 @@ class RendererSceneOcclusionCull {
4141public:
4242 class HZBuffer {
4343 protected:
44- static const Vector3 corners[8 ];
45-
4644 LocalVector<float > data;
4745 LocalVector<Size2i> sizes;
4846 LocalVector<float *> mips;
@@ -55,7 +53,7 @@ class RendererSceneOcclusionCull {
5553 uint64_t occlusion_frame = 0 ;
5654 Size2i occlusion_buffer_size;
5755
58- _FORCE_INLINE_ bool _is_occluded (const real_t p_bounds[6 ], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const Projection &p_cam_projection, real_t p_near) const {
56+ _FORCE_INLINE_ bool _is_occluded (const real_t p_bounds[6 ], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const Projection &p_cam_projection, real_t p_near, bool p_is_orthogonal ) const {
5957 if (is_empty ()) {
6058 return false ;
6159 }
@@ -79,27 +77,27 @@ class RendererSceneOcclusionCull {
7977 Vector2 rect_max = Vector2 (FLT_MIN, FLT_MIN);
8078
8179 for (int j = 0 ; j < 8 ; j++) {
82- const Vector3 &c = RendererSceneOcclusionCull::HZBuffer::corners[j];
83- Vector3 nc = Vector3 (1 , 1 , 1 ) - c;
84- Vector3 corner = Vector3 (p_bounds[0 ] * c.x + p_bounds[3 ] * nc.x , p_bounds[1 ] * c.y + p_bounds[4 ] * nc.y , p_bounds[2 ] * c.z + p_bounds[5 ] * nc.z );
80+ // Bitmask to cycle through the corners of the AABB.
81+ Vector3 corner = Vector3 (
82+ j & 4 ? p_bounds[0 ] : p_bounds[3 ],
83+ j & 2 ? p_bounds[1 ] : p_bounds[4 ],
84+ j & 1 ? p_bounds[2 ] : p_bounds[5 ]);
8585 Vector3 view = p_cam_inv_transform.xform (corner);
8686
8787 // When using an orthogonal camera, the closest point of an AABB to the camera is guaranteed to be a corner.
88- if (p_cam_projection. is_orthogonal () ) {
88+ if (p_is_orthogonal ) {
8989 min_depth = MIN (min_depth, -view.z );
9090 }
9191
92- Plane vp = Plane (view, 1.0 );
93- Plane projected = p_cam_projection.xform4 (vp);
92+ Vector3 projected = p_cam_projection.xform (view);
9493
95- float w = projected.d ;
96- if (w < 1.0 ) {
94+ if (-view.z < 0.0 ) {
9795 rect_min = Vector2 (0 .0f , 0 .0f );
9896 rect_max = Vector2 (1 .0f , 1 .0f );
9997 break ;
10098 }
10199
102- Vector2 normalized = Vector2 (projected.normal . x / w * 0 .5f + 0 .5f , projected.normal . y / w * 0 .5f + 0 .5f );
100+ Vector2 normalized = Vector2 (projected.x * 0 .5f + 0 .5f , projected.y * 0 .5f + 0 .5f );
103101 rect_min = rect_min.min (normalized);
104102 rect_max = rect_max.max (normalized);
105103 }
@@ -159,7 +157,10 @@ class RendererSceneOcclusionCull {
159157 public:
160158 static bool occlusion_jitter_enabled;
161159
162- bool is_empty () const ;
160+ _FORCE_INLINE_ bool is_empty () const {
161+ return sizes.is_empty ();
162+ }
163+
163164 virtual void clear ();
164165 virtual void resize (const Size2i &p_size);
165166
@@ -168,8 +169,8 @@ class RendererSceneOcclusionCull {
168169 // Thin wrapper around _is_occluded(),
169170 // allowing occlusion timers to delay the disappearance
170171 // of objects to prevent flickering when using jittering.
171- _FORCE_INLINE_ bool is_occluded (const real_t p_bounds[6 ], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const Projection &p_cam_projection, real_t p_near, uint64_t &r_occlusion_timeout) const {
172- bool occluded = _is_occluded (p_bounds, p_cam_position, p_cam_inv_transform, p_cam_projection, p_near);
172+ _FORCE_INLINE_ bool is_occluded (const real_t p_bounds[6 ], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const Projection &p_cam_projection, real_t p_near, bool p_is_orthogonal, uint64_t &r_occlusion_timeout) const {
173+ bool occluded = _is_occluded (p_bounds, p_cam_position, p_cam_inv_transform, p_cam_projection, p_near, p_is_orthogonal );
173174
174175 // Special case, temporal jitter disabled,
175176 // so we don't use occlusion timers.
0 commit comments