Browse Source

Add render buffer support to screen space effects

Bastiaan Olij 2 years ago
parent
commit
694c8ec273

File diff suppressed because it is too large
+ 299 - 408
servers/rendering/renderer_rd/effects/ss_effects.cpp


+ 29 - 48
servers/rendering/renderer_rd/effects/ss_effects.h

@@ -48,6 +48,26 @@
 #include "servers/rendering/renderer_scene_render.h"
 #include "servers/rendering_server.h"
 
+#define RB_SCOPE_SSDS SNAME("rb_ssds")
+#define RB_SCOPE_SSIL SNAME("rb_ssil")
+#define RB_SCOPE_SSAO SNAME("rb_ssao")
+#define RB_SCOPE_SSR SNAME("rb_ssr")
+
+#define RB_LINEAR_DEPTH SNAME("linear_depth")
+#define RB_FINAL SNAME("final")
+#define RB_LAST_FRAME SNAME("last_frame")
+#define RB_DEINTERLEAVED SNAME("deinterleaved")
+#define RB_DEINTERLEAVED_PONG SNAME("deinterleaved_pong")
+#define RB_EDGES SNAME("edges")
+#define RB_IMPORTANCE_MAP SNAME("importance_map")
+#define RB_IMPORTANCE_PONG SNAME("importance_pong")
+
+#define RB_DEPTH_SCALED SNAME("depth_scaled")
+#define RB_NORMAL_SCALED SNAME("normal_scaled")
+#define RB_BLUR_RADIUS SNAME("blur_radius")
+#define RB_INTERMEDIATE SNAME("intermediate")
+#define RB_OUTPUT SNAME("output")
+
 class RenderSceneBuffersRD;
 
 namespace RendererRD {
@@ -64,7 +84,7 @@ public:
 
 	/* SS Downsampler */
 
-	void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, bool p_invalidate_uniform_set, Size2i p_full_screen_size, const Projection &p_projection);
+	void downsample_depth(Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_view, const Projection &p_projection);
 
 	/* SSIL */
 	void ssil_set_quality(RS::EnvironmentSSILQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to);
@@ -75,23 +95,6 @@ public:
 		int buffer_height;
 		int half_buffer_width;
 		int half_buffer_height;
-
-		RID ssil_final;
-		RID deinterleaved;
-		Vector<RID> deinterleaved_slices;
-		RID pong;
-		Vector<RID> pong_slices;
-		RID edges;
-		Vector<RID> edges_slices;
-		RID importance_map[2];
-		RID depth_texture_view;
-
-		RID last_frame;
-		Vector<RID> last_frame_slices;
-
-		RID gather_uniform_set;
-		RID importance_map_uniform_set;
-		RID projection_uniform_set;
 	};
 
 	struct SSILSettings {
@@ -103,9 +106,8 @@ public:
 		Size2i full_screen_size;
 	};
 
-	void ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth);
-	void screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings);
-	void ssil_free(SSILRenderBuffers &p_ssil_buffers);
+	void ssil_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings);
+	void screen_space_indirect_lighting(Ref<RenderSceneBuffersRD> p_render_buffers, SSILRenderBuffers &p_ssil_buffers, uint32_t p_view, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings);
 
 	/* SSAO */
 	void ssao_set_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size, float p_adaptive_target, int p_blur_passes, float p_fadeout_from, float p_fadeout_to);
@@ -116,17 +118,6 @@ public:
 		int buffer_height;
 		int half_buffer_width;
 		int half_buffer_height;
-
-		RID ao_deinterleaved;
-		Vector<RID> ao_deinterleaved_slices;
-		RID ao_pong;
-		Vector<RID> ao_pong_slices;
-		RID ao_final;
-		RID importance_map[2];
-		RID depth_texture_view;
-
-		RID gather_uniform_set;
-		RID importance_map_uniform_set;
 	};
 
 	struct SSAOSettings {
@@ -140,9 +131,8 @@ public:
 		Size2i full_screen_size;
 	};
 
-	void ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth);
-	void generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings);
-	void ssao_free(SSAORenderBuffers &p_ssao_buffers);
+	void ssao_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings);
+	void generate_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, SSAORenderBuffers &p_ssao_buffers, uint32_t p_view, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings);
 
 	/* Screen Space Reflection */
 	void ssr_set_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality);
