diff options
author | Clay John <claynjohn@gmail.com> | 2022-10-27 09:59:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-27 09:59:27 -0700 |
commit | e1caa8797baf55d8f3fbb0b64313c4255228b809 (patch) | |
tree | 50766ce430beb33a2cd3e798b16aa82b752e54c9 /servers/rendering/renderer_rd | |
parent | 2f2c138b4499ef0a070c13e5cc242946a8db155f (diff) | |
parent | b6f44859d7ab5b128d71ce0d64b46b171b9357aa (diff) |
Merge pull request #67043 from clayjohn/clip_children
Improve behaviour of clip_children by clipping to parent alpha value but still retaining parent color
Diffstat (limited to 'servers/rendering/renderer_rd')
3 files changed, 46 insertions, 7 deletions
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp index 53237c1dfb..a14228eb3d 100644 --- a/servers/rendering/renderer_rd/effects/copy_effects.cpp +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -357,8 +357,8 @@ void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, cons copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE; } - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; + copy.push_constant.section[0] = p_rect.position.x; + copy.push_constant.section[1] = p_rect.position.y; copy.push_constant.section[2] = p_rect.size.width; copy.push_constant.section[3] = p_rect.size.height; copy.push_constant.target[0] = p_rect.position.x; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 4cde7406bb..dc0214e307 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1111,8 +1111,20 @@ void RendererCanvasRenderRD::_render_items(RID p_to_render_target, int p_item_co RID material = ci->material_owner == nullptr ? ci->material : ci->material_owner->material; - if (material.is_null() && ci->canvas_group != nullptr) { - material = default_canvas_group_material; + if (ci->canvas_group != nullptr) { + if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { + if (!p_to_backbuffer) { + material = default_clip_children_material; + } + } else { + if (material.is_null()) { + if (ci->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_ONLY) { + material = default_clip_children_material; + } else { + material = default_canvas_group_material; + } + } + } } if (material != prev_material) { @@ -1437,10 +1449,12 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p _render_items(p_to_render_target, item_count, canvas_transform_inverse, p_light_list); item_count = 0; - Rect2i group_rect = ci->canvas_group_owner->global_rect_cache; - - if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_OPAQUE) { + if (ci->canvas_group_owner->canvas_group->mode != RS::CANVAS_GROUP_MODE_TRANSPARENT) { + Rect2i group_rect = ci->canvas_group_owner->global_rect_cache; texture_storage->render_target_copy_to_back_buffer(p_to_render_target, group_rect, false); + if (ci->canvas_group_owner->canvas_group->mode == RS::CANVAS_GROUP_MODE_CLIP_AND_DRAW) { + items[item_count++] = ci->canvas_group_owner; + } } else if (!backbuffer_cleared) { texture_storage->render_target_clear_back_buffer(p_to_render_target, Rect2i(), Color(0, 0, 0, 0)); backbuffer_cleared = true; @@ -2738,6 +2752,26 @@ void fragment() { material_storage->material_set_shader(default_canvas_group_material, default_canvas_group_shader); } + { + default_clip_children_shader = material_storage->shader_allocate(); + material_storage->shader_initialize(default_clip_children_shader); + + material_storage->shader_set_code(default_clip_children_shader, R"( +// Default clip children shader. + +shader_type canvas_item; + +void fragment() { + vec4 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0); + COLOR.rgb = c.rgb; +} +)"); + default_clip_children_material = material_storage->material_allocate(); + material_storage->material_initialize(default_clip_children_material); + + material_storage->material_set_shader(default_clip_children_material, default_clip_children_shader); + } + static_assert(sizeof(PushConstant) == 128); } @@ -2789,6 +2823,9 @@ RendererCanvasRenderRD::~RendererCanvasRenderRD() { material_storage->material_free(default_canvas_group_material); material_storage->shader_free(default_canvas_group_shader); + material_storage->material_free(default_clip_children_material); + material_storage->shader_free(default_clip_children_shader); + { if (state.canvas_state_buffer.is_valid()) { RD::get_singleton()->free(state.canvas_state_buffer); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 67db56d913..4f1f77af5e 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -421,6 +421,8 @@ class RendererCanvasRenderRD : public RendererCanvasRender { RID default_canvas_group_shader; RID default_canvas_group_material; + RID default_clip_children_material; + RID default_clip_children_shader; RS::CanvasItemTextureFilter default_filter = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; RS::CanvasItemTextureRepeat default_repeat = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; |