diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2022-08-27 11:38:42 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2022-08-27 11:38:42 +0300 |
commit | 019173321422c5a546df8ca7496a9280b478043d (patch) | |
tree | adeddbffdf66eae1ba03321bdd3f75b556aa4042 | |
parent | 6868988a1e409f7fc26e9f5c0b025ec609aa474a (diff) |
Improve culling using inscribed sphere
-rw-r--r-- | source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl | 14 | ||||
-rw-r--r-- | source/blender/draw/intern/shaders/draw_visibility_comp.glsl | 23 |
2 files changed, 31 insertions, 6 deletions
diff --git a/source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl b/source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl index 1f8af429ce9..70fe645c128 100644 --- a/source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl +++ b/source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl @@ -13,8 +13,9 @@ void main() } mat4 model_mat = matrix_buf[resource_id].model; - + ObjectInfos infos = infos_buf[resource_id]; ObjectBounds bounds = bounds_buf[resource_id]; + if (bounds.bounding_sphere.w != -1.0) { /* Convert corners to origin + sides in world space. */ vec3 p0 = bounds.bounding_corners[0].xyz; @@ -23,21 +24,30 @@ void main() vec3 p03 = bounds.bounding_corners[3].xyz - p0; vec3 diagonal = p01 + p02 + p03; vec3 center = p0 + diagonal * 0.5; + float min_axis = min_v3(abs(diagonal)); bounds_buf[resource_id].bounding_sphere.xyz = transform_point(model_mat, center); /* We have to apply scaling to the diagonal. */ bounds_buf[resource_id].bounding_sphere.w = length(transform_direction(model_mat, diagonal)) * 0.5; + bounds_buf[resource_id]._inner_sphere_radius = min_axis; bounds_buf[resource_id].bounding_corners[0].xyz = transform_point(model_mat, p0); bounds_buf[resource_id].bounding_corners[1].xyz = transform_direction(model_mat, p01); bounds_buf[resource_id].bounding_corners[2].xyz = transform_direction(model_mat, p02); bounds_buf[resource_id].bounding_corners[3].xyz = transform_direction(model_mat, p03); + /* Always have correct handedness in the corners vectors. */ + if (flag_test(infos.flag, OBJECT_NEGATIVE_SCALE)) { + bounds_buf[resource_id].bounding_corners[0].xyz += + bounds_buf[resource_id].bounding_corners[1].xyz; + bounds_buf[resource_id].bounding_corners[1].xyz = + -bounds_buf[resource_id].bounding_corners[1].xyz; + } + /* TODO: Bypass test for very large objects (see T67319). */ if (bounds_buf[resource_id].bounding_sphere.w > 1e12) { bounds_buf[resource_id].bounding_sphere.w = -1.0; } } - ObjectInfos infos = infos_buf[resource_id]; vec3 loc = infos.orco_add; /* Box center. */ vec3 size = infos.orco_mul; /* Box half-extent. */ /* This is what the original computation looks like. diff --git a/source/blender/draw/intern/shaders/draw_visibility_comp.glsl b/source/blender/draw/intern/shaders/draw_visibility_comp.glsl index 84b11e3a442..7ec58c8f919 100644 --- a/source/blender/draw/intern/shaders/draw_visibility_comp.glsl +++ b/source/blender/draw/intern/shaders/draw_visibility_comp.glsl @@ -6,10 +6,15 @@ #pragma BLENDER_REQUIRE(common_math_lib.glsl) #pragma BLENDER_REQUIRE(common_intersect_lib.glsl) -#pragma BLENDER_REQUIRE(common_debug_print_lib.glsl) shared uint shared_result; +void mask_visibility_bit() +{ + uint bit = 1u << gl_LocalInvocationID.x; + atomicAnd(visibility_buf[gl_WorkGroupID.x], ~bit); +} + void main() { if (gl_GlobalInvocationID.x >= resource_len) { @@ -23,9 +28,19 @@ void main() bounds.bounding_corners[1].xyz, bounds.bounding_corners[2].xyz, bounds.bounding_corners[3].xyz); - if (intersect_view(box) == false) { - uint bit = 1u << gl_LocalInvocationID.x; - atomicAnd(visibility_buf[gl_WorkGroupID.x], ~bit); + Sphere bounding_sphere = Sphere(bounds.bounding_sphere.xyz, bounds.bounding_sphere.w); + Sphere inscribed_sphere = Sphere(bounds.bounding_sphere.xyz, bounds._inner_sphere_radius); + + if (intersect_view(inscribed_sphere) == true) { + /* Visible. */ + } + else if (intersect_view(bounding_sphere) == false) { + /* Not visible. */ + mask_visibility_bit(); + } + else if (intersect_view(box) == false) { + /* Not visible. */ + mask_visibility_bit(); } } }
\ No newline at end of file |