@@ -150,18 +140,10 @@ public:
 	struct SSRRenderBuffers {
 		Size2i size;
 		RenderingServer::EnvironmentSSRRoughnessQuality roughness_quality = RenderingServer::ENV_SSR_ROUGHNESS_QUALITY_DISABLED;
-
-		RID normal_scaled;
-		RID depth_scaled;
-		RID blur_radius[2];
-		RID intermediate;
-		RID output;
-		RID output_slices[RendererSceneRender::MAX_RENDER_VIEWS];
 	};
 
-	void ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format, const Size2i &p_screen_size, const uint32_t p_view_count);
-	void screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, const RID *p_metallic_slices, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets);
-	void ssr_free(SSRRenderBuffers &p_ssr_buffers);
+	void ssr_allocate_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format);
+	void screen_space_reflection(Ref<RenderSceneBuffersRD> p_render_buffers, SSRRenderBuffers &p_ssr_buffers, const RID *p_normal_roughness_slices, const RID *p_metallic_slices, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const Projection *p_projections, const Vector3 *p_eye_offsets);
 
 	/* subsurface scattering */
 	void sss_set_quality(RS::SubSurfaceScatteringQuality p_quality);
@@ -223,7 +205,6 @@ private:
 		SSEffectsDownsamplePushConstant downsample_push_constant;
 		SsEffectsDownsampleShaderRD downsample_shader;
 		RID downsample_shader_version;
-		RID downsample_uniform_set;
 		bool used_half_size_last_frame = false;
 		bool used_mips_last_frame = false;
 		bool used_full_mips_last_frame = false;
@@ -332,7 +313,7 @@ private:
 		RID pipelines[SSIL_MAX];
 	} ssil;
 
-	void gather_ssil(RD::ComputeListID p_compute_list, const Vector<RID> p_ssil_slices, const Vector<RID> p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set);
+	void gather_ssil(RD::ComputeListID p_compute_list, const RID *p_ssil_slices, const RID *p_edges_slices, const SSILSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set, RID p_projection_uniform_set);
 
 	/* SSAO */
 
@@ -426,7 +407,7 @@ private:
 		RID pipelines[SSAO_MAX];
 	} ssao;
 
-	void gather_ssao(RD::ComputeListID p_compute_list, const Vector<RID> p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set);
+	void gather_ssao(RD::ComputeListID p_compute_list, const RID *p_ao_slices, const SSAOSettings &p_settings, bool p_adaptive_base_pass, RID p_gather_uniform_set, RID p_importance_map_uniform_set);
 
 	/* Screen Space Reflection */
 

+ 66 - 86
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

@@ -108,6 +108,10 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::free_data() {
 	// JIC, should already have been cleared
 	if (render_buffers) {
 		render_buffers->clear_context(RB_SCOPE_FORWARD_CLUSTERED);
+		render_buffers->clear_context(RB_SCOPE_SSDS);
+		render_buffers->clear_context(RB_SCOPE_SSIL);
+		render_buffers->clear_context(RB_SCOPE_SSAO);
+		render_buffers->clear_context(RB_SCOPE_SSR);
 	}
 
 	if (cluster_builder) {
@@ -118,21 +122,6 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::free_data() {
 	if (!render_sdfgi_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_sdfgi_uniform_set)) {
 		RD::get_singleton()->free(render_sdfgi_uniform_set);
 	}
-
-	if (ss_effects_data.linear_depth.is_valid()) {
-		RD::get_singleton()->free(ss_effects_data.linear_depth);
-		ss_effects_data.linear_depth = RID();
-		ss_effects_data.linear_depth_slices.clear();
-	}
-
-	if (ss_effects_data.downsample_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(ss_effects_data.downsample_uniform_set)) {
-		RD::get_singleton()->free(ss_effects_data.downsample_uniform_set);
-		ss_effects_data.downsample_uniform_set = RID();
-	}
-
-	RenderForwardClustered::get_singleton()->get_ss_effects()->ssao_free(ss_effects_data.ssao);
-	RenderForwardClustered::get_singleton()->get_ss_effects()->ssil_free(ss_effects_data.ssil);
-	RenderForwardClustered::get_singleton()->get_ss_effects()->ssr_free(ss_effects_data.ssr);
 }
 
 void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RenderSceneBuffersRD *p_render_buffers) {
@@ -1252,7 +1241,7 @@ void RenderForwardClustered::setup_added_decal(const Transform3D &p_transform, c
 
 /* Render scene */
 
-void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection) {
+void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections) {
 	ERR_FAIL_NULL(ss_effects);
 	ERR_FAIL_COND(p_render_buffers.is_null());
 	ERR_FAIL_COND(p_environment.is_null());
@@ -1271,11 +1260,14 @@ void RenderForwardClustered::_process_ssao(Ref<RenderSceneBuffersRD> p_render_bu
 	settings.sharpness = environment_get_ssao_sharpness(p_environment);
 	settings.full_screen_size = p_render_buffers->get_internal_size();
 
-	ss_effects->ssao_allocate_buffers(rb_data->ss_effects_data.ssao, settings, rb_data->ss_effects_data.linear_depth);
-	ss_effects->generate_ssao(rb_data->ss_effects_data.ssao, p_normal_buffer, p_projection, settings);
+	ss_effects->ssao_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssao, settings);
+
+	for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) {
+		ss_effects->generate_ssao(p_render_buffers, rb_data->ss_effects_data.ssao, v, p_normal_buffers[v], p_projections[v], settings);
+	}
 }
 
