diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 24422c574e8..336cd9ba26e 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -45,20 +45,6 @@ Vector3 Vector3::rotated(const Vector3 &p_axis, real_t p_angle) const { return r; } -Vector3 Vector3::clamp(const Vector3 &p_min, const Vector3 &p_max) const { - return Vector3( - CLAMP(x, p_min.x, p_max.x), - CLAMP(y, p_min.y, p_max.y), - CLAMP(z, p_min.z, p_max.z)); -} - -Vector3 Vector3::clampf(real_t p_min, real_t p_max) const { - return Vector3( - CLAMP(x, p_min, p_max), - CLAMP(y, p_min, p_max), - CLAMP(z, p_min, p_max)); -} - void Vector3::snap(const Vector3 &p_step) { x = Math::snapped(x, p_step.x); y = Math::snapped(y, p_step.y); diff --git a/core/math/vector3.h b/core/math/vector3.h index f6809217184..0ebab7a3a90 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -106,6 +106,20 @@ struct [[nodiscard]] Vector3 { return Vector3(MAX(x, p_scalar), MAX(y, p_scalar), MAX(z, p_scalar)); } + Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const { + return Vector3( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y), + CLAMP(z, p_min.z, p_max.z)); + } + + Vector3 clampf(real_t p_min, real_t p_max) const { + return Vector3( + CLAMP(x, p_min, p_max), + CLAMP(y, p_min, p_max), + CLAMP(z, p_min, p_max)); + } + _FORCE_INLINE_ real_t length() const; _FORCE_INLINE_ real_t length_squared() const; @@ -151,8 +165,6 @@ struct [[nodiscard]] Vector3 { _FORCE_INLINE_ Vector3 sign() const; _FORCE_INLINE_ Vector3 ceil() const; _FORCE_INLINE_ Vector3 round() const; - Vector3 clamp(const Vector3 &p_min, const Vector3 &p_max) const; - Vector3 clampf(real_t p_min, real_t p_max) const; _FORCE_INLINE_ real_t distance_to(const Vector3 &p_to) const; _FORCE_INLINE_ real_t distance_squared_to(const Vector3 &p_to) const; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 0c84348b699..a7f2ff4025c 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -2824,6 +2824,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul Transform3D inv_cam_transform = cull_data.cam_transform.inverse(); float z_near = cull_data.camera_matrix->get_z_near(); + bool is_orthogonal = cull_data.camera_matrix->is_orthogonal(); for (uint64_t i = p_from; i < p_to; i++) { bool mesh_visible = false; @@ -2838,7 +2839,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul #define VIS_RANGE_CHECK ((idata.visibility_index == -1) || _visibility_range_check(cull_data.scenario->instance_visibility[idata.visibility_index], cull_data.cam_transform.origin, cull_data.visibility_viewport_mask) == 0) #define VIS_PARENT_CHECK (_visibility_parent_check(cull_data, idata)) #define VIS_CHECK (visibility_check < 0 ? (visibility_check = (visibility_flags != InstanceData::FLAG_VISIBILITY_DEPENDENCY_NEEDS_CHECK || (VIS_RANGE_CHECK && VIS_PARENT_CHECK))) : visibility_check) -#define OCCLUSION_CULLED (cull_data.occlusion_buffer != nullptr && (cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_OCCLUSION_CULLING) == 0 && cull_data.occlusion_buffer->is_occluded(cull_data.scenario->instance_aabbs[i].bounds, cull_data.cam_transform.origin, inv_cam_transform, *cull_data.camera_matrix, z_near, cull_data.scenario->instance_data[i].occlusion_timeout)) +#define OCCLUSION_CULLED (cull_data.occlusion_buffer != nullptr && (cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_OCCLUSION_CULLING) == 0 && cull_data.occlusion_buffer->is_occluded(cull_data.scenario->instance_aabbs[i].bounds, cull_data.cam_transform.origin, inv_cam_transform, *cull_data.camera_matrix, z_near, is_orthogonal, cull_data.scenario->instance_data[i].occlusion_timeout)) if (!HIDDEN_BY_VISIBILITY_CHECKS) { if ((LAYER_CHECK && IN_FRUSTUM(cull_data.cull->frustum) && VIS_CHECK && !OCCLUSION_CULLED) || (cull_data.scenario->instance_data[i].flags & InstanceData::FLAG_IGNORE_ALL_CULLING)) { diff --git a/servers/rendering/renderer_scene_occlusion_cull.cpp b/servers/rendering/renderer_scene_occlusion_cull.cpp index 89fe6671a33..6f9f4bf907f 100644 --- a/servers/rendering/renderer_scene_occlusion_cull.cpp +++ b/servers/rendering/renderer_scene_occlusion_cull.cpp @@ -32,23 +32,8 @@ RendererSceneOcclusionCull *RendererSceneOcclusionCull::singleton = nullptr; -const Vector3 RendererSceneOcclusionCull::HZBuffer::corners[8] = { - Vector3(0, 0, 0), - Vector3(0, 0, 1), - Vector3(0, 1, 0), - Vector3(0, 1, 1), - Vector3(1, 0, 0), - Vector3(1, 0, 1), - Vector3(1, 1, 0), - Vector3(1, 1, 1) -}; - bool RendererSceneOcclusionCull::HZBuffer::occlusion_jitter_enabled = false; -bool RendererSceneOcclusionCull::HZBuffer::is_empty() const { - return sizes.is_empty(); -} - void RendererSceneOcclusionCull::HZBuffer::clear() { if (sizes.is_empty()) { return; // Already cleared diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h index 48965446f43..749d5160a38 100644 --- a/servers/rendering/renderer_scene_occlusion_cull.h +++ b/servers/rendering/renderer_scene_occlusion_cull.h @@ -41,8 +41,6 @@ protected: public: class HZBuffer { protected: - static const Vector3 corners[8]; - LocalVector data; LocalVector sizes; LocalVector mips; @@ -55,7 +53,7 @@ public: uint64_t occlusion_frame = 0; Size2i occlusion_buffer_size; - _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 { + _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 { if (is_empty()) { return false; } @@ -79,27 +77,27 @@ public: Vector2 rect_max = Vector2(FLT_MIN, FLT_MIN); for (int j = 0; j < 8; j++) { - const Vector3 &c = RendererSceneOcclusionCull::HZBuffer::corners[j]; - Vector3 nc = Vector3(1, 1, 1) - c; - 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); + // Bitmask to cycle through the corners of the AABB. + Vector3 corner = Vector3( + j & 4 ? p_bounds[0] : p_bounds[3], + j & 2 ? p_bounds[1] : p_bounds[4], + j & 1 ? p_bounds[2] : p_bounds[5]); Vector3 view = p_cam_inv_transform.xform(corner); // When using an orthogonal camera, the closest point of an AABB to the camera is guaranteed to be a corner. - if (p_cam_projection.is_orthogonal()) { + if (p_is_orthogonal) { min_depth = MIN(min_depth, -view.z); } - Plane vp = Plane(view, 1.0); - Plane projected = p_cam_projection.xform4(vp); + Vector3 projected = p_cam_projection.xform(view); - float w = projected.d; - if (w < 1.0) { + if (-view.z < 0.0) { rect_min = Vector2(0.0f, 0.0f); rect_max = Vector2(1.0f, 1.0f); break; } - Vector2 normalized = Vector2(projected.normal.x / w * 0.5f + 0.5f, projected.normal.y / w * 0.5f + 0.5f); + Vector2 normalized = Vector2(projected.x * 0.5f + 0.5f, projected.y * 0.5f + 0.5f); rect_min = rect_min.min(normalized); rect_max = rect_max.max(normalized); } @@ -159,7 +157,10 @@ public: public: static bool occlusion_jitter_enabled; - bool is_empty() const; + _FORCE_INLINE_ bool is_empty() const { + return sizes.is_empty(); + } + virtual void clear(); virtual void resize(const Size2i &p_size); @@ -168,8 +169,8 @@ public: // Thin wrapper around _is_occluded(), // allowing occlusion timers to delay the disappearance // of objects to prevent flickering when using jittering. - _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 { - bool occluded = _is_occluded(p_bounds, p_cam_position, p_cam_inv_transform, p_cam_projection, p_near); + _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 { + bool occluded = _is_occluded(p_bounds, p_cam_position, p_cam_inv_transform, p_cam_projection, p_near, p_is_orthogonal); // Special case, temporal jitter disabled, // so we don't use occlusion timers.