Przeglądaj źródła

Shadow map rendering optimization

-All shadow rendering is done with raster now (no compute)
-All shadow rendering is done by rendering directly to the shadow atlas
-Improved how buffer clearing is done to optimize the above.
-Ability to set shadows as 16 bits.
reduz 4 lat temu
rodzic
commit
a9beb7aa8c
29 zmienionych plików z 330 dodań i 292 usunięć
  1. 16 8
      drivers/vulkan/rendering_device_vulkan.cpp
  2. 5 0
      editor/editor_node.cpp
  3. 2 0
      editor/plugins/node_3d_editor_plugin.cpp
  4. 0 21
      main/main.cpp
  5. 20 0
      scene/main/scene_tree.cpp
  6. 21 6
      scene/main/viewport.cpp
  7. 4 0
      scene/main/viewport.h
  8. 18 17
      servers/rendering/renderer_rd/effects_rd.cpp
  9. 4 5
      servers/rendering/renderer_rd/effects_rd.h
  10. 61 48
      servers/rendering/renderer_rd/renderer_scene_render_forward.cpp
  11. 2 2
      servers/rendering/renderer_rd/renderer_scene_render_forward.h
  12. 79 94
      servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
  13. 10 11
      servers/rendering/renderer_rd/renderer_scene_render_rd.h
  14. 30 15
      servers/rendering/renderer_rd/shaders/cube_to_dp.glsl
  15. 2 1
      servers/rendering/renderer_rd/shaders/gi.glsl
  16. 3 4
      servers/rendering/renderer_rd/shaders/resolve.glsl
  17. 1 1
      servers/rendering/renderer_rd/shaders/scene_forward.glsl
  18. 30 30
      servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl
  19. 2 2
      servers/rendering/renderer_scene.h
  20. 2 2
      servers/rendering/renderer_scene_cull.h
  21. 2 2
      servers/rendering/renderer_scene_render.h
  22. 3 2
      servers/rendering/renderer_viewport.cpp
  23. 2 1
      servers/rendering/renderer_viewport.h
  24. 1 0
      servers/rendering/rendering_device.cpp
  25. 2 1
      servers/rendering/rendering_device.h
  26. 2 2
      servers/rendering/rendering_server_default.h
  27. 2 2
      servers/rendering/rendering_server_wrap_mt.h
  28. 2 13
      servers/rendering_server.cpp
  29. 2 2
      servers/rendering_server.h

+ 16 - 8
drivers/vulkan/rendering_device_vulkan.cpp

@@ -3104,6 +3104,7 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
 		// the read.  If this is a performance issue, one could track the actual last accessor of each resource, adding only that
 		// stage
 		switch (is_depth_stencil ? p_initial_depth_action : p_initial_color_action) {
+			case INITIAL_ACTION_CLEAR_REGION:
 			case INITIAL_ACTION_CLEAR: {
 				description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
 				description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
@@ -3116,9 +3117,9 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
 					description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
 					description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
 				} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-					description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
-					description.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; //don't care what is there
-					description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
+					description.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
+					description.initialLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
+					description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
 					dependency_from_external.srcStageMask |= reading_stages;
 				} else {
 					description.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
@@ -5726,11 +5727,18 @@ Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuff
 	render_pass_begin.pNext = nullptr;
 	render_pass_begin.renderPass = render_pass;
 	render_pass_begin.framebuffer = vkframebuffer;
-
+	/*
+	 * Given how API works, it makes sense to always fully operate on the whole framebuffer.
+	 * This allows better continue operations for operations like shadowmapping.
 	render_pass_begin.renderArea.extent.width = viewport_size.width;
 	render_pass_begin.renderArea.extent.height = viewport_size.height;
 	render_pass_begin.renderArea.offset.x = viewport_offset.x;
 	render_pass_begin.renderArea.offset.y = viewport_offset.y;
+	*/
+	render_pass_begin.renderArea.extent.width = framebuffer->size.width;
+	render_pass_begin.renderArea.extent.height = framebuffer->size.height;
+	render_pass_begin.renderArea.offset.x = 0;
+	render_pass_begin.renderArea.offset.y = 0;
 
 	Vector<VkClearValue> clear_values;
 	clear_values.resize(framebuffer->texture_ids.size());
@@ -5879,11 +5887,11 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
 		viewport_offset = regioni.position;
 		viewport_size = regioni.size;
 
-		if (p_initial_color_action == INITIAL_ACTION_CLEAR) {
+		if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) {
 			needs_clear_color = true;
 			p_initial_color_action = INITIAL_ACTION_KEEP;
 		}
-		if (p_initial_depth_action == INITIAL_ACTION_CLEAR) {
+		if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) {
 			needs_clear_depth = true;
 			p_initial_depth_action = INITIAL_ACTION_KEEP;
 		}
@@ -5969,11 +5977,11 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
 		viewport_offset = regioni.position;
 		viewport_size = regioni.size;
 
-		if (p_initial_color_action == INITIAL_ACTION_CLEAR) {
+		if (p_initial_color_action == INITIAL_ACTION_CLEAR_REGION) {
 			needs_clear_color = true;
 			p_initial_color_action = INITIAL_ACTION_KEEP;
 		}
-		if (p_initial_depth_action == INITIAL_ACTION_CLEAR) {
+		if (p_initial_depth_action == INITIAL_ACTION_CLEAR_REGION) {
 			needs_clear_depth = true;
 			p_initial_depth_action = INITIAL_ACTION_KEEP;
 		}

+ 5 - 0
editor/editor_node.cpp

@@ -498,6 +498,11 @@ void EditorNode::_notification(int p_what) {
 				float sss_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_scale");
 				float sss_depth_scale = GLOBAL_GET("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale");
 				RS::get_singleton()->sub_surface_scattering_set_scale(sss_scale, sss_depth_scale);
+
+				uint32_t directional_shadow_size = GLOBAL_GET("rendering/quality/directional_shadow/size");
+				uint32_t directional_shadow_16_bits = GLOBAL_GET("rendering/quality/directional_shadow/16_bits");
+				RS::get_singleton()->directional_shadow_atlas_set_size(directional_shadow_size, directional_shadow_16_bits);
+
 				RS::ShadowQuality shadows_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/shadows/soft_shadow_quality")));
 				RS::get_singleton()->shadows_quality_set(shadows_quality);
 				RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality")));

+ 2 - 0
editor/plugins/node_3d_editor_plugin.cpp

@@ -2445,12 +2445,14 @@ void Node3DEditorViewport::_notification(int p_what) {
 		//update shadow atlas if changed
 
 		int shadowmap_size = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/size");
+		bool shadowmap_16_bits = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/16_bits");
 		int atlas_q0 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv");
 		int atlas_q1 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv");
 		int atlas_q2 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv");
 		int atlas_q3 = ProjectSettings::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv");
 
 		viewport->set_shadow_atlas_size(shadowmap_size);
+		viewport->set_shadow_atlas_16_bits(shadowmap_16_bits);
 		viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
 		viewport->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
 		viewport->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));

+ 0 - 21
main/main.cpp

@@ -2151,11 +2151,6 @@ bool Main::start() {
 		}
 #endif
 
-		{
-			int directional_atlas_size = GLOBAL_GET("rendering/quality/directional_shadow/size");
-			RenderingServer::get_singleton()->directional_shadow_atlas_set_size(directional_atlas_size);
-		}
-
 		if (!editor && !project_manager) {
 			//standard helpers that can be changed from main config
 
@@ -2199,22 +2194,6 @@ bool Main::start() {
 			DisplayServer::get_singleton()->window_set_title(appname);
 #endif
 
-			int shadow_atlas_size = GLOBAL_GET("rendering/quality/shadow_atlas/size");
-			int shadow_atlas_q0_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_0_subdiv");
-			int shadow_atlas_q1_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_1_subdiv");
-			int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv");
-			int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv");
-
-			sml->get_root()->set_shadow_atlas_size(shadow_atlas_size);
-			sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(
-																		 shadow_atlas_q0_subdiv));
-			sml->get_root()->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(
-																		 shadow_atlas_q1_subdiv));
-			sml->get_root()->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(
-																		 shadow_atlas_q2_subdiv));
-			sml->get_root()->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(
-																		 shadow_atlas_q3_subdiv));
-
 			bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
 			sml->get_root()->set_snap_controls_to_pixels(snap_controls);
 

+ 20 - 0
scene/main/scene_tree.cpp

@@ -1372,6 +1372,26 @@ SceneTree::SceneTree() {
 	bool snap_2d_vertices = GLOBAL_DEF("rendering/quality/2d/snap_2d_vertices_to_pixel", false);
 	root->set_snap_2d_vertices_to_pixel(snap_2d_vertices);
 
+	int shadowmap_size = GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
+	GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
+	bool shadowmap_16_bits = GLOBAL_DEF("rendering/quality/shadow_atlas/16_bits", true);
+	int atlas_q0 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 2);
+	int atlas_q1 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2);
+	int atlas_q2 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3);
+	int atlas_q3 = GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4);
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+
+	root->set_shadow_atlas_size(shadowmap_size);
+	root->set_shadow_atlas_16_bits(shadowmap_16_bits);
+	root->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
+	root->set_shadow_atlas_quadrant_subdiv(1, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q1));
+	root->set_shadow_atlas_quadrant_subdiv(2, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q2));
+	root->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q3));
+
 	Viewport::SDFOversize sdf_oversize = Viewport::SDFOversize(int(GLOBAL_DEF("rendering/quality/2d_sdf/oversize", 1)));
 	root->set_sdf_oversize(sdf_oversize);
 	Viewport::SDFScale sdf_scale = Viewport::SDFScale(int(GLOBAL_DEF("rendering/quality/2d_sdf/scale", 1)));