-void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform) {
+void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections, const Transform3D &p_transform) {
 	ERR_FAIL_NULL(ss_effects);
 	ERR_FAIL_COND(p_render_buffers.is_null());
 	ERR_FAIL_COND(p_environment.is_null());
@@ -1292,36 +1284,46 @@ void RenderForwardClustered::_process_ssil(Ref<RenderSceneBuffersRD> p_render_bu
 	settings.normal_rejection = environment_get_ssil_normal_rejection(p_environment);
 	settings.full_screen_size = p_render_buffers->get_internal_size();
 
-	Projection correction;
-	correction.set_depth_correction(true);
-	Projection projection = correction * p_projection;
+	ss_effects->ssil_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssil, settings);
+
 	Transform3D transform = p_transform;
 	transform.set_origin(Vector3(0.0, 0.0, 0.0));
-	Projection last_frame_projection = rb_data->ss_effects_data.last_frame_projection * Projection(rb_data->ss_effects_data.last_frame_transform.affine_inverse()) * Projection(transform) * projection.inverse();
 
-	ss_effects->ssil_allocate_buffers(rb_data->ss_effects_data.ssil, settings, rb_data->ss_effects_data.linear_depth);
-	ss_effects->screen_space_indirect_lighting(rb_data->ss_effects_data.ssil, p_normal_buffer, p_projection, last_frame_projection, settings);
-	rb_data->ss_effects_data.last_frame_projection = projection;
+	for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) {
+		Projection correction;
+		correction.set_depth_correction(true);
+		Projection projection = correction * p_projections[v];
+		Projection last_frame_projection = rb_data->ss_effects_data.last_frame_projections[v] * Projection(rb_data->ss_effects_data.last_frame_transform.affine_inverse()) * Projection(transform) * projection.inverse();
+
+		ss_effects->screen_space_indirect_lighting(p_render_buffers, rb_data->ss_effects_data.ssil, v, p_normal_buffers[v], p_projections[v], last_frame_projection, settings);
+
+		rb_data->ss_effects_data.last_frame_projections[v] = projection;
+	}
 	rb_data->ss_effects_data.last_frame_transform = transform;
 }
 
 void RenderForwardClustered::_copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers) {
 	ERR_FAIL_COND(p_render_buffers.is_null());
 
-	Ref<RenderBufferDataForwardClustered> rb_data = p_render_buffers->get_custom_data(RB_SCOPE_FORWARD_CLUSTERED);
-	ERR_FAIL_COND(rb_data.is_null());
-
-	if (rb_data->ss_effects_data.ssil.last_frame.is_valid()) {
+	if (p_render_buffers->has_texture(RB_SCOPE_SSIL, RB_LAST_FRAME)) {
 		Size2i size = p_render_buffers->get_internal_size();
-		RID texture = p_render_buffers->get_internal_texture();
-		copy_effects->copy_to_rect(texture, rb_data->ss_effects_data.ssil.last_frame, Rect2i(0, 0, size.x, size.y));
-
-		int width = size.x;
-		int height = size.y;
-		for (int i = 0; i < rb_data->ss_effects_data.ssil.last_frame_slices.size() - 1; i++) {
-			width = MAX(1, width >> 1);
-			height = MAX(1, height >> 1);
-			copy_effects->make_mipmap(rb_data->ss_effects_data.ssil.last_frame_slices[i], rb_data->ss_effects_data.ssil.last_frame_slices[i + 1], Size2i(width, height));
+		uint32_t mipmaps = p_render_buffers->get_texture_format(RB_SCOPE_SSIL, RB_LAST_FRAME).mipmaps;
+		for (uint32_t v = 0; v < p_render_buffers->get_view_count(); v++) {
+			RID source = p_render_buffers->get_internal_texture(v);
+			RID dest = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_LAST_FRAME, v, 0);
+			copy_effects->copy_to_rect(source, dest, Rect2i(0, 0, size.x, size.y));
+
+			int width = size.x;
+			int height = size.y;
+			for (uint32_t m = 1; m < mipmaps; m++) {
+				width = MAX(1, width >> 1);
+				height = MAX(1, height >> 1);
+
+				source = dest;
+				dest = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_LAST_FRAME, v, m);
+
+				copy_effects->make_mipmap(source, dest, Size2i(width, height));
+			}
 		}
 	}
 }
@@ -1421,41 +1423,23 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
 	}
 
 	if (rb_data.is_valid() && ss_effects) {
-		if (p_use_ssao || p_use_ssil) {
-			Size2i size = rb->get_internal_size();
+		// Note, in multiview we're allocating buffers for each eye/view we're rendering.
+		// This should allow most of the processing to happen in parallel even if we're doing
+		// drawcalls per eye/view. It will all sync up at the barrier.
 
-			bool invalidate_uniform_set = false;
-			if (rb_data->ss_effects_data.linear_depth.is_null()) {
-				RD::TextureFormat tf;
-				tf.format = RD::DATA_FORMAT_R16_SFLOAT;
-				tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
-				tf.width = (size.x + 1) / 2;
-				tf.height = (size.y + 1) / 2;
-				tf.mipmaps = 5;
-				tf.array_layers = 4;
-				tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
-				rb_data->ss_effects_data.linear_depth = RD::get_singleton()->texture_create(tf, RD::TextureView());
-				RD::get_singleton()->set_resource_name(rb_data->ss_effects_data.linear_depth, "SS Effects Depth");
-				for (uint32_t i = 0; i < tf.mipmaps; i++) {
-					RID slice = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb_data->ss_effects_data.linear_depth, 0, i, 1, RD::TEXTURE_SLICE_2D_ARRAY);
-					rb_data->ss_effects_data.linear_depth_slices.push_back(slice);
-					RD::get_singleton()->set_resource_name(slice, "SS Effects Depth Mip " + itos(i) + " ");
-				}
-				invalidate_uniform_set = true;
+		if (p_use_ssao || p_use_ssil) {
+			// Convert our depth buffer data to linear data in
+			for (uint32_t v = 0; v < rb->get_view_count(); v++) {
+				ss_effects->downsample_depth(rb, v, p_render_data->scene_data->view_projection[v]);
 			}
 
-			RID depth_texture = rb->get_depth_texture();
-			ss_effects->downsample_depth(depth_texture, rb_data->ss_effects_data.linear_depth_slices, invalidate_uniform_set, size, p_render_data->scene_data->cam_projection);
-		}
-
-		if (p_use_ssao) {
-			// TODO make these proper stereo
-			_process_ssao(rb, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection);
-		}
+			if (p_use_ssao) {
+				_process_ssao(rb, p_render_data->environment, p_normal_roughness_slices, p_render_data->scene_data->view_projection);
+			}
 
-		if (p_use_ssil) {
-			// TODO make these proper stereo
-			_process_ssil(rb, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform);
+			if (p_use_ssil) {
+				_process_ssil(rb, p_render_data->environment, p_normal_roughness_slices, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform);
+			}
 		}
 	}
 
@@ -1514,17 +1498,11 @@ void RenderForwardClustered::_process_ssr(Ref<RenderSceneBuffersRD> p_render_buf
 	ERR_FAIL_COND(p_environment.is_null());
 	ERR_FAIL_COND(!environment_get_ssr_enabled(p_environment));
 
-	Size2i half_size = Size2i(internal_size.x / 2, internal_size.y / 2);
-	ss_effects->ssr_allocate_buffers(rb_data->ss_effects_data.ssr, _render_buffers_get_color_format(), half_size, view_count);
+	ss_effects->ssr_allocate_buffers(p_render_buffers, rb_data->ss_effects_data.ssr, _render_buffers_get_color_format());
+	ss_effects->screen_space_reflection(p_render_buffers, rb_data->ss_effects_data.ssr, p_normal_slices, p_metallic_slices, environment_get_ssr_max_steps(p_environment), environment_get_ssr_fade_in(p_environment), environment_get_ssr_fade_out(p_environment), environment_get_ssr_depth_tolerance(p_environment), p_projections, p_eye_offsets);
 
-	RID texture_slices[RendererSceneRender::MAX_RENDER_VIEWS];
-	RID depth_slices[RendererSceneRender::MAX_RENDER_VIEWS];
-	for (uint32_t v = 0; v < view_count; v++) {
-		texture_slices[v] = p_render_buffers->get_internal_texture(v);
-		depth_slices[v] = p_render_buffers->get_depth_texture(v);
-	}
-	ss_effects->screen_space_reflection(rb_data->ss_effects_data.ssr, texture_slices, p_normal_slices, p_metallic_slices, depth_slices, half_size, environment_get_ssr_max_steps(p_environment), environment_get_ssr_fade_in(p_environment), environment_get_ssr_fade_out(p_environment), environment_get_ssr_depth_tolerance(p_environment), view_count, p_projections, p_eye_offsets);
-	copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : p_render_buffers->get_internal_texture(), rb_data->ss_effects_data.ssr.output, view_count);
+	RID output = p_render_buffers->get_texture(RB_SCOPE_SSR, RB_OUTPUT);
+	copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : p_render_buffers->get_internal_texture(), output, view_count);
 }
 
 void RenderForwardClustered::_process_sss(Ref<RenderSceneBuffersRD> p_render_buffers, const Projection &p_camera) {
@@ -2129,14 +2107,16 @@ void RenderForwardClustered::_render_buffers_debug_draw(Ref<RenderSceneBuffersRD
 
 	RID render_target = p_render_buffers->get_render_target();
 
-	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb_data->ss_effects_data.ssao.ao_final.is_valid()) {
+	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSAO && p_render_buffers->has_texture(RB_SCOPE_SSAO, RB_FINAL)) {
+		RID final = p_render_buffers->get_texture_slice(RB_SCOPE_SSAO, RB_FINAL, 0, 0);
 		Size2i rtsize = texture_storage->render_target_get_size(render_target);
-		copy_effects->copy_to_fb_rect(rb_data->ss_effects_data.ssao.ao_final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, true);
+		copy_effects->copy_to_fb_rect(final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, true);
 	}
 
-	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSIL && rb_data->ss_effects_data.ssil.ssil_final.is_valid()) {
+	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SSIL && p_render_buffers->has_texture(RB_SCOPE_SSIL, RB_FINAL)) {
+		RID final = p_render_buffers->get_texture_slice(RB_SCOPE_SSIL, RB_FINAL, 0, 0);
 		Size2i rtsize = texture_storage->render_target_get_size(render_target);
-		copy_effects->copy_to_fb_rect(rb_data->ss_effects_data.ssil.ssil_final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false);
+		copy_effects->copy_to_fb_rect(final, texture_storage->render_target_get_rd_framebuffer(render_target), Rect2(Vector2(), rtsize), false, false);
 	}
 
 	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && p_render_buffers->has_texture(RB_SCOPE_GI, RB_TEX_AMBIENT)) {
@@ -3058,7 +3038,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
 		RD::Uniform u;
 		u.binding = 13;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-		RID aot = rb_data.is_valid() ? rb_data->get_ao_texture() : RID();
+		RID aot = rb.is_valid() && rb->has_texture(RB_SCOPE_SSAO, RB_FINAL) ? rb->get_texture(RB_SCOPE_SSAO, RB_FINAL) : RID();
 		RID texture = aot.is_valid() ? aot : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK);
 		u.append_id(texture);
 		uniforms.push_back(u);
@@ -3144,7 +3124,7 @@ RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_rend
 		RD::Uniform u;
 		u.binding = 20;
 		u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-		RID ssil = rb_data.is_valid() ? rb_data->get_ssil_texture() : RID();
+		RID ssil = rb.is_valid() && rb->has_texture(RB_SCOPE_SSIL, RB_FINAL) ? rb->get_texture(RB_SCOPE_SSIL, RB_FINAL) : RID();
 		RID texture = ssil.is_valid() ? ssil : texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_BLACK);
 		u.append_id(texture);
 		uniforms.push_back(u);

+ 4 - 12
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h

@@ -104,16 +104,11 @@ class RenderForwardClustered : public RendererSceneRenderRD {
 		ClusterBuilderRD *cluster_builder = nullptr;
 
 		struct SSEffectsData {
-			RID linear_depth;
-			Vector<RID> linear_depth_slices;
-
-			RID downsample_uniform_set;
-
-			Projection last_frame_projection;
+			Projection last_frame_projections[RendererSceneRender::MAX_RENDER_VIEWS];
 			Transform3D last_frame_transform;
 
-			RendererRD::SSEffects::SSAORenderBuffers ssao;
 			RendererRD::SSEffects::SSILRenderBuffers ssil;
+			RendererRD::SSEffects::SSAORenderBuffers ssao;
 			RendererRD::SSEffects::SSRRenderBuffers ssr;
 		} ss_effects_data;
 
@@ -155,9 +150,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
 		RID get_depth_fb(DepthFrameBufferType p_type = DEPTH_FB);
 		RID get_specular_only_fb();
 
-		RID get_ao_texture() const { return ss_effects_data.ssao.ao_final; }
-		RID get_ssil_texture() const { return ss_effects_data.ssil.ssil_final; }
-
 		virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
 		virtual void free_data() override;
 	};
@@ -600,8 +592,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
 	void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL_BARRIERS);
 
 	/* Render Scene */
-	void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection);
-	void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform);
+	void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections);
+	void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const RID *p_normal_buffers, const Projection *p_projections, const Transform3D &p_transform);
 	void _copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers);
 	void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer);
 	void _process_ssr(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive);

+ 8 - 0
servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl

@@ -1390,7 +1390,11 @@ void fragment_shader(in SceneData scene_data) {
 #endif // !USE_LIGHTMAP
 
 	if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) {
+#ifdef USE_MULTIVIEW
+		float ssao = texture(sampler2DArray(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(screen_uv, ViewIndex)).r;
+#else
 		float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
+#endif
 		ao = min(ao, ssao);
 		ao_light_affect = mix(ao_light_affect, max(ao_light_affect, implementation_data.ssao_light_affect), implementation_data.ssao_ao_affect);
 	}
@@ -1473,7 +1477,11 @@ void fragment_shader(in SceneData scene_data) {
 		ambient_light *= ao;
 
 		if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) {
+#ifdef USE_MULTIVIEW
+			vec4 ssil = textureLod(sampler2DArray(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(screen_uv, ViewIndex), 0.0);
+#else
 			vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0);
+#endif // USE_MULTIVIEW
 			ambient_light *= 1.0 - ssil.a;
 			ambient_light += ssil.rgb * albedo.rgb;
 		}

+ 6 - 1
servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl

@@ -275,6 +275,7 @@ layout(r32ui, set = 1, binding = 13) uniform restrict uimage3D geom_facing_grid;
 layout(set = 1, binding = 10) uniform texture2DArray depth_buffer;
 layout(set = 1, binding = 11) uniform texture2DArray color_buffer;
 layout(set = 1, binding = 12) uniform texture2DArray normal_roughness_buffer;
+layout(set = 1, binding = 13) uniform texture2DArray ao_buffer;
 layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer;
 layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer;
 #define multiviewSampler sampler2DArray
@@ -282,11 +283,11 @@ layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer;
 layout(set = 1, binding = 10) uniform texture2D depth_buffer;
 layout(set = 1, binding = 11) uniform texture2D color_buffer;
 layout(set = 1, binding = 12) uniform texture2D normal_roughness_buffer;
+layout(set = 1, binding = 13) uniform texture2D ao_buffer;
 layout(set = 1, binding = 14) uniform texture2D ambient_buffer;
 layout(set = 1, binding = 15) uniform texture2D reflection_buffer;
 #define multiviewSampler sampler2D
 #endif
-layout(set = 1, binding = 13) uniform texture2D ao_buffer;
 layout(set = 1, binding = 16) uniform texture2DArray sdfgi_lightprobe_texture;
 layout(set = 1, binding = 17) uniform texture3D sdfgi_occlusion_cascades;
 
@@ -312,7 +313,11 @@ voxel_gi_instances;
 
 layout(set = 1, binding = 19) uniform texture3D volumetric_fog_texture;
 
+#ifdef USE_MULTIVIEW
+layout(set = 1, binding = 20) uniform texture2DArray ssil_buffer;
+#else
 layout(set = 1, binding = 20) uniform texture2D ssil_buffer;
+#endif // USE_MULTIVIEW
 
 #endif
 

Some files were not shown because too many files changed in this diff