Browse Source

Merge pull request #76565 from clayjohn/debug-PSSM-splits

Re-implement the PSSM_SPLITS debug option
Rémi Verschelde 2 years ago
parent
commit
9ecb929da6

+ 3 - 0
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

@@ -334,6 +334,9 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
 			} else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {
 			} else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {
 				material_uniform_set = scene_shader.overdraw_material_uniform_set;
 				material_uniform_set = scene_shader.overdraw_material_uniform_set;
 				shader = scene_shader.overdraw_material_shader_ptr;
 				shader = scene_shader.overdraw_material_shader_ptr;
+			} else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS)) {
+				material_uniform_set = scene_shader.debug_shadow_splits_material_uniform_set;
+				shader = scene_shader.debug_shadow_splits_material_shader_ptr;
 			} else {
 			} else {
 #endif
 #endif
 				material_uniform_set = surf->material_uniform_set;
 				material_uniform_set = surf->material_uniform_set;

+ 26 - 0
servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp

@@ -465,9 +465,11 @@ SceneShaderForwardClustered::~SceneShaderForwardClustered() {
 
 
 	material_storage->shader_free(overdraw_material_shader);
 	material_storage->shader_free(overdraw_material_shader);
 	material_storage->shader_free(default_shader);
 	material_storage->shader_free(default_shader);
+	material_storage->shader_free(debug_shadow_splits_material_shader);
 
 
 	material_storage->material_free(overdraw_material);
 	material_storage->material_free(overdraw_material);
 	material_storage->material_free(default_material);
 	material_storage->material_free(default_material);
+	material_storage->material_free(debug_shadow_splits_material);
 }
 }
 
 
 void SceneShaderForwardClustered::init(const String p_defines) {
 void SceneShaderForwardClustered::init(const String p_defines) {
@@ -720,6 +722,7 @@ void SceneShaderForwardClustered::init(const String p_defines) {
 		actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
 		actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
 		actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
 		actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
 		actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
 		actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
+		actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
 
 
 		actions.sampler_array_name = "material_samplers";
 		actions.sampler_array_name = "material_samplers";
 		actions.base_texture_binding_index = 1;
 		actions.base_texture_binding_index = 1;
@@ -793,6 +796,29 @@ void fragment() {
 		overdraw_material_uniform_set = md->uniform_set;
 		overdraw_material_uniform_set = md->uniform_set;
 	}
 	}
 
 
+	{
+		debug_shadow_splits_material_shader = material_storage->shader_allocate();
+		material_storage->shader_initialize(debug_shadow_splits_material_shader);
+		material_storage->shader_set_code(debug_shadow_splits_material_shader, R"(
+// 3D debug shadow splits mode shader(mobile).
+
+shader_type spatial;
+
+render_mode debug_shadow_splits;
+
+void fragment() {
+	ALBEDO = vec3(1.0, 1.0, 1.0);
+}
+)");
+		debug_shadow_splits_material = material_storage->material_allocate();
+		material_storage->material_initialize(debug_shadow_splits_material);
+		material_storage->material_set_shader(debug_shadow_splits_material, debug_shadow_splits_material_shader);
+
+		MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(debug_shadow_splits_material, RendererRD::MaterialStorage::SHADER_TYPE_3D));
+		debug_shadow_splits_material_shader_ptr = md->shader_data;
+		debug_shadow_splits_material_uniform_set = md->uniform_set;
+	}
+
 	{
 	{
 		default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256);
 		default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256);
 		Vector<RD::Uniform> uniforms;
 		Vector<RD::Uniform> uniforms;

+ 5 - 0
servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h

@@ -222,6 +222,8 @@ public:
 	RID default_material;
 	RID default_material;
 	RID overdraw_material_shader;
 	RID overdraw_material_shader;
 	RID overdraw_material;
 	RID overdraw_material;
+	RID debug_shadow_splits_material_shader;
+	RID debug_shadow_splits_material;
 	RID default_shader_rd;
 	RID default_shader_rd;
 	RID default_shader_sdfgi_rd;
 	RID default_shader_sdfgi_rd;
 
 
@@ -236,6 +238,9 @@ public:
 	RID overdraw_material_uniform_set;
 	RID overdraw_material_uniform_set;
 	ShaderData *overdraw_material_shader_ptr = nullptr;
 	ShaderData *overdraw_material_shader_ptr = nullptr;
 
 
+	RID debug_shadow_splits_material_uniform_set;
+	ShaderData *debug_shadow_splits_material_shader_ptr = nullptr;
+
 	Vector<RD::PipelineSpecializationConstant> default_specialization_constants;
 	Vector<RD::PipelineSpecializationConstant> default_specialization_constants;
 	HashSet<uint32_t> valid_color_pass_pipelines;
 	HashSet<uint32_t> valid_color_pass_pipelines;
 	SceneShaderForwardClustered();
 	SceneShaderForwardClustered();

+ 3 - 0
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

@@ -2113,6 +2113,9 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
 			} else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {
 			} else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW)) {
 				material_uniform_set = scene_shader.overdraw_material_uniform_set;
 				material_uniform_set = scene_shader.overdraw_material_uniform_set;
 				shader = scene_shader.overdraw_material_shader_ptr;
 				shader = scene_shader.overdraw_material_shader_ptr;
+			} else if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS)) {
+				material_uniform_set = scene_shader.debug_shadow_splits_material_uniform_set;
+				shader = scene_shader.debug_shadow_splits_material_shader_ptr;
 			} else {
 			} else {
 #endif
 #endif
 				material_uniform_set = surf->material_uniform_set;
 				material_uniform_set = surf->material_uniform_set;

+ 27 - 0
servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp

@@ -609,6 +609,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
 		actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
 		actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
 		actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
 		actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
 		actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
 		actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
+		actions.render_mode_defines["debug_shadow_splits"] = "#define DEBUG_DRAW_PSSM_SPLITS\n";
 
 
 		actions.sampler_array_name = "material_samplers";
 		actions.sampler_array_name = "material_samplers";
 		actions.base_texture_binding_index = 1;
 		actions.base_texture_binding_index = 1;
@@ -682,6 +683,30 @@ void fragment() {
 		overdraw_material_uniform_set = md->uniform_set;
 		overdraw_material_uniform_set = md->uniform_set;
 	}
 	}
 
 