+ 21 - 6
scene/main/viewport.cpp

@@ -1416,18 +1416,26 @@ Ref<ViewportTexture> Viewport::get_texture() const {
 }
 
 void Viewport::set_shadow_atlas_size(int p_size) {
-	if (shadow_atlas_size == p_size) {
-		return;
-	}
-
 	shadow_atlas_size = p_size;
-	RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size);
+	RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size, shadow_atlas_16_bits);
 }
 
 int Viewport::get_shadow_atlas_size() const {
 	return shadow_atlas_size;
 }
 
+void Viewport::set_shadow_atlas_16_bits(bool p_16_bits) {
+	if (shadow_atlas_16_bits == p_16_bits) {
+		return;
+	}
+
+	shadow_atlas_16_bits = p_16_bits;
+	RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, shadow_atlas_size, shadow_atlas_16_bits);
+}
+
+bool Viewport::get_shadow_atlas_16_bits() const {
+	return shadow_atlas_16_bits;
+}
 void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv) {
 	ERR_FAIL_INDEX(p_quadrant, 4);
 	ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
@@ -3481,6 +3489,9 @@ void Viewport::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_shadow_atlas_size", "size"), &Viewport::set_shadow_atlas_size);
 	ClassDB::bind_method(D_METHOD("get_shadow_atlas_size"), &Viewport::get_shadow_atlas_size);
 
+	ClassDB::bind_method(D_METHOD("set_shadow_atlas_16_bits", "enable"), &Viewport::set_shadow_atlas_16_bits);
+	ClassDB::bind_method(D_METHOD("get_shadow_atlas_16_bits"), &Viewport::get_shadow_atlas_16_bits);
+
 	ClassDB::bind_method(D_METHOD("set_snap_controls_to_pixels", "enabled"), &Viewport::set_snap_controls_to_pixels);
 	ClassDB::bind_method(D_METHOD("is_snap_controls_to_pixels_enabled"), &Viewport::is_snap_controls_to_pixels_enabled);
 
@@ -3548,6 +3559,7 @@ void Viewport::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "sdf_scale", PROPERTY_HINT_ENUM, "100%,50%,25%"), "set_sdf_scale", "get_sdf_scale");
 	ADD_GROUP("Shadow Atlas", "shadow_atlas_");
 	ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_atlas_size"), "set_shadow_atlas_size", "get_shadow_atlas_size");
+	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shadow_atlas_16_bits"), "set_shadow_atlas_16_bits", "get_shadow_atlas_16_bits");
 	ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_0", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 0);
 	ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_1", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 1);
 	ADD_PROPERTYI(PropertyInfo(Variant::INT, "shadow_atlas_quad_2", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"), "set_shadow_atlas_quadrant_subdiv", "get_shadow_atlas_quadrant_subdiv", 2);
@@ -3662,7 +3674,10 @@ Viewport::Viewport() {
 	physics_has_last_mousepos = false;
 	physics_last_mousepos = Vector2(Math_INF, Math_INF);
 
-	shadow_atlas_size = 0;
+	shadow_atlas_16_bits = true;
+	shadow_atlas_size = 2048;
+	set_shadow_atlas_size(shadow_atlas_size);
+
 	for (int i = 0; i < 4; i++) {
 		shadow_atlas_quadrant_subdiv[i] = SHADOW_ATLAS_QUADRANT_SUBDIV_MAX;
 	}

+ 4 - 0
scene/main/viewport.h

@@ -297,6 +297,7 @@ private:
 	DebugDraw debug_draw;
 
 	int shadow_atlas_size;
+	bool shadow_atlas_16_bits = true;
 	ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
 
 	MSAA msaa;
@@ -537,6 +538,9 @@ public:
 	void set_shadow_atlas_size(int p_size);
 	int get_shadow_atlas_size() const;
 
+	void set_shadow_atlas_16_bits(bool p_16_bits);
+	bool get_shadow_atlas_16_bits() const;
+
 	void set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv);
 	ShadowAtlasQuadrantSubdiv get_shadow_atlas_quadrant_subdiv(int p_quadrant) const;
 

+ 18 - 17
servers/rendering/renderer_rd/effects_rd.cpp

@@ -702,27 +702,24 @@ void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const S
 	RD::get_singleton()->compute_list_end();
 }
 
-void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
+void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip) {
 	CopyToDPPushConstant push_constant;
-	push_constant.screen_size[0] = p_rect.size.x;
-	push_constant.screen_size[1] = p_rect.size.y;
-	push_constant.dest_offset[0] = p_rect.position.x;
-	push_constant.dest_offset[1] = p_rect.position.y;
-	push_constant.bias = p_bias;
+	push_constant.screen_rect[0] = p_rect.position.x;
+	push_constant.screen_rect[1] = p_rect.position.y;
+	push_constant.screen_rect[2] = p_rect.size.width;
+	push_constant.screen_rect[3] = p_rect.size.height;
 	push_constant.z_far = p_z_far;
 	push_constant.z_near = p_z_near;
 	push_constant.z_flip = p_dp_flip;
 
-	int32_t x_groups = (p_rect.size.width - 1) / 8 + 1;
-	int32_t y_groups = (p_rect.size.height - 1) / 8 + 1;
+	RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
+	RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
+	RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
+	RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
 
-	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cube_to_dp.pipeline);
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0);
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1);
-	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(CopyToDPPushConstant));
-	RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
-	RD::get_singleton()->compute_list_end();
+	RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
+	RD::get_singleton()->draw_list_draw(draw_list, true);
+	RD::get_singleton()->draw_list_end();
 }
 
 void EffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
