@@ -107,50 +107,57 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas
107107 }
108108}
109109
110- 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) {
110+ 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 ) {
111111 int child_item_count = p_canvas_item->child_items .size ();
112112 RendererCanvasCull::Item **child_items = p_canvas_item->child_items .ptrw ();
113113 for (int i = 0 ; i < child_item_count; i++) {
114114 if (child_items[i]->visible ) {
115- // To y-sort according to the item's final position, physics interpolation
116- // and transform snapping need to be applied before y-sorting.
117- Transform2D child_xform;
118- if (!_interpolation_data.interpolation_enabled || !child_items[i]->interpolated ) {
119- child_xform = child_items[i]->xform_curr ;
120- } else {
121- real_t f = Engine::get_singleton ()->get_physics_interpolation_fraction ();
122- TransformInterpolator::interpolate_transform_2d (child_items[i]->xform_prev , child_items[i]->xform_curr , child_xform, f);
123- }
115+ if (child_items[i]->visibility_layer & p_canvas_cull_mask) {
116+ // To y-sort according to the item's final position, physics interpolation
117+ // and transform snapping need to be applied before y-sorting.
118+ Transform2D child_xform;
119+ if (!_interpolation_data.interpolation_enabled || !child_items[i]->interpolated ) {
120+ child_xform = child_items[i]->xform_curr ;
121+ } else {
122+ real_t f = Engine::get_singleton ()->get_physics_interpolation_fraction ();
123+ TransformInterpolator::interpolate_transform_2d (child_items[i]->xform_prev , child_items[i]->xform_curr , child_xform, f);
124+ }
124125
125- if (snapping_2d_transforms_to_pixel) {
126- child_xform.columns [2 ] = (child_xform.columns [2 ] + Point2 (0.5 , 0.5 )).floor ();
127- }
126+ if (snapping_2d_transforms_to_pixel) {
127+ child_xform.columns [2 ] = (child_xform.columns [2 ] + Point2 (0.5 , 0.5 )).floor ();
128+ }
128129
129- r_items[r_index] = child_items[i];
130- child_items[i]->ysort_xform = p_canvas_item->ysort_xform * child_xform;
131- child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr ;
132- child_items[i]->ysort_modulate = p_modulate;
133- child_items[i]->ysort_index = r_index;
134- child_items[i]->ysort_parent_abs_z_index = p_z;
135-
136- if (!child_items[i]->repeat_source ) {
137- child_items[i]->repeat_size = p_canvas_item->repeat_size ;
138- child_items[i]->repeat_times = p_canvas_item->repeat_times ;
139- child_items[i]->repeat_source_item = p_canvas_item->repeat_source_item ;
140- }
130+ r_items[r_index] = child_items[i];
131+ child_items[i]->ysort_xform = p_canvas_item->ysort_xform * child_xform;
132+ child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr ;
133+ child_items[i]->ysort_modulate = p_modulate;
134+ child_items[i]->ysort_index = r_index;
135+ child_items[i]->ysort_parent_abs_z_index = p_z;
136+
137+ if (!child_items[i]->repeat_source ) {
138+ child_items[i]->repeat_size = p_canvas_item->repeat_size ;
139+ child_items[i]->repeat_times = p_canvas_item->repeat_times ;
140+ child_items[i]->repeat_source_item = p_canvas_item->repeat_source_item ;
141+ }
141142
142- // Y sorted canvas items are flattened into r_items. Calculate their absolute z index to use when rendering r_items.
143- int abs_z = 0 ;
144- if (child_items[i]->z_relative ) {
145- abs_z = CLAMP (p_z + child_items[i]->z_index , RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
146- } else {
147- abs_z = child_items[i]->z_index ;
148- }
143+ // Y sorted canvas items are flattened into r_items. Calculate their absolute z index to use when rendering r_items.
144+ int abs_z = 0 ;
145+ if (child_items[i]->z_relative ) {
146+ abs_z = CLAMP (p_z + child_items[i]->z_index , RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
147+ } else {
148+ abs_z = child_items[i]->z_index ;
149+ }
149150
150- r_index++;
151+ r_index++;
151152
152- if (child_items[i]->sort_y ) {
153- _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);
153+ if (child_items[i]->sort_y ) {
154+ _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);
155+ }
156+ } else {
157+ r_ysort_children_count--;
158+ if (child_items[i]->sort_y ) {
159+ r_ysort_children_count -= child_items[i]->ysort_children_count ;
160+ }
154161 }
155162 }
156163 }
@@ -164,7 +171,10 @@ int RendererCanvasCull::_count_ysort_children(RendererCanvasCull::Item *p_canvas
164171 if (child_items[i]->visible ) {
165172 ysort_children_count++;
166173 if (child_items[i]->sort_y ) {
167- ysort_children_count += _count_ysort_children (child_items[i]);
174+ if (child_items[i]->ysort_children_count == -1 ) {
175+ child_items[i]->ysort_children_count = _count_ysort_children (child_items[i]);
176+ }
177+ ysort_children_count += child_items[i]->ysort_children_count ;
168178 }
169179 }
170180 }
@@ -439,7 +449,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
439449 ci->ysort_parent_abs_z_index = parent_z;
440450 child_items[0 ] = ci;
441451 int i = 1 ;
442- _collect_ysort_children (ci, p_material_owner, Color (1 , 1 , 1 , 1 ), child_items, i, p_z);
452+ _collect_ysort_children (ci, p_material_owner, Color (1 , 1 , 1 , 1 ), child_items, i, child_item_count, p_z, p_canvas_cull_mask );
443453
444454 SortArray<Item *, ItemYSort> sorter;
445455 sorter.sort (child_items, child_item_count);
0 commit comments