diff options
author | Robbie Cooper <cooperra@users.noreply.github.com> | 2022-10-08 05:33:47 -0400 |
---|---|---|
committer | Robbie Cooper <cooperra@users.noreply.github.com> | 2022-10-10 03:20:59 -0400 |
commit | 79d3e090cd7752e37aabf1efe185bcd543ec5f5a (patch) | |
tree | d2ade1e90bc6138f7db6df97461132b9d0954ede /servers | |
parent | ca25c6e0a3f25948ee4a197f3442c66f019e7424 (diff) |
Vulkan Clustered: Fix culling of negatively-scaled objects
Negatively scaled objects should be mirrored. This is already implemented, but it breaks when mirrored and non-mirrored instances of the same object are visible together.
It turns out that the code that skips-over repeats in `RenderForwardClustered::_render_list_template` also skips the code that accounts for the culling mode of mirrored objects.
The solution here is to consider the `mirror` flag when determining repeats. This might result in more draw commands than necessary since a mirrored object can split a group of non-mirrored instances in two.
This problem doesn't appear in the mobile renderer because the repeat optimization isn't implemented there yet.
The problem still appears in MultiMeshInstance3D in *all* renderers.
Fixes #62879 and #58546.
Diffstat (limited to 'servers')
-rw-r--r-- | servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 84d2ad328c..039a2d2bf4 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -754,7 +754,7 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i bool cant_repeat = instance_data.flags & INSTANCE_DATA_FLAG_MULTIMESH || inst->mesh_instance.is_valid(); - if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2 && repeats < RenderElementInfo::MAX_REPEATS) { + if (prev_surface != nullptr && !cant_repeat && prev_surface->sort.sort_key1 == surface->sort.sort_key1 && prev_surface->sort.sort_key2 == surface->sort.sort_key2 && inst->mirror == prev_surface->owner->mirror && repeats < RenderElementInfo::MAX_REPEATS) { //this element is the same as the previous one, count repeats to draw it using instancing repeats++; } else { |