Merge pull request #110550 from WesleyClements/master

Fix `TileMapLayer` tiles displaying incorrectly with y_sort based on visibility layer
This commit is contained in:
Thaddeus Crews 2025-09-23 12:08:50 -05:00
commit 75f0f3dc55
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
2 changed files with 52 additions and 42 deletions

View file

@ -107,11 +107,12 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas
} }
} }
void RendererCanvasCull::_collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int p_z) { void RendererCanvasCull::_collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int &r_ysort_children_count, int p_z, uint32_t p_canvas_cull_mask) {
int child_item_count = p_canvas_item->child_items.size(); int child_item_count = p_canvas_item->child_items.size();
RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw(); RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw();
for (int i = 0; i < child_item_count; i++) { for (int i = 0; i < child_item_count; i++) {
if (child_items[i]->visible) { if (child_items[i]->visible) {
if (child_items[i]->visibility_layer & p_canvas_cull_mask) {
// To y-sort according to the item's final position, physics interpolation // To y-sort according to the item's final position, physics interpolation
// and transform snapping need to be applied before y-sorting. // and transform snapping need to be applied before y-sorting.
Transform2D child_xform; Transform2D child_xform;
@ -150,7 +151,13 @@ void RendererCanvasCull::_collect_ysort_children(RendererCanvasCull::Item *p_can
r_index++; r_index++;
if (child_items[i]->sort_y) { if (child_items[i]->sort_y) {
_collect_ysort_children(child_items[i], child_items[i]->use_parent_material ? p_material_owner : child_items[i], p_modulate * child_items[i]->modulate, r_items, r_index, abs_z); _collect_ysort_children(child_items[i], child_items[i]->use_parent_material ? p_material_owner : child_items[i], p_modulate * child_items[i]->modulate, r_items, r_index, r_ysort_children_count, abs_z, p_canvas_cull_mask);
}
} else {
r_ysort_children_count--;
if (child_items[i]->sort_y) {
r_ysort_children_count -= child_items[i]->ysort_children_count;
}
} }
} }
} }
@ -164,7 +171,10 @@ int RendererCanvasCull::_count_ysort_children(RendererCanvasCull::Item *p_canvas
if (child_items[i]->visible) { if (child_items[i]->visible) {
ysort_children_count++; ysort_children_count++;
if (child_items[i]->sort_y) { if (child_items[i]->sort_y) {
ysort_children_count += _count_ysort_children(child_items[i]); if (child_items[i]->ysort_children_count == -1) {
child_items[i]->ysort_children_count = _count_ysort_children(child_items[i]);
}
ysort_children_count += child_items[i]->ysort_children_count;
} }
} }
} }
@ -439,7 +449,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
ci->ysort_parent_abs_z_index = parent_z; ci->ysort_parent_abs_z_index = parent_z;
child_items[0] = ci; child_items[0] = ci;
int i = 1; int i = 1;
_collect_ysort_children(ci, p_material_owner, Color(1, 1, 1, 1), child_items, i, p_z); _collect_ysort_children(ci, p_material_owner, Color(1, 1, 1, 1), child_items, i, child_item_count, p_z, p_canvas_cull_mask);
SortArray<Item *, ItemYSort> sorter; SortArray<Item *, ItemYSort> sorter;
sorter.sort(child_items, child_item_count); sorter.sort(child_items, child_item_count);

View file

@ -207,7 +207,7 @@ private:
void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info = nullptr); void _render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RendererCanvasRender::Light *p_lights, RendererCanvasRender::Light *p_directional_lights, RS::CanvasItemTextureFilter p_default_filter, RS::CanvasItemTextureRepeat p_default_repeat, bool p_snap_2d_vertices_to_pixel, uint32_t p_canvas_cull_mask, RenderingMethod::RenderInfo *r_render_info = nullptr);
void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_parent_xform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool p_is_already_y_sorted, uint32_t p_canvas_cull_mask, const Point2 &p_repeat_size, int p_repeat_times, RendererCanvasRender::Item *p_repeat_source_item); void _cull_canvas_item(Item *p_canvas_item, const Transform2D &p_parent_xform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RendererCanvasRender::Item **r_z_list, RendererCanvasRender::Item **r_z_last_list, Item *p_canvas_clip, Item *p_material_owner, bool p_is_already_y_sorted, uint32_t p_canvas_cull_mask, const Point2 &p_repeat_size, int p_repeat_times, RendererCanvasRender::Item *p_repeat_source_item);
void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int p_z); void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, RendererCanvasCull::Item *p_material_owner, const Color &p_modulate, RendererCanvasCull::Item **r_items, int &r_index, int &r_ysort_children_count, int p_z, uint32_t p_canvas_cull_mask);
int _count_ysort_children(RendererCanvasCull::Item *p_canvas_item); int _count_ysort_children(RendererCanvasCull::Item *p_canvas_item);
void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner); void _mark_ysort_dirty(RendererCanvasCull::Item *ysort_owner);