소스 검색

(Re-)Implemented Light3D's property "shadow_reverse_cull_face"

The parameter shadow_reverse_cull_face is now passed to the shadow pass so that the mesh back-faces are used for shadow map calculation.
Markus Grafen 2 년 전
부모
커밋
8a3e829930

+ 7 - 0
drivers/gles3/storage/light_storage.h

@@ -287,6 +287,13 @@ public:
 		return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS];
 		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 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 uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
 	virtual uint64_t light_get_version(RID p_light) const override;
 	virtual uint64_t light_get_version(RID p_light) const override;

+ 1 - 0
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 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 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 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 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 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; }
 	virtual uint64_t light_get_version(RID p_light) const override { return 0; }

+ 8 - 3
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;
 	uint32_t atlas_size = 1;
 	RID atlas_fb;
 	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 = false;
 	bool using_dual_paraboloid_flip = false;
 	bool using_dual_paraboloid_flip = false;
 	Vector2i dual_paraboloid_offset;
 	Vector2i dual_paraboloid_offset;
@@ -2292,7 +2293,7 @@ void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas
 
 
 	if (render_cubemap) {
 	if (render_cubemap) {
 		//rendering to 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) {
 		if (finalize_cubemap) {
 			_render_shadow_process();
 			_render_shadow_process();
 			_render_shadow_end();
 			_render_shadow_end();
@@ -2310,7 +2311,7 @@ void RenderForwardClustered::_render_shadow_pass(RID p_light, RID p_shadow_atlas
 
 
 	} else {
 	} else {
 		//render shadow
 		//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();
 	scene_state.instance_data[RENDER_LIST_SECONDARY].clear();
 }
 }
 
 
-void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &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<RenderGeometryInstance *> &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();
 	uint32_t shadow_pass_index = scene_state.shadow_passes.size();
 
 
 	SceneState::ShadowPass shadow_pass;
 	SceneState::ShadowPass shadow_pass;
@@ -2370,6 +2371,10 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
 			flip_cull = !flip_cull;
 			flip_cull = !flip_cull;
 		}
 		}
 
 
+		if (p_reverse_cull_face) {
+			flip_cull = !flip_cull;
+		}
+
 		shadow_pass.element_from = render_list_from;
 		shadow_pass.element_from = render_list_from;
 		shadow_pass.element_count = render_list_size;
 		shadow_pass.element_count = render_list_size;
 		shadow_pass.flip_cull = flip_cull;
 		shadow_pass.flip_cull = flip_cull;

+ 1 - 1
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<RenderGeometryInstance *> &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_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &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_begin();
-	void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &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<RenderGeometryInstance *> &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_process();
 	void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
 	void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
 
 

+ 8 - 1
servers/rendering/renderer_rd/storage_rd/light_storage.h

@@ -451,7 +451,7 @@ public:
 
 
 	/* LIGHT */
 	/* 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);
 	void _light_initialize(RID p_rid, RS::LightType p_type);
 
 
@@ -565,6 +565,13 @@ public:
 		return light->param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS];
 		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 RS::LightBakeMode light_get_bake_mode(RID p_light) override;
 	virtual uint32_t light_get_max_sdfgi_cascade(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;
 	virtual uint64_t light_get_version(RID p_light) const override;

+ 1 - 0
servers/rendering/storage/light_storage.h

@@ -81,6 +81,7 @@ public:
 	virtual AABB light_get_aabb(RID p_light) const = 0;
 	virtual AABB light_get_aabb(RID p_light) const = 0;
 	virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0;
 	virtual float light_get_param(RID p_light, RS::LightParam p_param) = 0;
 	virtual Color light_get_color(RID p_light) = 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 RS::LightBakeMode light_get_bake_mode(RID p_light) = 0;
 	virtual uint32_t light_get_max_sdfgi_cascade(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;
 	virtual uint64_t light_get_version(RID p_light) const = 0;