@@ -1678,8 +1675,12 @@ EffectsRD::EffectsRD() {
 		cube_to_dp.shader.initialize(copy_modes);
 
 		cube_to_dp.shader_version = cube_to_dp.shader.version_create();
-
-		cube_to_dp.pipeline = RD::get_singleton()->compute_pipeline_create(cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0));
+		RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
+		RD::PipelineDepthStencilState dss;
+		dss.enable_depth_test = true;
+		dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS;
+		dss.enable_depth_write = true;
+		cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0);
 	}
 
 	{

+ 4 - 5
servers/rendering/renderer_rd/effects_rd.h

@@ -234,18 +234,17 @@ class EffectsRD {
 	} luminance_reduce;
 
 	struct CopyToDPPushConstant {
-		int32_t screen_size[2];
-		int32_t dest_offset[2];
-		float bias;
 		float z_far;
 		float z_near;
 		uint32_t z_flip;
+		uint32_t pad;
+		float screen_rect[4];
 	};
 
 	struct CoptToDP {
 		CubeToDpShaderRD shader;
 		RID shader_version;
-		RID pipeline;
+		PipelineCacheRD pipeline;
 	} cube_to_dp;
 
 	struct BokehPushConstant {
@@ -687,7 +686,7 @@ public:
 
 	void cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
 	void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size);
-	void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip);
+	void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2 &p_rect, float p_z_near, float p_z_far, bool p_dp_flip);
 	void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
 	void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal);
 

+ 61 - 48
servers/rendering/renderer_rd/renderer_scene_render_forward.cpp

@@ -1722,7 +1722,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
 
 	RENDER_TIMESTAMP("Render Opaque Pass");
 
-	RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps);
+	RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_cluster_buffer, p_gi_probes, p_lightmaps, true);
 
 	bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
 	bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
@@ -1838,7 +1838,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
 	}
 }
 
-void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &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_lod_threshold) {
+void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &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_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) {
 	RENDER_TIMESTAMP("Setup Rendering Shadow");
 
 	_update_render_base_uniform_set();
@@ -1847,7 +1847,7 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr
 
 	scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
 
-	_setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), true, Color(), 0, p_zfar, false, p_use_pancake);
+	_setup_environment(RID(), RID(), p_projection, p_transform, RID(), true, Vector2(1, 1), 1, 32, RID(), !p_flip_y, Color(), 0, p_zfar, false, p_use_pancake);
 
 	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
 		p_screen_lod_threshold = 0.0;
@@ -1865,8 +1865,12 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr
 
 	{
 		//regular forward for now
-		RenderListParameters render_list_params(render_list.elements, render_list.element_count, p_use_dp_flip, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
-		_render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ);
+		bool flip_cull = p_use_dp_flip;
+		if (p_flip_y) {
+			flip_cull = !flip_cull;
+		}
+		RenderListParameters render_list_params(render_list.elements, render_list.element_count, flip_cull, pass_mode, true, rp_uniform_set, false, Vector2(), p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
+		_render_list_with_threads(&render_list_params, p_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : RD::INITIAL_ACTION_CONTINUE, p_end ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, Vector<Color>(), 1.0, 0, p_rect);
 	}
 }
 
@@ -2128,14 +2132,14 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
 
 		{
 			RD::Uniform u;
-			u.binding = 5;
+			u.binding = 4;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.ids.push_back(get_omni_light_buffer());
 			uniforms.push_back(u);
 		}
 		{
 			RD::Uniform u;
-			u.binding = 6;
+			u.binding = 5;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.ids.push_back(get_spot_light_buffer());
 			uniforms.push_back(u);
@@ -2143,35 +2147,35 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
 
 		{
 			RD::Uniform u;
-			u.binding = 7;
+			u.binding = 6;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.ids.push_back(get_reflection_probe_buffer());
 			uniforms.push_back(u);
 		}
 		{
 			RD::Uniform u;
-			u.binding = 8;
+			u.binding = 7;
 			u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
 			u.ids.push_back(get_directional_light_buffer());
 			uniforms.push_back(u);
 		}
 		{
 			RD::Uniform u;
-			u.binding = 10;
+			u.binding = 8;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.ids.push_back(scene_state.lightmap_buffer);
 			uniforms.push_back(u);
 		}
 		{
 			RD::Uniform u;
-			u.binding = 11;
+			u.binding = 9;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.ids.push_back(scene_state.lightmap_capture_buffer);
 			uniforms.push_back(u);
 		}
 		{
 			RD::Uniform u;
-			u.binding = 12;
+			u.binding = 10;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			RID decal_atlas = storage->decal_atlas_get_texture();
 			u.ids.push_back(decal_atlas);
@@ -2179,7 +2183,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
 		}
 		{
 			RD::Uniform u;
-			u.binding = 13;
+			u.binding = 11;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			RID decal_atlas = storage->decal_atlas_get_texture_srgb();
 			u.ids.push_back(decal_atlas);
@@ -2187,28 +2191,16 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
 		}
 		{
 			RD::Uniform u;
-			u.binding = 14;
+			u.binding = 12;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.ids.push_back(get_decal_buffer());
 			uniforms.push_back(u);
 		}
 
-		{
-			RD::Uniform u;
-			u.binding = 15;
-			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			if (directional_shadow_get_texture().is_valid()) {
-				u.ids.push_back(directional_shadow_get_texture());
-			} else {
-				u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
-			}
-			uniforms.push_back(u);
-		}
-
 		{
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
-			u.binding = 16;
+			u.binding = 13;
 			u.ids.push_back(storage->global_variables_get_storage_buffer());
 			uniforms.push_back(u);
 		}
@@ -2216,7 +2208,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
 		if (!low_end) {
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
-			u.binding = 17;
+			u.binding = 14;
 			u.ids.push_back(sdfgi_get_ubo());
 			uniforms.push_back(u);
 		}
@@ -2225,7 +2217,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
 	}
 }
 
-RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps) {
+RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas) {
 	if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
 		RD::get_singleton()->free(render_pass_uniform_set);
 	}