+	{
+		debug_shadow_splits_material_shader = material_storage->shader_allocate();
+		material_storage->shader_initialize(debug_shadow_splits_material_shader);
+		// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
+		material_storage->shader_set_code(debug_shadow_splits_material_shader, R"(
+// 3D debug shadow splits mode shader(mobile).
+
+shader_type spatial;
+
+render_mode debug_shadow_splits.
+
+void fragment() {
+	ALBEDO = vec3(1.0, 1.0, 1.0);
+}
+)");
+		debug_shadow_splits_material = material_storage->material_allocate();
+		material_storage->material_initialize(debug_shadow_splits_material);
+		material_storage->material_set_shader(debug_shadow_splits_material, debug_shadow_splits_material_shader);
+
+		MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(debug_shadow_splits_material, RendererRD::MaterialStorage::SHADER_TYPE_3D));
+		debug_shadow_splits_material_shader_ptr = md->shader_data;
+		debug_shadow_splits_material_uniform_set = md->uniform_set;
+	}
+
 	{
 	{
 		default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256);
 		default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256);
 		Vector<RD::Uniform> uniforms;
 		Vector<RD::Uniform> uniforms;
@@ -724,7 +749,9 @@ SceneShaderForwardMobile::~SceneShaderForwardMobile() {
 
 
 	material_storage->shader_free(overdraw_material_shader);
 	material_storage->shader_free(overdraw_material_shader);
 	material_storage->shader_free(default_shader);
 	material_storage->shader_free(default_shader);
+	material_storage->shader_free(debug_shadow_splits_material_shader);
 
 
 	material_storage->material_free(overdraw_material);
 	material_storage->material_free(overdraw_material);
 	material_storage->material_free(default_material);
 	material_storage->material_free(default_material);
+	material_storage->material_free(debug_shadow_splits_material);
 }
 }

+ 5 - 0
servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h

@@ -181,6 +181,8 @@ public:
 	RID default_material;
 	RID default_material;
 	RID overdraw_material_shader;
 	RID overdraw_material_shader;
 	RID overdraw_material;
 	RID overdraw_material;
+	RID debug_shadow_splits_material_shader;
+	RID debug_shadow_splits_material;
 	RID default_shader_rd;
 	RID default_shader_rd;
 
 
 	RID default_vec4_xform_buffer;
 	RID default_vec4_xform_buffer;
@@ -194,6 +196,9 @@ public:
 	RID overdraw_material_uniform_set;
 	RID overdraw_material_uniform_set;
 	ShaderData *overdraw_material_shader_ptr = nullptr;
 	ShaderData *overdraw_material_shader_ptr = nullptr;
 
 
+	RID debug_shadow_splits_material_uniform_set;
+	ShaderData *debug_shadow_splits_material_shader_ptr = nullptr;
+
 	SceneShaderForwardMobile();
 	SceneShaderForwardMobile();
 	~SceneShaderForwardMobile();
 	~SceneShaderForwardMobile();
 
 

+ 22 - 1
servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl

@@ -1817,9 +1817,30 @@ void fragment_shader(in SceneData scene_data) {
 
 
 			blur_shadow(shadow);
 			blur_shadow(shadow);
 
 
+#ifdef DEBUG_DRAW_PSSM_SPLITS
+			vec3 tint = vec3(1.0);
+			if (-vertex.z < directional_lights.data[i].shadow_split_offsets.x) {
+				tint = vec3(1.0, 0.0, 0.0);
+			} else if (-vertex.z < directional_lights.data[i].shadow_split_offsets.y) {
+				tint = vec3(0.0, 1.0, 0.0);
+			} else if (-vertex.z < directional_lights.data[i].shadow_split_offsets.z) {
+				tint = vec3(0.0, 0.0, 1.0);
+			} else {
+				tint = vec3(1.0, 1.0, 0.0);
+			}
+			tint = mix(tint, vec3(1.0), shadow);
+			shadow = 1.0;
+#endif
+
 			float size_A = sc_use_light_soft_shadows ? directional_lights.data[i].size : 0.0;
 			float size_A = sc_use_light_soft_shadows ? directional_lights.data[i].size : 0.0;
 
 
-			light_compute(normal, directional_lights.data[i].direction, normalize(view), size_A, directional_lights.data[i].color * directional_lights.data[i].energy, true, shadow, f0, orms, 1.0, albedo, alpha,
+			light_compute(normal, directional_lights.data[i].direction, normalize(view), size_A,
+#ifndef DEBUG_DRAW_PSSM_SPLITS
+					directional_lights.data[i].color * directional_lights.data[i].energy,
+#else
+					directional_lights.data[i].color * directional_lights.data[i].energy * tint,
+#endif
+					true, shadow, f0, orms, 1.0, albedo, alpha,
 #ifdef LIGHT_BACKLIGHT_USED
 #ifdef LIGHT_BACKLIGHT_USED
 					backlight,
 					backlight,
 #endif
 #endif

+ 22 - 1
servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl

@@ -1534,7 +1534,28 @@ void main() {
 #endif
 #endif
 			blur_shadow(shadow);
 			blur_shadow(shadow);
 
 
-			light_compute(normal, directional_lights.data[i].direction, normalize(view), 0.0, directional_lights.data[i].color * directional_lights.data[i].energy, true, shadow, f0, orms, 1.0, albedo, alpha,
+#ifdef DEBUG_DRAW_PSSM_SPLITS
+			vec3 tint = vec3(1.0);
+			if (-vertex.z < directional_lights.data[i].shadow_split_offsets.x) {
+				tint = vec3(1.0, 0.0, 0.0);
+			} else if (-vertex.z < directional_lights.data[i].shadow_split_offsets.y) {
+				tint = vec3(0.0, 1.0, 0.0);
+			} else if (-vertex.z < directional_lights.data[i].shadow_split_offsets.z) {
+				tint = vec3(0.0, 0.0, 1.0);
+			} else {
+				tint = vec3(1.0, 1.0, 0.0);
+			}
+			tint = mix(tint, vec3(1.0), shadow);
+			shadow = 1.0;
+#endif
+
+			light_compute(normal, directional_lights.data[i].direction, normalize(view), 0.0,
+#ifndef DEBUG_DRAW_PSSM_SPLITS
+					directional_lights.data[i].color * directional_lights.data[i].energy,
+#else
+					directional_lights.data[i].color * directional_lights.data[i].energy * tint,
+#endif
+					true, shadow, f0, orms, 1.0, albedo, alpha,
 #ifdef LIGHT_BACKLIGHT_USED
 #ifdef LIGHT_BACKLIGHT_USED
 					backlight,
 					backlight,
 #endif
 #endif

+ 0 - 4
servers/rendering/renderer_rd/storage_rd/light_storage.cpp

@@ -634,10 +634,6 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
 
 
 				light_data.size = 1.0 - Math::cos(Math::deg_to_rad(size)); //angle to cosine offset
 				light_data.size = 1.0 - Math::cos(Math::deg_to_rad(size)); //angle to cosine offset
 
 
-				if (RendererSceneRenderRD::get_singleton()->get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_PSSM_SPLITS) {
-					WARN_PRINT_ONCE("The DirectionalLight3D PSSM splits debug draw mode is not reimplemented yet.");
-				}
-
 				light_data.shadow_opacity = (p_using_shadows && light->shadow)
 				light_data.shadow_opacity = (p_using_shadows && light->shadow)
 						? light->param[RS::LIGHT_PARAM_SHADOW_OPACITY]
 						? light->param[RS::LIGHT_PARAM_SHADOW_OPACITY]
 						: 0.0;
 						: 0.0;

+ 1 - 0
servers/rendering/shader_types.cpp

@@ -226,6 +226,7 @@ ShaderTypes::ShaderTypes() {
 		shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("particle_trails") });
 		shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("particle_trails") });
 		shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage") });
 		shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage") });
 		shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage_and_one") });
 		shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage_and_one") });
+		shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("debug_shadow_splits") });
 	}
 	}
 
 
 	/************ CANVAS ITEM **************************/
 	/************ CANVAS ITEM **************************/