diff --git a/drivers/gles3/storage/light_storage.h b/drivers/gles3/storage/light_storage.h index 8e6480869b7..0f8120be155 100644 --- a/drivers/gles3/storage/light_storage.h +++ b/drivers/gles3/storage/light_storage.h @@ -287,6 +287,13 @@ public: return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; } + virtual bool light_get_reverse_cull_face_mode(RID p_light) const override { + const Light *light = light_owner.get_or_null(p_light); + ERR_FAIL_COND_V(!light, false); + + return light->reverse_cull; + } + virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; } virtual uint64_t light_get_version(RID p_light) const override; diff --git a/servers/rendering/dummy/storage/light_storage.h b/servers/rendering/dummy/storage/light_storage.h index b9e8bcc6f19..a9a7beb387a 100644 --- a/servers/rendering/dummy/storage/light_storage.h +++ b/servers/rendering/dummy/storage/light_storage.h @@ -77,6 +77,7 @@ public: virtual AABB light_get_aabb(RID p_light) const override { return AABB(); } virtual float light_get_param(RID p_light, RS::LightParam p_param) override { return 0.0; } virtual Color light_get_color(RID p_light) override { return Color(); } + virtual bool light_get_reverse_cull_face_mode(RID p_light) const override { return false; } virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override { return RS::LIGHT_BAKE_DISABLED; } virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; } virtual uint64_t light_get_version(RID p_light) const override { return 0; } 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 779249c2da5..bac788d0e99 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -2149,6 +2149,7 @@ void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas uint32_t atlas_size = 1; RID atlas_fb; + bool reverse_cull_face = light_storage->light_get_reverse_cull_face_mode(base); bool using_dual_paraboloid = false; bool using_dual_paraboloid_flip = false; Vector2i dual_paraboloid_offset; @@ -2292,7 +2293,7 @@ void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas if (render_cubemap) { //rendering to cubemap - _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, reverse_cull_face, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info); if (finalize_cubemap) { _render_shadow_process(); _render_shadow_end(); @@ -2310,7 +2311,7 @@ void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas } else { //render shadow - _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info); + _render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, reverse_cull_face, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info); } } @@ -2323,7 +2324,7 @@ void RenderForwardClustered::_render_shadow_begin() { scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info) { +void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_reverse_cull_face, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RenderingMethod::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -2370,6 +2371,10 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page flip_cull = !flip_cull; } + if (p_reverse_cull_face) { + flip_cull = !flip_cull; + } + shadow_pass.element_from = render_list_from; shadow_pass.element_count = render_list_size; shadow_pass.flip_cull = flip_cull; diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index e07d2f2258b..7ab9e67bac4 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -587,7 +587,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr); void _render_shadow_begin(); - void _render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr); + void _render_shadow_append(RID p_framebuffer, const PagedArray &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_reverse_cull_face, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr); void _render_shadow_process(); void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS); diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h index 3360358169a..512c440ae8f 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h @@ -451,7 +451,7 @@ public: /* LIGHT */ - bool owns_light(RID p_rid) { return light_owner.owns(p_rid); }; + bool owns_light(RID p_rid) { return light_owner.owns(p_rid); } void _light_initialize(RID p_rid, RS::LightType p_type); @@ -565,6 +565,13 @@ public: return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS]; } + virtual bool light_get_reverse_cull_face_mode(RID p_light) const override { + const Light *light = light_owner.get_or_null(p_light); + ERR_FAIL_COND_V(!light, false); + + return light->reverse_cull; + } + virtual RS::LightBakeMode light_get_bake_mode(RID p_light) override; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override; virtual uint64_t light_get_version(RID p_light) const override; diff --git a/servers/rendering/storage/light_storage.h b/servers/rendering/storage/light_storage.h index 5bd42971795..c1f79cfc492 100644 --- a/servers/rendering/storage/light_storage.h +++ b/servers/rendering/storage/light_storage.h @@ -81,6 +81,7 @@ public: virtual AABB light_get_aabb(RID p_light) const = 0; virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0; virtual Color light_get_color(RID p_light) = 0; + virtual bool light_get_reverse_cull_face_mode(RID p_light) const = 0; virtual RS::LightBakeMode light_get_bake_mode(RID p_light) = 0; virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0; virtual uint64_t light_get_version(RID p_light) const = 0;