@@ -2284,6 +2276,17 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 		RD::Uniform u;
 		u.binding = 3;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+		if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) {
+			u.ids.push_back(directional_shadow_get_texture());
+		} else {
+			u.ids.push_back(storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE));
+		}
+		uniforms.push_back(u);
+	}
+	{
+		RD::Uniform u;
+		u.binding = 4;
+		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 		u.ids.resize(scene_state.max_lightmaps);
 		RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
 		for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
@@ -2301,7 +2304,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 	}
 	{
 		RD::Uniform u;
-		u.binding = 4;
+		u.binding = 5;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 		u.ids.resize(MAX_GI_PROBES);
 		RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
@@ -2322,7 +2325,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 
 	{
 		RD::Uniform u;
-		u.binding = 5;
+		u.binding = 6;
 		u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 		RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer;
 		u.ids.push_back(cb);
@@ -2331,7 +2334,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 
 	{
 		RD::Uniform u;
-		u.binding = 6;
+		u.binding = 7;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 		RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
 		u.ids.push_back(texture);
@@ -2339,7 +2342,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 	}
 	{
 		RD::Uniform u;
-		u.binding = 7;
+		u.binding = 8;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 		RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID();
 		RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
@@ -2350,7 +2353,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 	if (!low_end) {
 		{
 			RD::Uniform u;
-			u.binding = 8;
+			u.binding = 9;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
 			u.ids.push_back(texture);
@@ -2359,7 +2362,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 
 		{
 			RD::Uniform u;
-			u.binding = 9;
+			u.binding = 10;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID();
 			RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
@@ -2369,7 +2372,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 
 		{
 			RD::Uniform u;
-			u.binding = 10;
+			u.binding = 11;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			RID ambient_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_ambient_texture(p_render_buffers) : RID();
 			RID texture = ambient_buffer.is_valid() ? ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
@@ -2379,7 +2382,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 
 		{
 			RD::Uniform u;
-			u.binding = 11;
+			u.binding = 12;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			RID reflection_buffer = p_render_buffers.is_valid() ? render_buffers_get_gi_reflection_texture(p_render_buffers) : RID();
 			RID texture = reflection_buffer.is_valid() ? reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
@@ -2388,7 +2391,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 		}
 		{
 			RD::Uniform u;
-			u.binding = 12;
+			u.binding = 13;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			RID t;
 			if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
@@ -2401,7 +2404,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 		}
 		{
 			RD::Uniform u;
-			u.binding = 13;
+			u.binding = 14;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
 				u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers));
@@ -2412,14 +2415,14 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
 		}
 		{
 			RD::Uniform u;
-			u.binding = 14;
+			u.binding = 15;
 			u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
 			u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer());
 			uniforms.push_back(u);
 		}
 		{
 			RD::Uniform u;
-			u.binding = 15;
+			u.binding = 16;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			RID vfog = RID();
 			if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) {
@@ -2477,10 +2480,20 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
 	}
 
 	{
-		// No Lightmaps
+		// No directional shadow atlas.
 		RD::Uniform u;
 		u.binding = 3;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+		RID texture = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
+		u.ids.push_back(texture);
+		uniforms.push_back(u);
+	}
+
+	{
+		// No Lightmaps
+		RD::Uniform u;
+		u.binding = 4;
+		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 		u.ids.resize(scene_state.max_lightmaps);
 		RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
 		for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
@@ -2493,7 +2506,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
 	{
 		// No GIProbes
 		RD::Uniform u;
-		u.binding = 4;
+		u.binding = 5;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 		u.ids.resize(MAX_GI_PROBES);
 		RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
@@ -2506,7 +2519,7 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
 
 	{
 		RD::Uniform u;
-		u.binding = 5;
+		u.binding = 6;
 		u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 		RID cb = default_vec4_xform_buffer;
 		u.ids.push_back(cb);
@@ -2518,28 +2531,28 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
 	{
 		RD::Uniform u;
 		u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-		u.binding = 6;
+		u.binding = 7;
 		u.ids.push_back(p_albedo_texture);
 		uniforms.push_back(u);
 	}
 	{
 		RD::Uniform u;
 		u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-		u.binding = 7;
+		u.binding = 8;
 		u.ids.push_back(p_emission_texture);
 		uniforms.push_back(u);
 	}
 	{
 		RD::Uniform u;
 		u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-		u.binding = 8;
+		u.binding = 9;
 		u.ids.push_back(p_emission_aniso_texture);
 		uniforms.push_back(u);
 	}
 	{
 		RD::Uniform u;
 		u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-		u.binding = 9;
+		u.binding = 10;
 		u.ids.push_back(p_geom_facing_texture);
 		uniforms.push_back(u);
 	}

+ 2 - 2
servers/rendering/renderer_rd/renderer_scene_render_forward.h

@@ -257,7 +257,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
 
 	void _update_render_base_uniform_set();
 	RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
-	RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps);
+	RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas = false);
 
 	struct LightmapData {
 		float normal_xform[12];
@@ -701,7 +701,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
 
 protected:
 	virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
-	virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &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_lod_threshold = 0.0);
+	virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_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);
 	virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
 	virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
 	virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);

+ 79 - 94
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -3564,13 +3564,28 @@ RID RendererSceneRenderRD::shadow_atlas_create() {
 	return shadow_atlas_owner.make_rid(ShadowAtlas());
 }
 
-void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
+void RendererSceneRenderRD::_update_shadow_atlas(ShadowAtlas *shadow_atlas) {
+	if (shadow_atlas->size > 0 && shadow_atlas->depth.is_null()) {
+		RD::TextureFormat tf;
+		tf.format = shadow_atlas->use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
+		tf.width = shadow_atlas->size;
+		tf.height = shadow_atlas->size;
+		tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+
+		shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
+		Vector<RID> fb_tex;
+		fb_tex.push_back(shadow_atlas->depth);
+		shadow_atlas->fb = RD::get_singleton()->framebuffer_create(fb_tex);
+	}
+}
+
+void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) {
 	ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
 	ERR_FAIL_COND(!shadow_atlas);
 	ERR_FAIL_COND(p_size < 0);
 	p_size = next_power_of_2(p_size);
 
-	if (p_size == shadow_atlas->size) {
+	if (p_size == shadow_atlas->size && p_16_bits == shadow_atlas->use_16_bits) {
 		return;
 	}
 
@@ -3597,16 +3612,7 @@ void RendererSceneRenderRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
 	shadow_atlas->shadow_owners.clear();
 
 	shadow_atlas->size = p_size;
-
-	if (shadow_atlas->size) {
-		RD::TextureFormat tf;
-		tf.format = RD::DATA_FORMAT_R32_SFLOAT;
-		tf.width = shadow_atlas->size;
-		tf.height = shadow_atlas->size;
-		tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
-		shadow_atlas->depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
-	}
+	shadow_atlas->use_16_bits = p_size;
 }
 
 void RendererSceneRenderRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
@@ -3861,10 +3867,24 @@ bool RendererSceneRenderRD::shadow_atlas_update_light(RID p_atlas, RID p_light_i
 	return false;
 }
 
-void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
+void RendererSceneRenderRD::_update_directional_shadow_atlas() {
+	if (directional_shadow.depth.is_null() && directional_shadow.size > 0) {
+		RD::TextureFormat tf;
+		tf.format = directional_shadow.use_16_bits ? RD::DATA_FORMAT_D16_UNORM : RD::DATA_FORMAT_D32_SFLOAT;
+		tf.width = directional_shadow.size;
+		tf.height = directional_shadow.size;
+		tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+
+		directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
+		Vector<RID> fb_tex;
+		fb_tex.push_back(directional_shadow.depth);
+		directional_shadow.fb = RD::get_singleton()->framebuffer_create(fb_tex);
+	}
+}
+void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
 	p_size = nearest_power_of_2_templated(p_size);
 
-	if (directional_shadow.size == p_size) {
+	if (directional_shadow.size == p_size && directional_shadow.use_16_bits == p_16_bits) {
 		return;
 	}
 
@@ -3874,19 +3894,8 @@ void RendererSceneRenderRD::directional_shadow_atlas_set_size(int p_size) {
 		RD::get_singleton()->free(directional_shadow.depth);
 		_clear_shadow_shrink_stages(directional_shadow.shrink_stages);
 		directional_shadow.depth = RID();
+		_base_uniforms_changed();
 	}
-
-	if (p_size > 0) {
-		RD::TextureFormat tf;
-		tf.format = RD::DATA_FORMAT_R32_SFLOAT;
-		tf.width = p_size;
-		tf.height = p_size;
-		tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-
-		directional_shadow.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
-	}
-
-	_base_uniforms_changed();
 }
 
 void RendererSceneRenderRD::set_directional_shadow_count(int p_count) {
@@ -4056,29 +4065,6 @@ RendererSceneRenderRD::ShadowCubemap *RendererSceneRenderRD::_get_shadow_cubemap
 	return &shadow_cubemaps[p_size];
 }
 
-RendererSceneRenderRD::ShadowMap *RendererSceneRenderRD::_get_shadow_map(const Size2i &p_size) {
-	if (!shadow_maps.has(p_size)) {
-		ShadowMap sm;
-		{
-			RD::TextureFormat tf;
-			tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
-			tf.width = p_size.width;
-			tf.height = p_size.height;
-			tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
-
-			sm.depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
-		}
-
-		Vector<RID> fbtex;
-		fbtex.push_back(sm.depth);
-		sm.fb = RD::get_singleton()->framebuffer_create(fbtex);
-
-		shadow_maps[p_size] = sm;
-	}
-
-	return &shadow_maps[p_size];
-}
-
 //////////////////////////
 
 RID RendererSceneRenderRD::decal_instance_create(RID p_decal) {
@@ -7456,26 +7442,31 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 	ERR_FAIL_COND(!light_instance);
 
 	Rect2i atlas_rect;
-	RID atlas_texture;
+	uint32_t atlas_size;
+	RID atlas_fb;
 
 	bool using_dual_paraboloid = false;
 	bool using_dual_paraboloid_flip = false;
-	float znear = 0;
-	float zfar = 0;
 	RID render_fb;
 	RID render_texture;
-	float bias = 0;
-	float normal_bias = 0;
+	float zfar;
 
 	bool use_pancake = false;
-	bool use_linear_depth = false;
 	bool render_cubemap = false;
 	bool finalize_cubemap = false;
 
+	bool flip_y = false;
+
 	CameraMatrix light_projection;
 	Transform light_transform;
 
+	bool clear_region = true;
+	bool begin_texture = true;
+	bool end_texture = true;
+
 	if (storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) {
+		_update_directional_shadow_atlas();
+
 		//set pssm stuff
 		if (light_instance->last_scene_shadow_pass != scene_pass) {
 			light_instance->directional_rect = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, directional_shadow.current_light);
@@ -7492,6 +7483,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 		atlas_rect.size.width = light_instance->directional_rect.size.x;
 		atlas_rect.size.height = light_instance->directional_rect.size.y;
 
+		int pass_count = 1;
 		if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
 			atlas_rect.size.width /= 2;
 			atlas_rect.size.height /= 2;
@@ -7504,7 +7496,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 				atlas_rect.position.x += atlas_rect.size.width;
 				atlas_rect.position.y += atlas_rect.size.height;
 			}
-
+			pass_count = 4;
 		} else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
 			atlas_rect.size.height /= 2;
 
@@ -7512,6 +7504,7 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 			} else {
 				atlas_rect.position.y += atlas_rect.size.height;
 			}
+			pass_count = 2;
 		}
 
 		light_instance->shadow_transform[p_pass].atlas_rect = atlas_rect;
@@ -7519,15 +7512,15 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 		light_instance->shadow_transform[p_pass].atlas_rect.position /= directional_shadow.size;
 		light_instance->shadow_transform[p_pass].atlas_rect.size /= directional_shadow.size;
 
-		float bias_mult = light_instance->shadow_transform[p_pass].bias_scale;
 		zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
-		bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS) * bias_mult;
-		normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS) * bias_mult;
 
-		ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
-		render_fb = shadow_map->fb;
-		render_texture = shadow_map->depth;
-		atlas_texture = directional_shadow.depth;
+		render_fb = directional_shadow.fb;
+		render_texture = RID();
+		flip_y = true;
+
+		clear_region = false;
+		begin_texture = (directional_shadow.current_light == 1) && (p_pass == 0); //light is 1-index because it was incremented above
+		end_texture = (directional_shadow.current_light == directional_shadow.light_count) && (p_pass == pass_count - 1);
 
 	} else {
 		//set from shadow atlas
@@ -7536,6 +7529,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 		ERR_FAIL_COND(!shadow_atlas);
 		ERR_FAIL_COND(!shadow_atlas->shadow_owners.has(p_light));
 
+		_update_shadow_atlas(shadow_atlas);
+
 		uint32_t key = shadow_atlas->shadow_owners[p_light];
 
 		uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
@@ -7554,11 +7549,8 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 
 		atlas_rect.size.width = shadow_size;
 		atlas_rect.size.height = shadow_size;
-		atlas_texture = shadow_atlas->depth;
 
 		zfar = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_RANGE);
-		bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_BIAS);
-		normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS);
 
 		if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) {
 			if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
@@ -7571,6 +7563,10 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 				light_transform = light_instance->shadow_transform[0].transform;
 				render_cubemap = true;
 				finalize_cubemap = p_pass == 5;
+				atlas_fb = shadow_atlas->fb;
+
+				atlas_size = shadow_atlas->size;
+				clear_region = false;
 
 			} else {
 				light_projection = light_instance->shadow_transform[0].camera;
@@ -7581,22 +7577,17 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 
 				using_dual_paraboloid = true;
 				using_dual_paraboloid_flip = p_pass == 1;
-
-				ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
-				render_fb = shadow_map->fb;
-				render_texture = shadow_map->depth;
+				render_fb = shadow_atlas->fb;
+				flip_y = true;
 			}
 
 		} else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) {
 			light_projection = light_instance->shadow_transform[0].camera;
 			light_transform = light_instance->shadow_transform[0].transform;
 
-			ShadowMap *shadow_map = _get_shadow_map(atlas_rect.size);
-			render_fb = shadow_map->fb;
-			render_texture = shadow_map->depth;
+			render_fb = shadow_atlas->fb;
 
-			znear = light_instance->shadow_transform[0].camera.get_z_near();
-			use_linear_depth = true;
+			flip_y = true;
 		}
 	}
 
@@ -7605,25 +7596,19 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
 		_render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
 		if (finalize_cubemap) {
 			//reblit
-			atlas_rect.size.height /= 2;
-			storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, false);
-			atlas_rect.position.y += atlas_rect.size.height;
-			storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_texture, atlas_rect, light_projection.get_z_near(), light_projection.get_z_far(), 0.0, true);
+			Rect2 atlas_rect_norm = atlas_rect;
+			atlas_rect_norm.position.x /= float(atlas_size);
+			atlas_rect_norm.position.y /= float(atlas_size);
+			atlas_rect_norm.size.x /= float(atlas_size);
+			atlas_rect_norm.size.y /= float(atlas_size);
+			atlas_rect_norm.size.height /= 2;
+			storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), false);
+			atlas_rect_norm.position.y += atlas_rect_norm.size.height;
+			storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, light_projection.get_z_near(), light_projection.get_z_far(), true);
 		}
 	} else {
 		//render shadow
-
-		_render_shadow(render_fb, p_instances, light_projection, light_transform, zfar, bias, normal_bias, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_lod_threshold);
-
-		//copy to atlas
-		if (use_linear_depth) {
-			storage->get_effects()->copy_depth_to_rect_and_linearize(render_texture, atlas_texture, atlas_rect, true, znear, zfar);
-		} else {
-			storage->get_effects()->copy_depth_to_rect(render_texture, atlas_texture, atlas_rect, true);
-		}
-
-		//does not work from depth to color
-		//RD::get_singleton()->texture_copy(render_texture, atlas_texture, Vector3(0, 0, 0), Vector3(atlas_rect.position.x, atlas_rect.position.y, 0), Vector3(atlas_rect.size.x, atlas_rect.size.y, 1), 0, 0, 0, 0, true);
+		_render_shadow(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_lod_threshold, atlas_rect, flip_y, clear_region, begin_texture, end_texture);
 	}
 }
 
@@ -8404,6 +8389,9 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
 	sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1)));
 	sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1)));
 
+	directional_shadow.size = GLOBAL_GET("rendering/quality/directional_shadow/size");
+	directional_shadow.use_16_bits = GLOBAL_GET("rendering/quality/directional_shadow/16_bits");
+
 	uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
 
 	low_end = GLOBAL_GET("rendering/quality/rd_renderer/use_low_end_renderer");
