Commit: b82f7814c4f386c05215d7dc85d526fa10e2b4e1 Author: Miguel Pozo Date: Mon Jan 16 18:41:06 2023 +0100 Branches: master https://developer.blender.org/rBb82f7814c4f386c05215d7dc85d526fa10e2b4e1
Fix: Draw: Incorrect culling in the new Draw Manager ViewCullingData::corners (vec4) was casted to a BoundingBox (vec3), so the frustum corners were uploaded in the wrong format to the GPU. Now the ViewCullingData::corners are used directly without casting, since the BoundBox API is not really needed. Reviewed By: fclem Differential Revision: https://developer.blender.org/D17008 =================================================================== M source/blender/draw/intern/draw_view.cc M source/blender/draw/intern/draw_view.hh =================================================================== diff --git a/source/blender/draw/intern/draw_view.cc b/source/blender/draw/intern/draw_view.cc index 2e303aa9295..82f614f20f2 100644 --- a/source/blender/draw/intern/draw_view.cc +++ b/source/blender/draw/intern/draw_view.cc @@ -24,16 +24,14 @@ void View::sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id) is_inverted_ = (is_negative_m4(view_mat.ptr()) == is_negative_m4(win_mat.ptr())); - BoundBox &bound_box = *reinterpret_cast<BoundBox *>(&culling_[view_id].corners); - BoundSphere &bound_sphere = *reinterpret_cast<BoundSphere *>(&culling_[view_id].bound_sphere); - frustum_boundbox_calc(bound_box, view_id); + frustum_boundbox_calc(view_id); frustum_culling_planes_calc(view_id); - frustum_culling_sphere_calc(bound_box, bound_sphere, view_id); + frustum_culling_sphere_calc(view_id); dirty_ = true; } -void View::frustum_boundbox_calc(BoundBox &bbox, int view_id) +void View::frustum_boundbox_calc(int view_id) { /* Extract the 8 corners from a Projection Matrix. */ #if 0 /* Equivalent to this but it has accuracy problems. */ @@ -43,16 +41,18 @@ void View::frustum_boundbox_calc(BoundBox &bbox, int view_id) } #endif + MutableSpan<float4> corners = {culling_[view_id].corners, ARRAY_SIZE(culling_[view_id].corners)}; + float left, right, bottom, top, near, far; bool is_persp = data_[view_id].winmat[3][3] == 0.0f; projmat_dimensions(data_[view_id].winmat.ptr(), &left, &right, &bottom, &top, &near, &far); - bbox.vec[0][2] = bbox.vec[3][2] = bbox.vec[7][2] = bbox.vec[4][2] = -near; - bbox.vec[0][0] = bbox.vec[3][0] = left; - bbox.vec[4][0] = bbox.vec[7][0] = right; - bbox.vec[0][1] = bbox.vec[4][1] = bottom; - bbox.vec[7][1] = bbox.vec[3][1] = top; + corners[0][2] = corners[3][2] = corners[7][2] = corners[4][2] = -near; + corners[0][0] = corners[3][0] = left; + corners[4][0] = corners[7][0] = right; + corners[0][1] = corners[4][1] = bottom; + corners[7][1] = corners[3][1] = top; /* Get the coordinates of the far plane. */ if (is_persp) { @@ -63,15 +63,16 @@ void View::frustum_boundbox_calc(BoundBox &bbox, int view_id) top *= sca_far; } - bbox.vec[1][2] = bbox.vec[2][2] = bbox.vec[6][2] = bbox.vec[5][2] = -far; - bbox.vec[1][0] = bbox.vec[2][0] = left; - bbox.vec[6][0] = bbox.vec[5][0] = right; - bbox.vec[1][1] = bbox.vec[5][1] = bottom; - bbox.vec[2][1] = bbox.vec[6][1] = top; + corners[1][2] = corners[2][2] = corners[6][2] = corners[5][2] = -far; + corners[1][0] = corners[2][0] = left; + corners[6][0] = corners[5][0] = right; + corners[1][1] = corners[5][1] = bottom; + corners[2][1] = corners[6][1] = top; /* Transform into world space. */ - for (int i = 0; i < 8; i++) { - mul_m4_v3(data_[view_id].viewinv.ptr(), bbox.vec[i]); + for (float4 &corner : corners) { + mul_m4_v3(data_[view_id].viewinv.ptr(), corner); + corner.w = 1.0; } } @@ -87,19 +88,22 @@ void View::frustum_culling_planes_calc(int view_id) culling_[view_id].planes[2]); /* Normalize. */ - for (int p = 0; p < 6; p++) { - culling_[view_id].planes[p].w /= normalize_v3(culling_[view_id].planes[p]); + for (float4 &plane : culling_[view_id].planes) { + plane.w /= normalize_v3(plane); } } -void View::frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bsphere, int view_id) +void View::frustum_culling_sphere_calc(int view_id) { + BoundSphere &bsphere = *reinterpret_cast<BoundSphere *>(&culling_[view_id].bound_sphere); + Span<float4> corners = {culling_[view_id].corners, ARRAY_SIZE(culling_[view_id].corners)}; + /* Extract Bounding Sphere */ if (data_[view_id].winmat[3][3] != 0.0f) { /* Orthographic */ /* The most extreme points on the near and far plane. (normalized device coords). */ - const float *nearpoint = bbox.vec[0]; - const float *farpoint = bbox.vec[6]; + const float *nearpoint = corners[0]; + const float *farpoint = corners[6]; /* just use median point */ mid_v3_v3v3(bsphere.center, farpoint, nearpoint); @@ -113,12 +117,12 @@ void View::frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bspher /* center of each clipping plane */ float mid_min[3], mid_max[3]; - mid_v3_v3v3(mid_min, bbox.vec[3], bbox.vec[4]); - mid_v3_v3v3(mid_max, bbox.vec[2], bbox.vec[5]); + mid_v3_v3v3(mid_min, corners[3], corners[4]); + mid_v3_v3v3(mid_max, corners[2], corners[5]); /* square length of the diagonals of each clipping plane */ - float a_sq = len_squared_v3v3(bbox.vec[3], bbox.vec[4]); - float b_sq = len_squared_v3v3(bbox.vec[2], bbox.vec[5]); + float a_sq = len_squared_v3v3(corners[3], corners[4]); + float b_sq = len_squared_v3v3(corners[2], corners[5]); /* distance squared between clipping planes */ float h_sq = len_squared_v3v3(mid_min, mid_max); @@ -132,7 +136,7 @@ void View::frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bspher interp_v3_v3v3(bsphere.center, mid_min, mid_max, fac); /* distance from the center to one of the points of the far plane (1, 2, 5, 6) */ - bsphere.radius = len_v3v3(bsphere.center, bbox.vec[1]); + bsphere.radius = len_v3v3(bsphere.center, corners[1]); } else { /* Perspective with asymmetrical frustum. */ diff --git a/source/blender/draw/intern/draw_view.hh b/source/blender/draw/intern/draw_view.hh index cded44e5a56..3a3191e2a62 100644 --- a/source/blender/draw/intern/draw_view.hh +++ b/source/blender/draw/intern/draw_view.hh @@ -139,9 +139,10 @@ class View { void update_viewport_size(); - void frustum_boundbox_calc(BoundBox &bbox, int view_id); + /* WARNING: These 3 functions must be called in order */ + void frustum_boundbox_calc(int view_id); void frustum_culling_planes_calc(int view_id); - void frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bsphere, int view_id); + void frustum_culling_sphere_calc(int view_id); }; } // namespace blender::draw _______________________________________________ Bf-blender-cvs mailing list [email protected] List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs
