Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2022-08-27 11:38:42 +0300
committerClément Foucault <foucault.clem@gmail.com>2022-08-27 11:38:42 +0300
commit019173321422c5a546df8ca7496a9280b478043d (patch)
treeadeddbffdf66eae1ba03321bdd3f75b556aa4042
parent6868988a1e409f7fc26e9f5c0b025ec609aa474a (diff)
Improve culling using inscribed sphere
-rw-r--r--source/blender/draw/intern/shaders/draw_resource_finalize_comp.glsl14
-rw-r--r--source/blender/draw/intern/shaders/draw_visibility_comp.glsl23
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