@@ -8877,9 +8865,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
 }
 
 RendererSceneRenderRD::~RendererSceneRenderRD() {
-	for (Map<Vector2i, ShadowMap>::Element *E = shadow_maps.front(); E; E = E->next()) {
-		RD::get_singleton()->free(E->get().depth);
-	}
 	for (Map<int, ShadowCubemap>::Element *E = shadow_cubemaps.front(); E; E = E->next()) {
 		RD::get_singleton()->free(E->get().cubemap);
 	}

+ 10 - 11
servers/rendering/renderer_rd/renderer_scene_render_rd.h

@@ -110,7 +110,7 @@ protected:
 	void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used);
 
 	virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_cluster_max_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
-	virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
+	virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_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) = 0;
 	virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
 	virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
 	virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
@@ -572,6 +572,7 @@ private:
 		uint32_t smallest_subdiv = 0;
 
 		int size = 0;
+		bool use_16_bits = false;
 
 		RID depth;
 		RID fb; //for copying
@@ -583,6 +584,8 @@ private:
 
 	RID_Owner<ShadowAtlas> shadow_atlas_owner;
 
+	void _update_shadow_atlas(ShadowAtlas *shadow_atlas);
+
 	bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
 
 	RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set
@@ -603,9 +606,11 @@ private:
 
 	struct DirectionalShadow {
 		RID depth;
+		RID fb; //when renderign direct
 
 		int light_count = 0;
 		int size = 0;
+		bool use_16_bits = false;
 		int current_light = 0;
 
 		Vector<ShadowShrinkStage> shrink_stages;
@@ -615,6 +620,8 @@ private:
 	void _allocate_shadow_shrink_stages(RID p_base, int p_base_size, Vector<ShadowShrinkStage> &shrink_stages, uint32_t p_target_size);
 	void _clear_shadow_shrink_stages(Vector<ShadowShrinkStage> &shrink_stages);
 
+	void _update_directional_shadow_atlas();
+
 	/* SHADOW CUBEMAPS */
 
 	struct ShadowCubemap {
@@ -625,14 +632,6 @@ private:
 	Map<int, ShadowCubemap> shadow_cubemaps;
 	ShadowCubemap *_get_shadow_cubemap(int p_size);
 
-	struct ShadowMap {
-		RID depth;
-		RID fb;
-	};
-
-	Map<Vector2i, ShadowMap> shadow_maps;
-	ShadowMap *_get_shadow_map(const Size2i &p_size);
-
 	void _create_shadow_cubemaps();
 
 	/* LIGHT INSTANCE */
@@ -1555,7 +1554,7 @@ public:
 	/* SHADOW ATLAS API */
 
 	RID shadow_atlas_create();
-	void shadow_atlas_set_size(RID p_atlas, int p_size);
+	void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false);
 	void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision);
 	bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version);
 	_FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) {
@@ -1576,7 +1575,7 @@ public:
 		return Size2(atlas->size, atlas->size);
 	}
 
-	void directional_shadow_atlas_set_size(int p_size);
+	void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false);
 	int get_directional_light_shadow_size(RID p_light_intance);
 	void set_directional_shadow_count(int p_count);
 

+ 30 - 15
servers/rendering/renderer_rd/shaders/cube_to_dp.glsl

@@ -1,33 +1,48 @@
-#[compute]
+#[vertex]
 
 #version 450
 
 VERSION_DEFINES
 
-layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+layout(push_constant, binding = 1, std430) uniform Params {
+	float z_far;
+	float z_near;
+	bool z_flip;
+	uint pad;
+	vec4 screen_rect;
+}
+params;
+
+layout(location = 0) out vec2 uv_interp;
+
+void main() {
+	vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
+	uv_interp = base_arr[gl_VertexIndex];
+	vec2 screen_pos = uv_interp * params.screen_rect.zw + params.screen_rect.xy;
+	gl_Position = vec4(screen_pos * 2.0 - 1.0, 0.0, 1.0);
+}
+
+#[fragment]
+
+#version 450
+
+VERSION_DEFINES
+
+layout(location = 0) in vec2 uv_interp;
 
 layout(set = 0, binding = 0) uniform samplerCube source_cube;
 
 layout(push_constant, binding = 1, std430) uniform Params {
-	ivec2 screen_size;
-	ivec2 offset;
-	float bias;
 	float z_far;
 	float z_near;
 	bool z_flip;
+	uint pad;
+	vec4 screen_rect;
 }
 params;
 
-layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer;
-
 void main() {
-	ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
-	if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing
-		return;
-	}
-
-	vec2 pixel_size = 1.0 / vec2(params.screen_size);
-	vec2 uv = (vec2(pos) + 0.5) * pixel_size;
+	vec2 uv = uv_interp;
 
 	vec3 normal = vec3(uv * 2.0 - 1.0, 0.0);
 
@@ -65,5 +80,5 @@ void main() {
 	float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near));
 	depth = (linear_depth * depth_fix) / params.z_far;
 
-	imageStore(depth_buffer, pos + params.offset, vec4(depth));
+	gl_FragDepth = depth;
 }

+ 2 - 1
servers/rendering/renderer_rd/shaders/gi.glsl

@@ -655,7 +655,8 @@ void main() {
 		return;
 	}
 
-	vec4 ambient_light = vec4(0.0), reflection_light = vec4(0.0);
+	vec4 ambient_light = vec4(0.0);
+	vec4 reflection_light = vec4(0.0);
 
 	vec3 vertex = reconstruct_position(pos);
 	vertex.y = -vertex.y;

+ 3 - 4
servers/rendering/renderer_rd/shaders/resolve.glsl

@@ -71,19 +71,19 @@ void main() {
 	group1.y = texelFetch(source_depth, pos, 1).r;
 
 	//4X
-	if (params.sample_count <= 4) {
+	if (params.sample_count >= 4) {
 		group1.z = texelFetch(source_depth, pos, 2).r;
 		group1.w = texelFetch(source_depth, pos, 3).r;
 	}
 	//8X
-	if (params.sample_count <= 8) {
+	if (params.sample_count >= 8) {
 		group2.x = texelFetch(source_depth, pos, 4).r;
 		group2.y = texelFetch(source_depth, pos, 5).r;
 		group2.z = texelFetch(source_depth, pos, 6).r;
 		group2.w = texelFetch(source_depth, pos, 7).r;
 	}
 	//16X
-	if (params.sample_count <= 16) {
+	if (params.sample_count >= 16) {
 		group3.x = texelFetch(source_depth, pos, 8).r;
 		group3.y = texelFetch(source_depth, pos, 9).r;
 		group3.z = texelFetch(source_depth, pos, 10).r;
@@ -115,7 +115,6 @@ void main() {
 		}
 		if (freq.w < min_f) {
 			best_index = 3;
-			min_f = freq.w;
 		}
 	} else if (params.sample_count == 8) {
 		vec4 freq0 = vec4(equal(group1, vec4(group1.x)));

+ 1 - 1
servers/rendering/renderer_rd/shaders/scene_forward.glsl

@@ -1282,7 +1282,7 @@ float light_process_spot_shadow(uint idx, vec3 vertex, vec3 normal) {
 		} else {
 #endif
 			//hard shadow
-			vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, z_norm, 1.0);
+			vec4 shadow_uv = vec4(splane.xy * spot_lights.data[idx].atlas_rect.zw + spot_lights.data[idx].atlas_rect.xy, splane.z, 1.0);
 
 			shadow = sample_pcf_shadow(shadow_atlas, spot_lights.data[idx].soft_shadow_scale * scene_data.shadow_atlas_pixel_size, shadow_uv);
 #ifdef USE_SOFT_SHADOWS

+ 30 - 30
servers/rendering/renderer_rd/shaders/scene_forward_inc.glsl

@@ -153,22 +153,22 @@ scene_data;
 #define INSTANCE_FLAGS_SKELETON (1 << 19)
 #define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 20)
 
-layout(set = 0, binding = 5, std430) restrict readonly buffer OmniLights {
+layout(set = 0, binding = 4, std430) restrict readonly buffer OmniLights {
 	LightData data[];
 }
 omni_lights;
 
-layout(set = 0, binding = 6, std430) restrict readonly buffer SpotLights {
+layout(set = 0, binding = 5, std430) restrict readonly buffer SpotLights {
 	LightData data[];
 }
 spot_lights;
 
-layout(set = 0, binding = 7) buffer restrict readonly ReflectionProbeData {
+layout(set = 0, binding = 6) buffer restrict readonly ReflectionProbeData {
 	ReflectionData data[];
 }
 reflections;
 
-layout(set = 0, binding = 8, std140) uniform DirectionalLights {
+layout(set = 0, binding = 7, std140) uniform DirectionalLights {
 	DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
 }
 directional_lights;
@@ -180,7 +180,7 @@ struct Lightmap {
 	mat3 normal_xform;
 };
 
-layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps {
+layout(set = 0, binding = 8, std140) restrict readonly buffer Lightmaps {
 	Lightmap data[];
 }
 lightmaps;
@@ -189,22 +189,20 @@ struct LightmapCapture {
 	vec4 sh[9];
 };
 
-layout(set = 0, binding = 11, std140) restrict readonly buffer LightmapCaptures {
+layout(set = 0, binding = 9, std140) restrict readonly buffer LightmapCaptures {
 	LightmapCapture data[];
 }
 lightmap_captures;
 
-layout(set = 0, binding = 12) uniform texture2D decal_atlas;
-layout(set = 0, binding = 13) uniform texture2D decal_atlas_srgb;
+layout(set = 0, binding = 10) uniform texture2D decal_atlas;
+layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb;
 
-layout(set = 0, binding = 14, std430) restrict readonly buffer Decals {
+layout(set = 0, binding = 12, std430) restrict readonly buffer Decals {
 	DecalData data[];
 }
 decals;
 
-layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas;
-
-layout(set = 0, binding = 16, std430) restrict readonly buffer GlobalVariableData {
+layout(set = 0, binding = 13, std430) restrict readonly buffer GlobalVariableData {
 	vec4 data[];
 }
 global_variables;
@@ -218,7 +216,7 @@ struct SDFGIProbeCascadeData {
 	float to_cell; // 1/bounds * grid_size
 };
 
-layout(set = 0, binding = 17, std140) uniform SDFGI {
+layout(set = 0, binding = 14, std140) uniform SDFGI {
 	vec3 grid_size;
 	uint max_cascades;
 
@@ -268,13 +266,15 @@ layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas;
 
 layout(set = 1, binding = 2) uniform texture2D shadow_atlas;
 
-layout(set = 1, binding = 3) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
+layout(set = 1, binding = 3) uniform texture2D directional_shadow_atlas;
+
+layout(set = 1, binding = 4) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
 
 #ifndef LOW_END_MODE
-layout(set = 1, binding = 4) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
+layout(set = 1, binding = 5) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
 #endif
 
-layout(set = 1, binding = 5, std430) buffer restrict readonly ClusterBuffer {
+layout(set = 1, binding = 6, std430) buffer restrict readonly ClusterBuffer {
 	uint data[];
 }
 cluster_buffer;
@@ -283,10 +283,10 @@ cluster_buffer;
 
 #ifdef MODE_RENDER_SDF
 
-layout(r16ui, set = 1, binding = 6) uniform restrict writeonly uimage3D albedo_volume_grid;
-layout(r32ui, set = 1, binding = 7) uniform restrict writeonly uimage3D emission_grid;
-layout(r32ui, set = 1, binding = 8) uniform restrict writeonly uimage3D emission_aniso_grid;
-layout(r32ui, set = 1, binding = 9) uniform restrict uimage3D geom_facing_grid;
+layout(r16ui, set = 1, binding = 7) uniform restrict writeonly uimage3D albedo_volume_grid;
+layout(r32ui, set = 1, binding = 8) uniform restrict writeonly uimage3D emission_grid;
+layout(r32ui, set = 1, binding = 9) uniform restrict writeonly uimage3D emission_aniso_grid;
+layout(r32ui, set = 1, binding = 10) uniform restrict uimage3D geom_facing_grid;
 
 //still need to be present for shaders that use it, so remap them to something
 #define depth_buffer shadow_atlas
@@ -295,17 +295,17 @@ layout(r32ui, set = 1, binding = 9) uniform restrict uimage3D geom_facing_grid;
 
 #else
 
-layout(set = 1, binding = 6) uniform texture2D depth_buffer;
-layout(set = 1, binding = 7) uniform texture2D color_buffer;
+layout(set = 1, binding = 7) uniform texture2D depth_buffer;
+layout(set = 1, binding = 8) uniform texture2D color_buffer;
 
 #ifndef LOW_END_MODE
 
-layout(set = 1, binding = 8) uniform texture2D normal_roughness_buffer;
-layout(set = 1, binding = 9) uniform texture2D ao_buffer;
-layout(set = 1, binding = 10) uniform texture2D ambient_buffer;
-layout(set = 1, binding = 11) uniform texture2D reflection_buffer;
-layout(set = 1, binding = 12) uniform texture2DArray sdfgi_lightprobe_texture;
-layout(set = 1, binding = 13) uniform texture3D sdfgi_occlusion_cascades;
+layout(set = 1, binding = 9) uniform texture2D normal_roughness_buffer;
+layout(set = 1, binding = 10) uniform texture2D ao_buffer;
+layout(set = 1, binding = 11) uniform texture2D ambient_buffer;
+layout(set = 1, binding = 12) uniform texture2D reflection_buffer;
+layout(set = 1, binding = 13) uniform texture2DArray sdfgi_lightprobe_texture;
+layout(set = 1, binding = 14) uniform texture3D sdfgi_occlusion_cascades;
 
 struct GIProbeData {
 	mat4 xform;
@@ -323,12 +323,12 @@ struct GIProbeData {
 	uint mipmaps;
 };
 
-layout(set = 1, binding = 14, std140) uniform GIProbes {
+layout(set = 1, binding = 15, std140) uniform GIProbes {
 	GIProbeData data[MAX_GI_PROBES];
 }
 gi_probes;
 
-layout(set = 1, binding = 15) uniform texture3D volumetric_fog_texture;
+layout(set = 1, binding = 16) uniform texture3D volumetric_fog_texture;
 
 #endif // LOW_END_MODE
 

+ 2 - 2
servers/rendering/renderer_scene.h

@@ -95,7 +95,7 @@ public:
 	virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0;
 	virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0;
 
-	virtual void directional_shadow_atlas_set_size(int p_size) = 0;
+	virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
 
 	/* SKY API */
 
@@ -173,7 +173,7 @@ public:
 	virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
 
 	virtual RID shadow_atlas_create() = 0;
-	virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
+	virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = false) = 0;
 	virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
 
 	/* Render Buffers */

+ 2 - 2
servers/rendering/renderer_scene_cull.h

@@ -947,7 +947,7 @@ public:
 
 #define PASSBASE scene_render
 
-	PASS1(directional_shadow_atlas_set_size, int)
+	PASS2(directional_shadow_atlas_set_size, int, bool)
 	PASS1(gi_probe_set_quality, RS::GIProbeQuality)
 
 	/* SKY API */
@@ -1030,7 +1030,7 @@ public:
 
 	/* Shadow Atlas */
 	PASS0R(RID, shadow_atlas_create)
-	PASS2(shadow_atlas_set_size, RID, int)
+	PASS3(shadow_atlas_set_size, RID, int, bool)
 	PASS3(shadow_atlas_set_quadrant_subdivision, RID, int, int)
 
 	PASS1(set_debug_draw_mode, RS::ViewportDebugDraw)

+ 2 - 2
servers/rendering/renderer_scene_render.h

@@ -73,11 +73,11 @@ public:
 
 	virtual RID
 	shadow_atlas_create() = 0;
-	virtual void shadow_atlas_set_size(RID p_atlas, int p_size) = 0;
+	virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = false) = 0;
 	virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
 	virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
 
-	virtual void directional_shadow_atlas_set_size(int p_size) = 0;
+	virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
 	virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
 	virtual void set_directional_shadow_count(int p_count) = 0;
 

+ 3 - 2
servers/rendering/renderer_viewport.cpp

@@ -831,13 +831,14 @@ void RendererViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas
 	viewport->canvas_map[p_canvas].sublayer = p_sublayer;
 }
 
-void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
+void RendererViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits) {
 	Viewport *viewport = viewport_owner.getornull(p_viewport);
 	ERR_FAIL_COND(!viewport);
 
 	viewport->shadow_atlas_size = p_size;
+	viewport->shadow_atlas_16_bits = p_16_bits;
 
-	RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size);
+	RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size, viewport->shadow_atlas_16_bits);
 }
 
 void RendererViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {

+ 2 - 1
servers/rendering/renderer_viewport.h

@@ -81,6 +81,7 @@ public:
 
 		RID shadow_atlas;
 		int shadow_atlas_size;
+		bool shadow_atlas_16_bits = false;
 
 		bool sdf_active;
 
@@ -217,7 +218,7 @@ public:
 	void viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform);
 	void viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer);
 
-	void viewport_set_shadow_atlas_size(RID p_viewport, int p_size);
+	void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false);
 	void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv);
 
 	void viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa);

+ 1 - 0
servers/rendering/rendering_device.cpp

@@ -745,6 +745,7 @@ void RenderingDevice::_bind_methods() {
 	BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE);
 
 	BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params)
+	BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR_REGION); //start rendering and clear the framebuffer (supply params)
 	BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared)
 	BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it
 	BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously)

+ 2 - 1
servers/rendering/rendering_device.h

@@ -931,7 +931,8 @@ public:
 	/********************/
 
 	enum InitialAction {
-		INITIAL_ACTION_CLEAR, //start rendering and clear the framebuffer (supply params)
+		INITIAL_ACTION_CLEAR, //start rendering and clear the whole framebuffer (region or not) (supply params)
+		INITIAL_ACTION_CLEAR_REGION, //start rendering and clear the framebuffer in the specified region (supply params)
 		INITIAL_ACTION_KEEP, //start rendering, but keep attached color texture contents (depth will be cleared)
 		INITIAL_ACTION_DROP, //start rendering, ignore what is there, just write above it
 		INITIAL_ACTION_CONTINUE, //continue rendering (framebuffer must have been left in "continue" state as final action previously)

+ 2 - 2
servers/rendering/rendering_server_default.h

@@ -551,7 +551,7 @@ public:
 
 	BIND2(viewport_set_global_canvas_transform, RID, const Transform2D &)
 	BIND4(viewport_set_canvas_stacking, RID, RID, int, int)
-	BIND2(viewport_set_shadow_atlas_size, RID, int)
+	BIND3(viewport_set_shadow_atlas_size, RID, int, bool)
 	BIND3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale)
 	BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
 	BIND2(viewport_set_msaa, RID, ViewportMSAA)
@@ -572,7 +572,7 @@ public:
 //from now on, calls forwarded to this singleton
 #define BINDBASE RSG::scene
 
-	BIND1(directional_shadow_atlas_set_size, int)
+	BIND2(directional_shadow_atlas_set_size, int, bool)
 	BIND1(gi_probe_set_quality, GIProbeQuality)
 
 	/* SKY API */

+ 2 - 2
servers/rendering/rendering_server_wrap_mt.h

@@ -445,7 +445,7 @@ public:
 
 	FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
 	FUNC4(viewport_set_canvas_stacking, RID, RID, int, int)
-	FUNC2(viewport_set_shadow_atlas_size, RID, int)
+	FUNC3(viewport_set_shadow_atlas_size, RID, int, bool)
 	FUNC3(viewport_set_sdf_oversize_and_scale, RID, ViewportSDFOversize, ViewportSDFScale)
 
 	FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
@@ -470,7 +470,7 @@ public:
 		return rendering_server->viewport_get_measured_render_time_gpu(p_viewport);
 	}
 
-	FUNC1(directional_shadow_atlas_set_size, int)
+	FUNC2(directional_shadow_atlas_set_size, int, bool)
 
 	/* SKY API */
 

+ 2 - 13
servers/rendering_server.cpp

@@ -1661,7 +1661,7 @@ void RenderingServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &RenderingServer::viewport_set_transparent_background);
 	ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &RenderingServer::viewport_set_global_canvas_transform);
 	ClassDB::bind_method(D_METHOD("viewport_set_canvas_stacking", "viewport", "canvas", "layer", "sublayer"), &RenderingServer::viewport_set_canvas_stacking);
-	ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &RenderingServer::viewport_set_shadow_atlas_size);
+	ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size", "use_16_bits"), &RenderingServer::viewport_set_shadow_atlas_size, DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &RenderingServer::viewport_set_shadow_atlas_quadrant_subdivision);
 	ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &RenderingServer::viewport_set_msaa);
 	ClassDB::bind_method(D_METHOD("viewport_set_use_debanding", "viewport", "enable"), &RenderingServer::viewport_set_use_debanding);
