From 30801af298dd6b2416c00bab1aa7c6bec49246b8 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Fri, 20 Dec 2024 16:58:02 -0700 Subject: [PATCH] Properly transform light rect and occluder rect to perform light2d culling in canvas space --- drivers/gles3/rasterizer_canvas_gles3.cpp | 2 +- .../rendering/renderer_rd/renderer_canvas_render_rd.cpp | 8 ++++---- servers/rendering/renderer_viewport.cpp | 9 ++++++--- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 210ea7e102b7..d04c9d68d940 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -857,7 +857,7 @@ void RasterizerCanvasGLES3::_record_item_commands(const Item *p_item, RID p_rend Light *light = p_lights; while (light) { - if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { + if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects(light->rect_cache)) { uint32_t light_index = light->render_index_cache; lights[light_count >> 2] |= light_index << ((light_count & 3) * 8); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 3ccfb26c0c0e..b80a10fd4d34 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1035,14 +1035,14 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, while (instance) { OccluderPolygon *co = occluder_polygon_owner.get_or_null(instance->occluder); + occluder_count++; + if (!co || co->index_array.is_null()) { instance = instance->next; continue; } - occluder_count++; - - if (!(p_light_mask & instance->light_mask) || !p_light_rect.intersects(instance->aabb_cache)) { + if (!(p_light_mask & instance->light_mask) || !p_light_rect.intersects_transformed(instance->xform_cache, instance->aabb_cache)) { instance = instance->next; continue; } @@ -2353,7 +2353,7 @@ void RendererCanvasRenderRD::_record_item_commands(const Item *p_item, RenderTar Light *light = p_lights; while (light) { - if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) { + if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects(light->rect_cache)) { uint32_t light_index = light->render_index_cache; lights[light_count >> 2] |= light_index << ((light_count & 3) * 8); diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 342772c40118..a254647c71aa 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -413,7 +413,9 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { cl->xform_cache = xf * cl->xform_cache; } - if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) { + Rect2 temp_rect = cl->xform_cache.xform(cl->rect_cache); + + if (clip_rect.intersects(temp_rect)) { cl->filter_next_ptr = lights; lights = cl; Transform2D scale; @@ -423,12 +425,13 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { if (cl->use_shadow) { cl->shadows_next_ptr = lights_with_shadow; if (lights_with_shadow == nullptr) { - shadow_rect = cl->xform_cache.xform(cl->rect_cache); + shadow_rect = temp_rect; } else { - shadow_rect = shadow_rect.merge(cl->xform_cache.xform(cl->rect_cache)); + shadow_rect = shadow_rect.merge(temp_rect); } lights_with_shadow = cl; cl->radius_cache = cl->rect_cache.size.length(); + cl->rect_cache = temp_rect; } } }