@@ -2272,6 +2272,7 @@ RenderingServer::RenderingServer() {
 	GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality", 2);
 	GLOBAL_DEF("rendering/quality/directional_shadow/soft_shadow_quality.mobile", 0);
 	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/soft_shadow_quality", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/soft_shadow_quality", PROPERTY_HINT_ENUM, "Hard (Fastest),Soft Low (Fast),Soft Medium (Average),Soft High (Slow),Soft Ultra (Slowest)"));
+	GLOBAL_DEF("rendering/quality/directional_shadow/16_bits", true);
 
 	GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality", 2);
 	GLOBAL_DEF("rendering/quality/shadows/soft_shadow_quality.mobile", 0);
@@ -2282,18 +2283,6 @@ RenderingServer::RenderingServer() {
 	GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer", false);
 	GLOBAL_DEF("rendering/quality/rd_renderer/use_low_end_renderer.mobile", true);
 
-	GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
-	GLOBAL_DEF("rendering/quality/shadow_atlas/size.mobile", 2048);
-	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
-	GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 1);
-	GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2);
-	GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3);
-	GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4);
-	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
-	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
-	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
-	ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
-
 	GLOBAL_DEF("rendering/quality/reflections/roughness_layers", 8);
 	GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
 	GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections.mobile", false);

+ 2 - 2
servers/rendering_server.h

@@ -798,7 +798,7 @@ public:
 
 	virtual void viewport_set_sdf_oversize_and_scale(RID p_viewport, ViewportSDFOversize p_oversize, ViewportSDFScale p_scale) = 0;
 
-	virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size) = 0;
+	virtual void viewport_set_shadow_atlas_size(RID p_viewport, int p_size, bool p_16_bits = false) = 0;
 	virtual void viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) = 0;
 
 	enum ViewportMSAA {
@@ -868,7 +868,7 @@ public:
 	virtual float viewport_get_measured_render_time_cpu(RID p_viewport) const = 0;
 	virtual float viewport_get_measured_render_time_gpu(RID p_viewport) const = 0;
 
-	virtual void directional_shadow_atlas_set_size(int p_size) = 0;
+	virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = false) = 0;
 
 	/* SKY API */