Browse Source

Extract shared scene data into a separate class

Bastiaan Olij 2 years ago
parent
commit
02ea1de7d0

File diff suppressed because it is too large
+ 235 - 376
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp


+ 6 - 66
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h

@@ -37,7 +37,7 @@
 #include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
 #include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
 #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
 #include "servers/rendering/renderer_rd/storage_rd/utilities.h"
 
 #define RB_SCOPE_FORWARD_CLUSTERED SNAME("forward_clustered")
@@ -249,61 +249,22 @@ class RenderForwardClustered : public RendererSceneRenderRD {
 	};
 
 	struct SceneState {
-		// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code
+		// This struct is loaded into Set 1 - Binding 1, populated at start of rendering a frame, must match with shader code
 		struct UBO {
-			float projection_matrix[16];
-			float inv_projection_matrix[16];
-			float inv_view_matrix[16];
-			float view_matrix[16];
-
-			float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
-			float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
-			float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4];
-
-			float viewport_size[2];
-			float screen_pixel_size[2];
-
 			uint32_t cluster_shift;
 			uint32_t cluster_width;
 			uint32_t cluster_type_size;
 			uint32_t max_cluster_element_count_div_32;
 
-			float directional_penumbra_shadow_kernel[128]; //32 vec4s
-			float directional_soft_shadow_kernel[128];
-			float penumbra_shadow_kernel[128];
-			float soft_shadow_kernel[128];
-
-			float ambient_light_color_energy[4];
-
-			float ambient_color_sky_mix;
-			uint32_t use_ambient_light;
-			uint32_t use_ambient_cubemap;
-			uint32_t use_reflection_cubemap;
-
-			float radiance_inverse_xform[12];
-
-			float shadow_atlas_pixel_size[2];
-			float directional_shadow_pixel_size[2];
-
-			uint32_t directional_light_count;
-			float dual_paraboloid_side;
-			float z_far;
-			float z_near;
-
 			uint32_t ss_effects_flags;
 			float ssao_light_affect;
 			float ssao_ao_affect;
-			uint32_t roughness_limiter_enabled;
-
-			float roughness_limiter_amount;
-			float roughness_limiter_limit;
-			float opaque_prepass_threshold;
-			uint32_t roughness_limiter_pad;
+			uint32_t pad1;
 
 			float sdf_to_bounds[16];
 
 			int32_t sdf_offset[3];
-			uint32_t material_uv2_mode;
+			uint32_t pad2;
 
 			int32_t sdf_size[3];
 			uint32_t gi_upscale_for_msaa;
@@ -312,26 +273,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
 			float volumetric_fog_inv_length;
 			float volumetric_fog_detail_spread;
 			uint32_t volumetric_fog_pad;
-
-			// Fog
-			uint32_t fog_enabled;
-			float fog_density;
-			float fog_height;
-			float fog_height_density;
-
-			float fog_light_color[3];
-			float fog_sun_scatter;
-
-			float fog_aerial_perspective;
-
-			float time;
-			float reflection_multiplier;
-
-			uint32_t pancake_shadows;
-
-			float taa_jitter[2];
-			float emissive_exposure_normalization; // Needed to normalize emissive when using physical units.
-			float IBL_exposure_normalization;
 		};
 
 		struct PushConstant {
@@ -351,11 +292,10 @@ class RenderForwardClustered : public RendererSceneRenderRD {
 			float lightmap_uv_scale[4];
 		};
 
-		UBO ubo_data[2];
-		UBO &ubo = ubo_data[0];
-		UBO &prev_ubo = ubo_data[1];
+		UBO ubo;
 
 		LocalVector<RID> uniform_buffers;
+		LocalVector<RID> implementation_uniform_buffers;
 
 		LightmapData lightmaps[MAX_LIGHTMAPS];
 		RID lightmap_ids[MAX_LIGHTMAPS];

+ 1 - 1
servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h

@@ -32,7 +32,7 @@
 #define SCENE_SHADER_FORWARD_CLUSTERED_H
 
 #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl.gen.h"
 
 namespace RendererSceneRenderImplementation {
 

+ 88 - 232
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

@@ -504,8 +504,20 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 
 	RENDER_TIMESTAMP("Setup 3D Scene");
 
-	scene_state.ubo.directional_light_count = 0;
-	scene_state.ubo.opaque_prepass_threshold = 0.0;
+	/* TODO
+	// check if we need motion vectors
+	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
+		p_render_data->scene_data->calculate_motion_vectors = true;
+	} else if (render target has velocity override) { // TODO
+		p_render_data->scene_data->calculate_motion_vectors = true;
+	} else {
+		p_render_data->scene_data->calculate_motion_vectors = false;
+	}
+	*/
+	p_render_data->scene_data->calculate_motion_vectors = false; // for now, not yet supported...
+
+	p_render_data->scene_data->directional_light_count = 0;
+	p_render_data->scene_data->opaque_prepass_threshold = 0.0;
 
 	// We can only use our full subpass approach if we're:
 	// - not reading from SCREEN_TEXTURE/DEPTH_TEXTURE
@@ -581,13 +593,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 		ERR_FAIL(); //bug?
 	}
 
-	scene_state.ubo.viewport_size[0] = screen_size.x;
-	scene_state.ubo.viewport_size[1] = screen_size.y;
-	scene_state.ubo.emissive_exposure_normalization = -1.0;
+	p_render_data->scene_data->emissive_exposure_normalization = -1.0;
 
 	RD::get_singleton()->draw_command_begin_label("Render Setup");
 
-	_setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->cam_transform);
+	_setup_lightmaps(p_render_data, *p_render_data->lightmaps, p_render_data->scene_data->cam_transform);
 	_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
 
 	_update_render_base_uniform_set(); //may have changed due to the above (light buffer enlarged, as an example)
@@ -658,20 +668,20 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 		if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
 			RENDER_TIMESTAMP("Setup Sky");
 			RD::get_singleton()->draw_command_begin_label("Setup Sky");
-			Projection projection = p_render_data->cam_projection;
+			Projection projection = p_render_data->scene_data->cam_projection;
 			if (p_render_data->reflection_probe.is_valid()) {
 				Projection correction;
 				correction.set_depth_correction(true);
-				projection = correction * p_render_data->cam_projection;
+				projection = correction * p_render_data->scene_data->cam_projection;
 			}
 
-			sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->cam_transform, screen_size, this);
+			sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->scene_data->cam_transform, screen_size, this);
 
 			sky_energy_multiplier *= bg_energy_multiplier;
 
 			RID sky_rid = environment_get_sky(p_render_data->environment);
 			if (sky_rid.is_valid()) {
-				sky.update(p_render_data->environment, projection, p_render_data->cam_transform, time, sky_energy_multiplier);
+				sky.update(p_render_data->environment, projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
 				radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
 			} else {
 				// do not try to draw sky if invalid
@@ -694,10 +704,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 		if (p_render_data->reflection_probe.is_valid()) {
 			Projection correction;
 			correction.set_depth_correction(true);
-			Projection projection = correction * p_render_data->cam_projection;
-			sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->cam_transform, time, sky_energy_multiplier);
+			Projection projection = correction * p_render_data->scene_data->cam_projection;
+			sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
 		} else {
-			sky.update_res_buffers(p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, sky_energy_multiplier);
+			sky.update_res_buffers(p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
 		}
 
 		RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
@@ -734,7 +744,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 
 		RD::get_singleton()->draw_command_begin_label("Render Opaque Subpass");
 
-		scene_state.ubo.directional_light_count = p_render_data->directional_light_count;
+		p_render_data->scene_data->directional_light_count = p_render_data->directional_light_count;
 
 		_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, p_render_data->render_buffers.is_valid());
 
@@ -765,7 +775,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 			}
 
 			RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
-			RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
+			RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count);
 			render_list_params.framebuffer_format = fb_format;
 			if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
 				// secondary command buffers need more testing at this time
@@ -793,10 +803,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 			if (p_render_data->reflection_probe.is_valid()) {
 				Projection correction;
 				correction.set_depth_correction(true);
-				Projection projection = correction * p_render_data->cam_projection;
-				sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->cam_transform, time, sky_energy_multiplier);
+				Projection projection = correction * p_render_data->scene_data->cam_projection;
+				sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
 			} else {
-				sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, sky_energy_multiplier);
+				sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
 			}
 
 			RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass
@@ -832,7 +842,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 
 		if (using_subpass_transparent) {
 			RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
-			RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
+			RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR_TRANSPARENT, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count);
 			render_list_params.framebuffer_format = fb_format;
 			if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
 				// secondary command buffers need more testing at this time
@@ -871,7 +881,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 			// _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
 
 			RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(framebuffer);
-			RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
+			RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, PASS_MODE_COLOR, rp_uniform_set, spec_constant_base_flags, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->scene_data->lod_camera_plane, p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, p_render_data->scene_data->view_count);
 			render_list_params.framebuffer_format = fb_format;
 			if ((uint32_t)render_list_params.element_count > render_list_thread_threshold && false) {
 				// secondary command buffers need more testing at this time
@@ -928,26 +938,29 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
 		p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = p_instances.size();
 		p_render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_SHADOW][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_instances.size();
 	}
+
+	RenderSceneDataRD scene_data;
+	scene_data.cam_projection = p_projection;
+	scene_data.cam_transform = p_transform;
+	scene_data.view_projection[0] = p_projection;
+	scene_data.z_near = 0.0;
+	scene_data.z_far = p_zfar;
+	scene_data.lod_camera_plane = p_camera_plane;
+	scene_data.lod_distance_multiplier = p_lod_distance_multiplier;
+	scene_data.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
+	scene_data.opaque_prepass_threshold = 0.1;
+
 	RenderDataRD render_data;
-	render_data.cam_projection = p_projection;
-	render_data.cam_transform = p_transform;
-	render_data.view_projection[0] = p_projection;
-	render_data.z_near = 0.0;
-	render_data.z_far = p_zfar;
+	render_data.scene_data = &scene_data;
 	render_data.instances = &p_instances;
 	render_data.render_info = p_render_info;
-	render_data.lod_camera_plane = p_camera_plane;
-	render_data.lod_distance_multiplier = p_lod_distance_multiplier;
-
-	scene_state.ubo.dual_paraboloid_side = p_use_dp_flip ? -1 : 1;
-	scene_state.ubo.opaque_prepass_threshold = 0.1;
 
 	_setup_environment(&render_data, true, Vector2(1, 1), !p_flip_y, Color(), false, p_use_pancake, shadow_pass_index);
 
 	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
-		render_data.screen_mesh_lod_threshold = 0.0;
+		scene_data.screen_mesh_lod_threshold = 0.0;
 	} else {
-		render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
+		scene_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
 	}
 
 	PassMode pass_mode = p_use_dp ? PASS_MODE_SHADOW_DP : PASS_MODE_SHADOW;
@@ -972,8 +985,8 @@ void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedAr
 
 		shadow_pass.rp_uniform_set = RID(); //will be filled later when instance buffer is complete
 		shadow_pass.camera_plane = p_camera_plane;
-		shadow_pass.screen_mesh_lod_threshold = render_data.screen_mesh_lod_threshold;
-		shadow_pass.lod_distance_multiplier = render_data.lod_distance_multiplier;
+		shadow_pass.screen_mesh_lod_threshold = scene_data.screen_mesh_lod_threshold;
+		shadow_pass.lod_distance_multiplier = scene_data.lod_distance_multiplier;
 
 		shadow_pass.framebuffer = p_framebuffer;
 		shadow_pass.initial_depth_action = p_begin ? (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR) : (p_clear_region ? RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE : RD::INITIAL_ACTION_CONTINUE);
@@ -1020,15 +1033,17 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c
 
 	_update_render_base_uniform_set();
 
-	scene_state.ubo.dual_paraboloid_side = 0;
-	scene_state.ubo.material_uv2_mode = false;
-	scene_state.ubo.opaque_prepass_threshold = 0.0f;
-	scene_state.ubo.emissive_exposure_normalization = p_exposure_normalization;
+	RenderSceneDataRD scene_data;
+	scene_data.cam_projection = p_cam_projection;
+	scene_data.cam_transform = p_cam_transform;
+	scene_data.view_projection[0] = p_cam_projection;
+	scene_data.dual_paraboloid_side = 0;
+	scene_data.material_uv2_mode = false;
+	scene_data.opaque_prepass_threshold = 0.0f;
+	scene_data.emissive_exposure_normalization = p_exposure_normalization;
 
 	RenderDataRD render_data;
-	render_data.cam_projection = p_cam_projection;
-	render_data.cam_transform = p_cam_transform;
-	render_data.view_projection[0] = p_cam_projection;
+	render_data.scene_data = &scene_data;
 	render_data.instances = &p_instances;
 
 	_setup_environment(&render_data, true, Vector2(1, 1), false, Color());
@@ -1067,11 +1082,13 @@ void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *>
 
 	_update_render_base_uniform_set();
 
-	scene_state.ubo.dual_paraboloid_side = 0;
-	scene_state.ubo.material_uv2_mode = true;
-	scene_state.ubo.emissive_exposure_normalization = -1.0;
+	RenderSceneDataRD scene_data;
+	scene_data.dual_paraboloid_side = 0;
+	scene_data.material_uv2_mode = true;
+	scene_data.emissive_exposure_normalization = -1.0;
 
 	RenderDataRD render_data;
+	render_data.scene_data = &scene_data;
 	render_data.instances = &p_instances;
 
 	_setup_environment(&render_data, true, Vector2(1, 1), false, Color());
@@ -1138,15 +1155,18 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
 	RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield");
 
 	_update_render_base_uniform_set();
-	scene_state.ubo.dual_paraboloid_side = 0;
-	scene_state.ubo.opaque_prepass_threshold = 0.0;
+
+	RenderSceneDataRD scene_data;
+	scene_data.cam_projection = p_cam_projection;
+	scene_data.cam_transform = p_cam_transform;
+	scene_data.view_projection[0] = p_cam_projection;
+	scene_data.z_near = 0.0;
+	scene_data.z_far = p_cam_projection.get_z_far();
+	scene_data.dual_paraboloid_side = 0;
+	scene_data.opaque_prepass_threshold = 0.0;
 
 	RenderDataRD render_data;
-	render_data.cam_projection = p_cam_projection;
-	render_data.cam_transform = p_cam_transform;
-	render_data.view_projection[0] = p_cam_projection;
-	render_data.z_near = 0.0;
-	render_data.z_far = p_cam_projection.get_z_far();
+	render_data.scene_data = &scene_data;
 	render_data.instances = &p_instances;
 
 	_setup_environment(&render_data, true, Vector2(1, 1), true, Color(), false, false);
@@ -1385,9 +1405,9 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
 	}
 	uint32_t lightmap_captures_used = 0;
 
-	Plane near_plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin);
-	near_plane.d += p_render_data->cam_projection.get_z_near();
-	float z_max = p_render_data->cam_projection.get_z_far() - p_render_data->cam_projection.get_z_near();
+	Plane near_plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin);
+	near_plane.d += p_render_data->scene_data->cam_projection.get_z_near();
+	float z_max = p_render_data->scene_data->cam_projection.get_z_far() - p_render_data->scene_data->cam_projection.get_z_near();
 
 	RenderList *rl = &render_list[p_render_list];
 
@@ -1466,13 +1486,13 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
 
 			// LOD
 
-			if (p_render_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
+			if (p_render_data->scene_data->screen_mesh_lod_threshold > 0.0 && mesh_storage->mesh_surface_has_lod(surf->surface)) {
 				//lod
-				Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->lod_camera_plane.normal);
-				Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->lod_camera_plane.normal);
+				Vector3 lod_support_min = inst->transformed_aabb.get_support(-p_render_data->scene_data->lod_camera_plane.normal);
+				Vector3 lod_support_max = inst->transformed_aabb.get_support(p_render_data->scene_data->lod_camera_plane.normal);
 
-				float distance_min = p_render_data->lod_camera_plane.distance_to(lod_support_min);
-				float distance_max = p_render_data->lod_camera_plane.distance_to(lod_support_max);
+				float distance_min = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_min);
+				float distance_max = p_render_data->scene_data->lod_camera_plane.distance_to(lod_support_max);
 
 				float distance = 0.0;
 
@@ -1485,12 +1505,12 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
 					distance = -distance_max;
 				}
 
-				if (p_render_data->cam_orthogonal) {
+				if (p_render_data->scene_data->cam_orthogonal) {
 					distance = 1.0;
 				}
 
 				uint32_t indices;
-				surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, &indices);
+				surf->lod_index = mesh_storage->mesh_surface_get_lod(surf->surface, inst->lod_model_scale * inst->lod_bias, distance * p_render_data->scene_data->lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, &indices);
 				if (p_render_data->render_info) {
 					indices = _indices_to_primitives(surf->primitive, indices);
 					if (p_render_list == RENDER_LIST_OPAQUE) { //opaque
@@ -1562,184 +1582,20 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
 }
 
 void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
-	//!BAS! need to go through this and find out what we don't need anymore
-
-	// This populates our UBO with main scene data that is pushed into set 1
-
-	//Projection projection = p_render_data->cam_projection;
-	//projection.flip_y(); // Vulkan and modern APIs use Y-Down
-	Projection correction;
-	correction.set_depth_correction(p_flip_y);
-	Projection projection = correction * p_render_data->cam_projection;
-
-	//store camera into ubo
-	RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);
-	RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
-	RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
-	RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
-
-	for (uint32_t v = 0; v < p_render_data->view_count; v++) {
-		projection = correction * p_render_data->view_projection[v];
-		RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
-		RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
-
-		scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x;
-		scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y;
-		scene_state.ubo.eye_offset[v][2] = p_render_data->view_eye_offset[v].z;
-		scene_state.ubo.eye_offset[v][3] = 0.0;
-	}
-
-	scene_state.ubo.z_far = p_render_data->z_far;
-	scene_state.ubo.z_near = p_render_data->z_near;
-
-	scene_state.ubo.pancake_shadows = p_pancake_shadows;
-
-	RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
-	RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
-	RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
-	RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
-
-	Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
-	scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
-	scene_state.ubo.screen_pixel_size[1] = screen_pixel_size.y;
-
-	if (p_render_data->shadow_atlas.is_valid()) {
-		Vector2 sas = shadow_atlas_get_size(p_render_data->shadow_atlas);
-		scene_state.ubo.shadow_atlas_pixel_size[0] = 1.0 / sas.x;
-		scene_state.ubo.shadow_atlas_pixel_size[1] = 1.0 / sas.y;
-	}
-	{
-		Vector2 dss = directional_shadow_get_size();
-		scene_state.ubo.directional_shadow_pixel_size[0] = 1.0 / dss.x;
-		scene_state.ubo.directional_shadow_pixel_size[1] = 1.0 / dss.y;
-	}
-
-	//time global variables
-	scene_state.ubo.time = time;
-
-	if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
-		scene_state.ubo.use_ambient_light = true;
-		scene_state.ubo.ambient_light_color_energy[0] = 1;
-		scene_state.ubo.ambient_light_color_energy[1] = 1;
-		scene_state.ubo.ambient_light_color_energy[2] = 1;
-		scene_state.ubo.ambient_light_color_energy[3] = 1.0;
-		scene_state.ubo.use_ambient_cubemap = false;
-		scene_state.ubo.use_reflection_cubemap = false;
-		scene_state.ubo.ssao_enabled = false;
-
-	} else if (is_environment(p_render_data->environment)) {
-		RS::EnvironmentBG env_bg = environment_get_background(p_render_data->environment);
-		RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_render_data->environment);
-
-		float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment);
-
-		scene_state.ubo.ambient_light_color_energy[3] = bg_energy_multiplier;
-
-		scene_state.ubo.ambient_color_sky_mix = environment_get_ambient_sky_contribution(p_render_data->environment);
-
-		//ambient
-		if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {
-			Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_render_data->environment);
-			color = color.srgb_to_linear();
-
-			scene_state.ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier;
-			scene_state.ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier;
-			scene_state.ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier;
-			scene_state.ubo.use_ambient_light = true;
-			scene_state.ubo.use_ambient_cubemap = false;
-		} else {
-			float energy = environment_get_ambient_light_energy(p_render_data->environment);
-			Color color = environment_get_ambient_light(p_render_data->environment);
-			color = color.srgb_to_linear();
-			scene_state.ubo.ambient_light_color_energy[0] = color.r * energy;
-			scene_state.ubo.ambient_light_color_energy[1] = color.g * energy;
-			scene_state.ubo.ambient_light_color_energy[2] = color.b * energy;
-
-			Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);
-			sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
-			RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
-
-			scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
-			scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
-		}
-
-		//specular
-		RS::EnvironmentReflectionSource ref_src = environment_get_reflection_source(p_render_data->environment);
-		if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {
-			scene_state.ubo.use_reflection_cubemap = true;
-		} else {
-			scene_state.ubo.use_reflection_cubemap = false;
-		}
-
-		scene_state.ubo.ssao_enabled = p_opaque_render_buffers && environment_get_ssao_enabled(p_render_data->environment);
-		scene_state.ubo.ssao_ao_affect = environment_get_ssao_ao_channel_affect(p_render_data->environment);
-		scene_state.ubo.ssao_light_affect = environment_get_ssao_direct_light_affect(p_render_data->environment);
-
-		scene_state.ubo.fog_enabled = environment_get_fog_enabled(p_render_data->environment);
-		scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);
-		scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment);
-		scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
-		scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
-
-		Color fog_color = environment_get_fog_light_color(p_render_data->environment).srgb_to_linear();
-		float fog_energy = environment_get_fog_light_energy(p_render_data->environment);
-
-		scene_state.ubo.fog_light_color[0] = fog_color.r * fog_energy;
-		scene_state.ubo.fog_light_color[1] = fog_color.g * fog_energy;
-		scene_state.ubo.fog_light_color[2] = fog_color.b * fog_energy;
-
-		scene_state.ubo.fog_sun_scatter = environment_get_fog_sun_scatter(p_render_data->environment);
-
-	} else {
-		if (p_render_data->reflection_probe.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
-			scene_state.ubo.use_ambient_light = false;
-		} else {
-			scene_state.ubo.use_ambient_light = true;
-			Color clear_color = p_default_bg_color;
-			clear_color = clear_color.srgb_to_linear();
-			scene_state.ubo.ambient_light_color_energy[0] = clear_color.r;
-			scene_state.ubo.ambient_light_color_energy[1] = clear_color.g;
-			scene_state.ubo.ambient_light_color_energy[2] = clear_color.b;
-			scene_state.ubo.ambient_light_color_energy[3] = 1.0;
-		}
-
-		scene_state.ubo.use_ambient_cubemap = false;
-		scene_state.ubo.use_reflection_cubemap = false;
-		scene_state.ubo.ssao_enabled = false;
-	}
-
-	if (p_render_data->camera_attributes.is_valid()) {
-		scene_state.ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
-		scene_state.ubo.IBL_exposure_normalization = 1.0;
-		if (is_environment(p_render_data->environment)) {
-			RID sky_rid = environment_get_sky(p_render_data->environment);
-			if (sky_rid.is_valid()) {
-				float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes) * environment_get_bg_intensity(p_render_data->environment) / _render_buffers_get_luminance_multiplier();
-				scene_state.ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, sky.sky_get_baked_exposure(sky_rid));
-			}
-		}
-	} else if (scene_state.ubo.emissive_exposure_normalization > 0.0) {
-		// This branch is triggered when using render_material().
-		// Emissive is set outside the function, so don't set it.
-		// IBL isn't used don't set it.
-	} else {
-		scene_state.ubo.emissive_exposure_normalization = 1.0;
-		scene_state.ubo.IBL_exposure_normalization = 1.0;
-	}
-
-	scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active();
-	scene_state.ubo.roughness_limiter_amount = screen_space_roughness_limiter_get_amount();
-	scene_state.ubo.roughness_limiter_limit = screen_space_roughness_limiter_get_limit();
+	Ref<RenderSceneBuffersRD> rd = p_render_data->render_buffers;
+	RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID();
+	RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID();
 
+	// May do this earlier in RenderSceneRenderRD::render_scene
 	if (p_index >= (int)scene_state.uniform_buffers.size()) {
 		uint32_t from = scene_state.uniform_buffers.size();
 		scene_state.uniform_buffers.resize(p_index + 1);
-		render_pass_uniform_sets.resize(p_index + 1);
 		for (uint32_t i = from; i < scene_state.uniform_buffers.size(); i++) {
-			scene_state.uniform_buffers[i] = RD::get_singleton()->uniform_buffer_create(sizeof(SceneState::UBO));
+			scene_state.uniform_buffers[i] = p_render_data->scene_data->create_uniform_buffer();
 		}
 	}
-	RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER);
+
+	p_render_data->scene_data->update_ubo(scene_state.uniform_buffers[p_index], get_debug_draw_mode(), env, reflection_probe_instance, p_render_data->camera_attributes, p_flip_y, p_pancake_shadows, p_screen_size, p_default_bg_color, _render_buffers_get_luminance_multiplier(), p_opaque_render_buffers);
 }
 
 void RenderForwardMobile::_fill_element_info(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements) {

+ 0 - 69
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h

@@ -252,75 +252,6 @@ protected:
 	/* Scene state */
 
 	struct SceneState {
-		// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code
-		struct UBO {
-			float projection_matrix[16];
-			float inv_projection_matrix[16];
-			float inv_view_matrix[16];
-			float view_matrix[16];
-
-			float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
-			float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
-			float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4];
-
-			float viewport_size[2];
-			float screen_pixel_size[2];
-
-			float directional_penumbra_shadow_kernel[128]; //32 vec4s
-			float directional_soft_shadow_kernel[128];
-			float penumbra_shadow_kernel[128];
-			float soft_shadow_kernel[128];
-
-			float ambient_light_color_energy[4];
-
-			float ambient_color_sky_mix;
-			uint32_t use_ambient_light;
-			uint32_t use_ambient_cubemap;
-			uint32_t use_reflection_cubemap;
-
-			float radiance_inverse_xform[12];
-
-			float shadow_atlas_pixel_size[2];
-			float directional_shadow_pixel_size[2];
-
-			uint32_t directional_light_count;
-			float dual_paraboloid_side;
-			float z_far;
-			float z_near;
-
-			uint32_t ssao_enabled;
-			float ssao_light_affect;
-			float ssao_ao_affect;
-			uint32_t roughness_limiter_enabled;
-
-			float roughness_limiter_amount;
-			float roughness_limiter_limit;
-			float opaque_prepass_threshold;
-			uint32_t roughness_limiter_pad;
-
-			// Fog
-			uint32_t fog_enabled;
-			float fog_density;
-			float fog_height;
-			float fog_height_density;
-
-			float fog_light_color[3];
-			float fog_sun_scatter;
-
-			float fog_aerial_perspective;
-			uint32_t material_uv2_mode;
-
-			float time;
-			float reflection_multiplier;
-
-			uint32_t pancake_shadows;
-			float emissive_exposure_normalization; // Needed to normalize emissive when using physical units.
-			float IBL_exposure_normalization; // Adjusts for baked exposure.
-			uint32_t pad3;
-		};
-
-		UBO ubo;
-
 		LocalVector<RID> uniform_buffers;
 
 		// !BAS! We need to change lightmaps, we're not going to do this with a buffer but pushing the used lightmap in

+ 1 - 1
servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h

@@ -32,7 +32,7 @@
 #define SCENE_SHADER_FORWARD_MOBILE_H
 
 #include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl.gen.h"
 
 namespace RendererSceneRenderImplementation {
 

+ 71 - 52
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -1492,7 +1492,7 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR
 
 	bool can_use_storage = _render_buffers_can_be_storage();
 	Size2i size = rb->get_internal_size();
-	for (uint32_t v = 0; v < p_render_data->view_count; v++) {
+	for (uint32_t v = 0; v < p_render_data->scene_data->view_count; v++) {
 		RID depth_texture = rb->get_depth_texture(v);
 		RID depth_back_texture = rb->get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH, v, 0);
 
@@ -1544,9 +1544,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
 				buffers.depth_texture = rb->get_depth_texture(i);
 
 				// In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum
-				float z_near = p_render_data->view_projection[i].get_z_near();
-				float z_far = p_render_data->view_projection[i].get_z_far();
-				bokeh_dof->bokeh_dof_compute(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->cam_orthogonal);
+				float z_near = p_render_data->scene_data->view_projection[i].get_z_near();
+				float z_far = p_render_data->scene_data->view_projection[i].get_z_far();
+				bokeh_dof->bokeh_dof_compute(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->scene_data->cam_orthogonal);
 			};
 		} else {
 			// Set framebuffers.
@@ -1567,9 +1567,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
 				buffers.base_fb = FramebufferCacheRD::get_singleton()->get_cache(buffers.base_texture); // TODO move this into bokeh_dof_raster, we can do this internally
 
 				// In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum
-				float z_near = p_render_data->view_projection[i].get_z_near();
-				float z_far = p_render_data->view_projection[i].get_z_far();
-				bokeh_dof->bokeh_dof_raster(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->cam_orthogonal);
+				float z_near = p_render_data->scene_data->view_projection[i].get_z_near();
+				float z_far = p_render_data->scene_data->view_projection[i].get_z_far();
+				bokeh_dof->bokeh_dof_raster(buffers, p_render_data->camera_attributes, z_near, z_far, p_render_data->scene_data->cam_orthogonal);
 			}
 		}
 		RD::get_singleton()->draw_command_end_label();
@@ -2901,8 +2901,8 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 	render_state.shadows.clear();
 	render_state.directional_shadows.clear();
 
-	Plane camera_plane(-p_render_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->cam_transform.origin);
-	float lod_distance_multiplier = p_render_data->cam_projection.get_lod_multiplier();
+	Plane camera_plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin);
+	float lod_distance_multiplier = p_render_data->scene_data->cam_projection.get_lod_multiplier();
 	{
 		for (int i = 0; i < render_state.render_shadow_count; i++) {
 			LightInstance *li = light_instance_owner.get_or_null(render_state.render_shadows[i].light);
@@ -2918,7 +2918,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 
 		//cube shadows are rendered in their own way
 		for (uint32_t i = 0; i < render_state.cube_shadows.size(); i++) {
-			_render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
+			_render_shadow_pass(render_state.render_shadows[render_state.cube_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.cube_shadows[i]].pass, render_state.render_shadows[render_state.cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
 		}
 
 		if (render_state.directional_shadows.size()) {
@@ -2948,11 +2948,11 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 
 		//render directional shadows
 		for (uint32_t i = 0; i < render_state.directional_shadows.size(); i++) {
-			_render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false, p_render_data->render_info);
+			_render_shadow_pass(render_state.render_shadows[render_state.directional_shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.directional_shadows[i]].pass, render_state.render_shadows[render_state.directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, false, i == render_state.directional_shadows.size() - 1, false, p_render_data->render_info);
 		}
 		//render positional shadows
 		for (uint32_t i = 0; i < render_state.shadows.size(); i++) {
-			_render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true, p_render_data->render_info);
+			_render_shadow_pass(render_state.render_shadows[render_state.shadows[i]].light, p_render_data->shadow_atlas, render_state.render_shadows[render_state.shadows[i]].pass, render_state.render_shadows[render_state.shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, i == 0, i == render_state.shadows.size() - 1, true, p_render_data->render_info);
 		}
 
 		_render_shadow_process();
@@ -2960,7 +2960,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 
 	//start GI
 	if (render_gi) {
-		gi.process_gi(p_render_data->render_buffers, p_normal_roughness_slices, p_voxel_gi_buffer, p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->view_eye_offset, p_render_data->cam_transform, *p_render_data->voxel_gi_instances);
+		gi.process_gi(p_render_data->render_buffers, p_normal_roughness_slices, p_voxel_gi_buffer, p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, *p_render_data->voxel_gi_instances);
 	}
 
 	//Do shadow rendering (in parallel with GI)
@@ -2999,17 +2999,17 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 			}
 
 			RID depth_texture = rb->get_depth_texture();
-			ss_effects->downsample_depth(depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, size, p_render_data->cam_projection);
+			ss_effects->downsample_depth(depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, size, p_render_data->scene_data->cam_projection);
 		}
 
 		if (p_use_ssao) {
 			// TODO make these proper stereo
-			_process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->cam_projection);
+			_process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection);
 		}
 
 		if (p_use_ssil) {
 			// TODO make these proper stereo
-			_process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->cam_projection, p_render_data->cam_transform);
+			_process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_slices[0], p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform);
 		}
 	}
 
@@ -3017,7 +3017,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 	RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL);
 
 	if (current_cluster_builder) {
-		current_cluster_builder->begin(p_render_data->cam_transform, p_render_data->cam_projection, !p_render_data->reflection_probe.is_valid());
+		current_cluster_builder->begin(p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, !p_render_data->reflection_probe.is_valid());
 	}
 
 	bool using_shadows = true;
@@ -3028,13 +3028,13 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 		}
 	} else {
 		//do not render reflections when rendering a reflection probe
-		_setup_reflections(p_render_data, *p_render_data->reflection_probes, p_render_data->cam_transform.affine_inverse(), p_render_data->environment);
+		_setup_reflections(p_render_data, *p_render_data->reflection_probes, p_render_data->scene_data->cam_transform.affine_inverse(), p_render_data->environment);
 	}
 
 	uint32_t directional_light_count = 0;
 	uint32_t positional_light_count = 0;
-	_setup_lights(p_render_data, *p_render_data->lights, p_render_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
-	_setup_decals(*p_render_data->decals, p_render_data->cam_transform.affine_inverse());
+	_setup_lights(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
+	_setup_decals(*p_render_data->decals, p_render_data->scene_data->cam_transform.affine_inverse());
 
 	p_render_data->directional_light_count = directional_light_count;
 
@@ -3051,7 +3051,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
 			}
 		}
 		if (is_volumetric_supported()) {
-			_update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, p_render_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count, *p_render_data->fog_volumes);
+			_update_volumetric_fog(p_render_data->render_buffers, p_render_data->environment, p_render_data->scene_data->cam_projection, p_render_data->scene_data->cam_transform, p_render_data->scene_data->prev_cam_transform.affine_inverse(), p_render_data->shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.voxel_gi_count, *p_render_data->fog_volumes);
 		}
 	}
 }
@@ -3066,33 +3066,62 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
 		ERR_FAIL_COND(rb.is_null());
 	}
 
-	//assign render data
-	RenderDataRD render_data;
+	// setup scene data
+	RenderSceneDataRD scene_data;
 	{
-		render_data.render_buffers = rb;
-
 		// Our first camera is used by default
-		render_data.cam_transform = p_camera_data->main_transform;
-		render_data.cam_projection = p_camera_data->main_projection;
-		render_data.cam_orthogonal = p_camera_data->is_orthogonal;
-		render_data.taa_jitter = p_camera_data->taa_jitter;
+		scene_data.cam_transform = p_camera_data->main_transform;
+		scene_data.cam_projection = p_camera_data->main_projection;
+		scene_data.cam_orthogonal = p_camera_data->is_orthogonal;
+		scene_data.taa_jitter = p_camera_data->taa_jitter;
 
-		render_data.view_count = p_camera_data->view_count;
+		scene_data.view_count = p_camera_data->view_count;
 		for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
-			render_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin;
-			render_data.view_projection[v] = p_camera_data->view_projection[v];
+			scene_data.view_eye_offset[v] = p_camera_data->view_offset[v].origin;
+			scene_data.view_projection[v] = p_camera_data->view_projection[v];
 		}
 
-		render_data.prev_cam_transform = p_prev_camera_data->main_transform;
-		render_data.prev_cam_projection = p_prev_camera_data->main_projection;
-		render_data.prev_taa_jitter = p_prev_camera_data->taa_jitter;
+		scene_data.prev_cam_transform = p_prev_camera_data->main_transform;
+		scene_data.prev_cam_projection = p_prev_camera_data->main_projection;
+		scene_data.prev_taa_jitter = p_prev_camera_data->taa_jitter;
 
 		for (uint32_t v = 0; v < p_camera_data->view_count; v++) {
-			render_data.prev_view_projection[v] = p_prev_camera_data->view_projection[v];
+			scene_data.prev_view_projection[v] = p_prev_camera_data->view_projection[v];
+		}
+
+		scene_data.z_near = p_camera_data->main_projection.get_z_near();
+		scene_data.z_far = p_camera_data->main_projection.get_z_far();
+
+		// this should be the same for all cameras..
+		scene_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier();
+		scene_data.lod_camera_plane = Plane(-p_camera_data->main_transform.basis.get_column(Vector3::AXIS_Z), p_camera_data->main_transform.get_origin());
+
+		if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
+			scene_data.screen_mesh_lod_threshold = 0.0;
+		} else {
+			scene_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
+		}
+
+		if (p_shadow_atlas.is_valid()) {
+			Vector2 sas = shadow_atlas_get_size(p_shadow_atlas);
+			scene_data.shadow_atlas_pixel_size.x = 1.0 / sas.x;
+			scene_data.shadow_atlas_pixel_size.y = 1.0 / sas.y;
 		}
+		{
+			Vector2 dss = directional_shadow_get_size();
+			scene_data.directional_shadow_pixel_size.x = 1.0 / dss.x;
+			scene_data.directional_shadow_pixel_size.y = 1.0 / dss.y;
+		}
+
+		scene_data.time = time;
+		scene_data.time_step = time_step;
+	}
 
-		render_data.z_near = p_camera_data->main_projection.get_z_near();
-		render_data.z_far = p_camera_data->main_projection.get_z_far();
+	//assign render data
+	RenderDataRD render_data;
+	{
+		render_data.render_buffers = rb;
+		render_data.scene_data = &scene_data;
 
 		render_data.instances = &p_instances;
 		render_data.lights = &p_lights;
@@ -3108,16 +3137,6 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
 		render_data.reflection_probe = p_reflection_probe;
 		render_data.reflection_probe_pass = p_reflection_probe_pass;
 
-		// this should be the same for all cameras..
-		render_data.lod_distance_multiplier = p_camera_data->main_projection.get_lod_multiplier();
-		render_data.lod_camera_plane = Plane(-p_camera_data->main_transform.basis.get_column(Vector3::AXIS_Z), p_camera_data->main_transform.get_origin());
-
-		if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_DISABLE_LOD) {
-			render_data.screen_mesh_lod_threshold = 0.0;
-		} else {
-			render_data.screen_mesh_lod_threshold = p_screen_mesh_lod_threshold;
-		}
-
 		render_state.render_shadows = p_render_shadows;
 		render_state.render_shadow_count = p_render_shadow_count;
 		render_state.render_sdfgi_regions = p_render_sdfgi_regions;
@@ -3134,7 +3153,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
 		render_data.voxel_gi_instances = &empty;
 	}
 
-	//sdfgi first
+	// sdfgi first
 	if (rb.is_valid() && rb->has_custom_data(RB_SCOPE_SDFGI)) {
 		Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
 		float exposure_normalization = 1.0;
@@ -3191,12 +3210,12 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
 			Ref<RendererRD::GI::SDFGI> sdfgi = rb->get_custom_data(RB_SCOPE_SDFGI);
 			if (sdfgi.is_valid()) {
 				sdfgi->update_cascades();
-				sdfgi->pre_process_gi(render_data.cam_transform, &render_data, this);
+				sdfgi->pre_process_gi(scene_data.cam_transform, &render_data, this);
 				sdfgi->update_light();
 			}
 		}
 
-		gi.setup_voxel_gi_instances(&render_data, render_data.render_buffers, render_data.cam_transform, *render_data.voxel_gi_instances, render_state.voxel_gi_count, this);
+		gi.setup_voxel_gi_instances(&render_data, render_data.render_buffers, scene_data.cam_transform, *render_data.voxel_gi_instances, render_state.voxel_gi_count, this);
 	}
 
 	render_state.depth_prepass_used = false;
@@ -3246,7 +3265,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
 				view_rids.push_back(rb->get_internal_texture(v));
 			}
 
-			sdfgi->debug_draw(render_data.view_count, render_data.view_projection, render_data.cam_transform, size.x, size.y, rb->get_render_target(), source_texture, view_rids);
+			sdfgi->debug_draw(scene_data.view_count, scene_data.view_projection, scene_data.cam_transform, size.x, size.y, rb->get_render_target(), source_texture, view_rids);
 		}
 	}
 }

+ 6 - 29
servers/rendering/renderer_rd/renderer_scene_render_rd.h

@@ -46,30 +46,14 @@
 #include "servers/rendering/renderer_rd/environment/sky.h"
 #include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
 #include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h"
 #include "servers/rendering/renderer_scene.h"
 #include "servers/rendering/renderer_scene_render.h"
 #include "servers/rendering/rendering_device.h"
 
 struct RenderDataRD {
 	Ref<RenderSceneBuffersRD> render_buffers;
-
-	Transform3D cam_transform;
-	Projection cam_projection;
-	Vector2 taa_jitter;
-	bool cam_orthogonal = false;
-
-	// For stereo rendering
-	uint32_t view_count = 1;
-	Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS];
-	Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
-
-	Transform3D prev_cam_transform;
-	Projection prev_cam_projection;
-	Vector2 prev_taa_jitter;
-	Projection prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
-
-	float z_near = 0.0;
-	float z_far = 0.0;
+	RenderSceneDataRD *scene_data;
 
 	const PagedArray<RenderGeometryInstance *> *instances = nullptr;
 	const PagedArray<RID> *lights = nullptr;
@@ -85,10 +69,6 @@ struct RenderDataRD {
 	RID reflection_probe;
 	int reflection_probe_pass = 0;
 
-	float lod_distance_multiplier = 0.0;
-	Plane lod_camera_plane;
-	float screen_mesh_lod_threshold = 0.0;
-
 	RID cluster_buffer;
 	uint32_t cluster_size = 0;
 	uint32_t cluster_max_elements = 0;
@@ -598,13 +578,6 @@ private:
 	uint64_t scene_pass = 0;
 	uint64_t shadow_atlas_realloc_tolerance_msec = 500;
 
-	/* !BAS! is this used anywhere?
-	struct SDFGICosineNeighbour {
-		uint32_t neighbour;
-		float weight;
-	};
-	*/
-
 	uint32_t max_cluster_elements = 512;
 
 	void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RendererScene::RenderInfo *p_render_info = nullptr);
@@ -627,6 +600,10 @@ public:
 
 	RendererRD::GI *get_gi() { return &gi; }
 
+	/* SKY */
+
+	RendererRD::SkyRD *get_sky() { return &sky; }
+
 	/* SHADOW ATLAS API */
 
 	virtual RID shadow_atlas_create() override;

+ 2 - 0
servers/rendering/renderer_rd/shaders/SCsub

@@ -18,3 +18,5 @@ if "RD_GLSL" in env["BUILDERS"]:
 
 SConscript("effects/SCsub")
 SConscript("environment/SCsub")
+SConscript("forward_clustered/SCsub")
+SConscript("forward_mobile/SCsub")

+ 17 - 0
servers/rendering/renderer_rd/shaders/forward_clustered/SCsub

@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+Import("env")
+
+if "RD_GLSL" in env["BUILDERS"]:
+    # find all include files
+    gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
+
+    # find all shader code(all glsl files excluding our include files)
+    glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
+
+    # make sure we recompile shaders if include files change
+    env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
+
+    # compile shaders
+    for glsl_file in glsl_files:
+        env.RD_GLSL(glsl_file)

+ 25 - 25
servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl → servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl

@@ -326,10 +326,6 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
 
 	vertex_interp = vertex;
 
-#ifdef MOTION_VECTORS
-	screen_pos = projection_matrix * vec4(vertex_interp, 1.0);
-#endif
-
 #ifdef NORMAL_USED
 	normal_interp = normal;
 #endif
@@ -367,6 +363,10 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
 	gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
 #endif
 
+#ifdef MOTION_VECTORS
+	screen_pos = gl_Position;
+#endif
+
 #ifdef MODE_RENDER_DEPTH
 	if (scene_data.pancake_shadows) {
 		if (gl_Position.z <= 0.00001) {
@@ -553,7 +553,7 @@ layout(location = 0) out vec4 frag_color;
 layout(location = 2) out vec2 motion_vector;
 #endif
 
-#include "scene_forward_aa_inc.glsl"
+#include "../scene_forward_aa_inc.glsl"
 
 #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
 
@@ -562,20 +562,20 @@ layout(location = 2) out vec2 motion_vector;
 #define SPECULAR_SCHLICK_GGX
 #endif
 
-#include "scene_forward_lights_inc.glsl"
+#include "../scene_forward_lights_inc.glsl"
 
-#include "scene_forward_gi_inc.glsl"
+#include "../scene_forward_gi_inc.glsl"
 
 #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
 
 #ifndef MODE_RENDER_DEPTH
 
 vec4 volumetric_fog_process(vec2 screen_uv, float z) {
-	vec3 fog_pos = vec3(screen_uv, z * scene_data_block.data.volumetric_fog_inv_length);
+	vec3 fog_pos = vec3(screen_uv, z * implementation_data.volumetric_fog_inv_length);
 	if (fog_pos.z < 0.0) {
 		return vec4(0.0);
 	} else if (fog_pos.z < 1.0) {
-		fog_pos.z = pow(fog_pos.z, scene_data_block.data.volumetric_fog_detail_spread);
+		fog_pos.z = pow(fog_pos.z, implementation_data.volumetric_fog_detail_spread);
 	}
 
 	return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos);
@@ -821,7 +821,7 @@ void fragment_shader(in SceneData scene_data) {
 		fog = fog_process(vertex);
 	}
 
-	if (scene_data.volumetric_fog_enabled) {
+	if (implementation_data.volumetric_fog_enabled) {
 		vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z);
 		if (scene_data.fog_enabled) {
 			//must use the full blending equation here to blend fogs
@@ -849,8 +849,8 @@ void fragment_shader(in SceneData scene_data) {
 
 #ifndef MODE_RENDER_DEPTH
 
-	uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> scene_data.cluster_shift;
-	uint cluster_offset = (scene_data.cluster_width * cluster_pos.y + cluster_pos.x) * (scene_data.max_cluster_element_count_div_32 + 32);
+	uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> implementation_data.cluster_shift;
+	uint cluster_offset = (implementation_data.cluster_width * cluster_pos.y + cluster_pos.x) * (implementation_data.max_cluster_element_count_div_32 + 32);
 
 	uint cluster_z = uint(clamp((-vertex.z / scene_data.z_far) * 32.0, 0.0, 31.0));
 
@@ -860,14 +860,14 @@ void fragment_shader(in SceneData scene_data) {
 
 	{ // process decals
 
-		uint cluster_decal_offset = cluster_offset + scene_data.cluster_type_size * 2;
+		uint cluster_decal_offset = cluster_offset + implementation_data.cluster_type_size * 2;
 
 		uint item_min;
 		uint item_max;
 		uint item_from;
 		uint item_to;
 
-		cluster_get_item_range(cluster_decal_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+		cluster_get_item_range(cluster_decal_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
 
 #ifdef USE_SUBGROUPS
 		item_from = subgroupBroadcastFirst(subgroupMin(item_from));
@@ -1256,7 +1256,7 @@ void fragment_shader(in SceneData scene_data) {
 
 		vec2 coord;
 
-		if (scene_data.gi_upscale_for_msaa) {
+		if (implementation_data.gi_upscale_for_msaa) {
 			vec2 base_coord = screen_uv;
 			vec2 closest_coord = base_coord;
 #ifdef USE_MULTIVIEW
@@ -1298,10 +1298,10 @@ void fragment_shader(in SceneData scene_data) {
 	}
 #endif // !USE_LIGHTMAP
 
-	if (bool(scene_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) {
+	if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSAO)) {
 		float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
 		ao = min(ao, ssao);
-		ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect);
+		ao_light_affect = mix(ao_light_affect, max(ao_light_affect, implementation_data.ssao_light_affect), implementation_data.ssao_ao_affect);
 	}
 
 	{ // process reflections
@@ -1309,14 +1309,14 @@ void fragment_shader(in SceneData scene_data) {
 		vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
 		vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
 
-		uint cluster_reflection_offset = cluster_offset + scene_data.cluster_type_size * 3;
+		uint cluster_reflection_offset = cluster_offset + implementation_data.cluster_type_size * 3;
 
 		uint item_min;
 		uint item_max;
 		uint item_from;
 		uint item_to;
 
-		cluster_get_item_range(cluster_reflection_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+		cluster_get_item_range(cluster_reflection_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
 
 #ifdef USE_SUBGROUPS
 		item_from = subgroupBroadcastFirst(subgroupMin(item_from));
@@ -1380,7 +1380,7 @@ void fragment_shader(in SceneData scene_data) {
 	// convert ao to direct light ao
 	ao = mix(1.0, ao, ao_light_affect);
 
-	if (bool(scene_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) {
+	if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) {
 		vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0);
 		ambient_light *= 1.0 - ssil.a;
 		ambient_light += ssil.rgb * albedo.rgb;
@@ -1748,7 +1748,7 @@ void fragment_shader(in SceneData scene_data) {
 		uint item_from;
 		uint item_to;
 
-		cluster_get_item_range(cluster_omni_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+		cluster_get_item_range(cluster_omni_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
 
 #ifdef USE_SUBGROUPS
 		item_from = subgroupBroadcastFirst(subgroupMin(item_from));
@@ -1812,14 +1812,14 @@ void fragment_shader(in SceneData scene_data) {
 
 	{ //spot lights
 
-		uint cluster_spot_offset = cluster_offset + scene_data.cluster_type_size;
+		uint cluster_spot_offset = cluster_offset + implementation_data.cluster_type_size;
 
 		uint item_min;
 		uint item_max;
 		uint item_from;
 		uint item_to;
 
-		cluster_get_item_range(cluster_spot_offset + scene_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
+		cluster_get_item_range(cluster_spot_offset + implementation_data.max_cluster_element_count_div_32 + cluster_z, item_min, item_max, item_from, item_to);
 
 #ifdef USE_SUBGROUPS
 		item_from = subgroupBroadcastFirst(subgroupMin(item_from));
@@ -1909,8 +1909,8 @@ void fragment_shader(in SceneData scene_data) {
 #ifdef MODE_RENDER_SDF
 
 	{
-		vec3 local_pos = (scene_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
-		ivec3 grid_pos = scene_data.sdf_offset + ivec3(local_pos * vec3(scene_data.sdf_size));
+		vec3 local_pos = (implementation_data.sdf_to_bounds * vec4(vertex, 1.0)).xyz;
+		ivec3 grid_pos = implementation_data.sdf_offset + ivec3(local_pos * vec3(implementation_data.sdf_size));
 
 		uint albedo16 = 0x1; //solid flag
 		albedo16 |= clamp(uint(albedo.r * 31.0), 0, 31) << 11;

+ 44 - 95
servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl → servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl

@@ -17,8 +17,9 @@
 #extension GL_EXT_multiview : enable
 #endif
 
-#include "cluster_data_inc.glsl"
-#include "decal_data_inc.glsl"
+#include "../cluster_data_inc.glsl"
+#include "../decal_data_inc.glsl"
+#include "../scene_data_inc.glsl"
 
 #if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(MODE_RENDER_SDF) || defined(MODE_RENDER_NORMAL_ROUGHNESS) || defined(MODE_RENDER_VOXEL_GI) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
 #ifndef NORMAL_USED
@@ -38,7 +39,7 @@ draw_call;
 
 /* Set 0: Base Pass (never changes) */
 
-#include "light_data_inc.glsl"
+#include "../light_data_inc.glsl"
 
 #define SAMPLER_NEAREST_CLAMP 0
 #define SAMPLER_LINEAR_CLAMP 1
@@ -175,62 +176,27 @@ sdfgi;
 
 /* Set 1: Render Pass (changes per render pass) */
 
-struct SceneData {
-	mat4 projection_matrix;
-	mat4 inv_projection_matrix;
-	mat4 inv_view_matrix;
-	mat4 view_matrix;
-
-	// only used for multiview
-	mat4 projection_matrix_view[MAX_VIEWS];
-	mat4 inv_projection_matrix_view[MAX_VIEWS];
-	vec4 eye_offset[MAX_VIEWS];
-
-	vec2 viewport_size;
-	vec2 screen_pixel_size;
+layout(set = 1, binding = 0, std140) uniform SceneDataBlock {
+	SceneData data;
+	SceneData prev_data;
+}
+scene_data_block;
 
+struct ImplementationData {
 	uint cluster_shift;
 	uint cluster_width;
 	uint cluster_type_size;
 	uint max_cluster_element_count_div_32;
 
-	// Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted.
-	vec4 directional_penumbra_shadow_kernel[32];
-	vec4 directional_soft_shadow_kernel[32];
-	vec4 penumbra_shadow_kernel[32];
-	vec4 soft_shadow_kernel[32];
-
-	vec4 ambient_light_color_energy;
-
-	float ambient_color_sky_mix;
-	bool use_ambient_light;
-	bool use_ambient_cubemap;
-	bool use_reflection_cubemap;
-
-	mat3 radiance_inverse_xform;
-
-	vec2 shadow_atlas_pixel_size;
-	vec2 directional_shadow_pixel_size;
-
-	uint directional_light_count;
-	float dual_paraboloid_side;
-	float z_far;
-	float z_near;
-
 	uint ss_effects_flags;
 	float ssao_light_affect;
 	float ssao_ao_affect;
-	bool roughness_limiter_enabled;
-
-	float roughness_limiter_amount;
-	float roughness_limiter_limit;
-	float opaque_prepass_threshold;
-	uint roughness_limiter_pad;
+	uint pad1;
 
 	mat4 sdf_to_bounds;
 
 	ivec3 sdf_offset;
-	bool material_uv2_mode;
+	uint pad2;
 
 	ivec3 sdf_size;
 	bool gi_upscale_for_msaa;
@@ -239,31 +205,14 @@ struct SceneData {
 	float volumetric_fog_inv_length;
 	float volumetric_fog_detail_spread;
 	uint volumetric_fog_pad;
-
-	bool fog_enabled;
-	float fog_density;
-	float fog_height;
-	float fog_height_density;
-
-	vec3 fog_light_color;
-	float fog_sun_scatter;
-
-	float fog_aerial_perspective;
-
-	float time;
-	float reflection_multiplier; // one normally, zero when rendering reflections
-
-	bool pancake_shadows;
-	vec2 taa_jitter;
-	float emissive_exposure_normalization;
-	float IBL_exposure_normalization;
 };
 
-layout(set = 1, binding = 0, std140) uniform SceneDataBlock {
-	SceneData data;
-	SceneData prev_data;
+layout(set = 1, binding = 1, std140) uniform ImplementationDataBlock {
+	ImplementationData data;
 }
-scene_data_block;
+implementation_data_block;
+
+#define implementation_data implementation_data_block.data
 
 struct InstanceData {
 	mat4 transform;
@@ -275,42 +224,42 @@ struct InstanceData {
 	vec4 lightmap_uv_scale;
 };
 
-layout(set = 1, binding = 1, std430) buffer restrict readonly InstanceDataBuffer {
+layout(set = 1, binding = 2, std430) buffer restrict readonly InstanceDataBuffer {
 	InstanceData data[];
 }
 instances;
 
 #ifdef USE_RADIANCE_CUBEMAP_ARRAY
 
-layout(set = 1, binding = 2) uniform textureCubeArray radiance_cubemap;
+layout(set = 1, binding = 3) uniform textureCubeArray radiance_cubemap;
 
 #else
 
-layout(set = 1, binding = 2) uniform textureCube radiance_cubemap;
+layout(set = 1, binding = 3) uniform textureCube radiance_cubemap;
 
 #endif
 
-layout(set = 1, binding = 3) uniform textureCubeArray reflection_atlas;
+layout(set = 1, binding = 4) uniform textureCubeArray reflection_atlas;
 
-layout(set = 1, binding = 4) uniform texture2D shadow_atlas;
+layout(set = 1, binding = 5) uniform texture2D shadow_atlas;
 
-layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas;
+layout(set = 1, binding = 6) uniform texture2D directional_shadow_atlas;
 
-layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
+layout(set = 1, binding = 7) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
 
-layout(set = 1, binding = 7) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
+layout(set = 1, binding = 8) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
 
-layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer {
+layout(set = 1, binding = 9, std430) buffer restrict readonly ClusterBuffer {
 	uint data[];
 }
 cluster_buffer;
 
 #ifdef MODE_RENDER_SDF
 
-layout(r16ui, set = 1, binding = 9) uniform restrict writeonly uimage3D albedo_volume_grid;
-layout(r32ui, set = 1, binding = 10) uniform restrict writeonly uimage3D emission_grid;
-layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_aniso_grid;
-layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid;
+layout(r16ui, set = 1, binding = 10) uniform restrict writeonly uimage3D albedo_volume_grid;
+layout(r32ui, set = 1, binding = 11) uniform restrict writeonly uimage3D emission_grid;
+layout(r32ui, set = 1, binding = 12) uniform restrict writeonly uimage3D emission_aniso_grid;
+layout(r32ui, set = 1, binding = 13) 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
@@ -319,21 +268,21 @@ layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid;
 
 #else
 
-layout(set = 1, binding = 9) uniform texture2D depth_buffer;
-layout(set = 1, binding = 10) uniform texture2D color_buffer;
+layout(set = 1, binding = 10) uniform texture2D depth_buffer;
+layout(set = 1, binding = 11) uniform texture2D color_buffer;
 
 #ifdef USE_MULTIVIEW
-layout(set = 1, binding = 11) uniform texture2DArray normal_roughness_buffer;
-layout(set = 1, binding = 13) uniform texture2DArray ambient_buffer;
-layout(set = 1, binding = 14) uniform texture2DArray reflection_buffer;
+layout(set = 1, binding = 12) uniform texture2DArray normal_roughness_buffer;
+layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer;
+layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer;
 #else // USE_MULTIVIEW
-layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer;
-layout(set = 1, binding = 13) uniform texture2D ambient_buffer;
-layout(set = 1, binding = 14) uniform texture2D reflection_buffer;
+layout(set = 1, binding = 12) uniform texture2D normal_roughness_buffer;
+layout(set = 1, binding = 14) uniform texture2D ambient_buffer;
+layout(set = 1, binding = 15) uniform texture2D reflection_buffer;
 #endif
-layout(set = 1, binding = 12) uniform texture2D ao_buffer;
-layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture;
-layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades;
+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;
 
 struct VoxelGIData {
 	mat4 xform; // 64 - 64
@@ -350,14 +299,14 @@ struct VoxelGIData {
 	float exposure_normalization; // 4 - 112
 };
 
-layout(set = 1, binding = 17, std140) uniform VoxelGIs {
+layout(set = 1, binding = 18, std140) uniform VoxelGIs {
 	VoxelGIData data[MAX_VOXEL_GI_INSTANCES];
 }
 voxel_gi_instances;
 
-layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture;
+layout(set = 1, binding = 19) uniform texture3D volumetric_fog_texture;
 
-layout(set = 1, binding = 19) uniform texture2D ssil_buffer;
+layout(set = 1, binding = 20) uniform texture2D ssil_buffer;
 
 #endif
 

+ 17 - 0
servers/rendering/renderer_rd/shaders/forward_mobile/SCsub

@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+Import("env")
+
+if "RD_GLSL" in env["BUILDERS"]:
+    # find all include files
+    gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
+
+    # find all shader code(all glsl files excluding our include files)
+    glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
+
+    # make sure we recompile shaders if include files change
+    env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
+
+    # compile shaders
+    for glsl_file in glsl_files:
+        env.RD_GLSL(glsl_file)

+ 4 - 4
servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl → servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl

@@ -101,7 +101,7 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms
 
 #ifdef MODE_DUAL_PARABOLOID
 
-layout(location = 8) out highp float dp_clip;
+layout(location = 9) out highp float dp_clip;
 
 #endif
 
@@ -450,7 +450,7 @@ layout(location = 6) mediump in vec3 binormal_interp;
 
 #ifdef MODE_DUAL_PARABOLOID
 
-layout(location = 8) highp in float dp_clip;
+layout(location = 9) highp in float dp_clip;
 
 #endif
 
@@ -519,7 +519,7 @@ layout(location = 0) out mediump vec4 frag_color;
 
 #endif // RENDER DEPTH
 
-#include "scene_forward_aa_inc.glsl"
+#include "../scene_forward_aa_inc.glsl"
 
 #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
 
@@ -528,7 +528,7 @@ layout(location = 0) out mediump vec4 frag_color;
 #define SPECULAR_SCHLICK_GGX
 #endif
 
-#include "scene_forward_lights_inc.glsl"
+#include "../scene_forward_lights_inc.glsl"
 
 #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
 

+ 4 - 69
servers/rendering/renderer_rd/shaders/scene_forward_mobile_inc.glsl → servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl

@@ -5,7 +5,8 @@
 #extension GL_EXT_multiview : enable
 #endif
 
-#include "decal_data_inc.glsl"
+#include "../decal_data_inc.glsl"
+#include "../scene_data_inc.glsl"
 
 #if !defined(MODE_RENDER_DEPTH) || defined(MODE_RENDER_MATERIAL) || defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
 #ifndef NORMAL_USED
@@ -32,7 +33,7 @@ draw_call;
 
 /* Set 0: Base Pass (never changes) */
 
-#include "light_data_inc.glsl"
+#include "../light_data_inc.glsl"
 
 #define SAMPLER_NEAREST_CLAMP 0
 #define SAMPLER_LINEAR_CLAMP 1
@@ -127,75 +128,9 @@ global_shader_uniforms;
 
 /* Set 1: Render Pass (changes per render pass) */
 
-struct SceneData {
-	highp mat4 projection_matrix;
-	highp mat4 inv_projection_matrix;
-	highp mat4 inv_view_matrix;
-	highp mat4 view_matrix;
-
-	// only used for multiview
-	highp mat4 projection_matrix_view[MAX_VIEWS];
-	highp mat4 inv_projection_matrix_view[MAX_VIEWS];
-	highp vec4 eye_offset[MAX_VIEWS];
-
-	highp vec2 viewport_size;
-	highp vec2 screen_pixel_size;
-
-	// Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted.
-	highp vec4 directional_penumbra_shadow_kernel[32];
-	highp vec4 directional_soft_shadow_kernel[32];
-	highp vec4 penumbra_shadow_kernel[32];
-	highp vec4 soft_shadow_kernel[32];
-
-	mediump vec4 ambient_light_color_energy;
-
-	mediump float ambient_color_sky_mix;
-	bool use_ambient_light;
-	bool use_ambient_cubemap;
-	bool use_reflection_cubemap;
-
-	mediump mat3 radiance_inverse_xform;
-
-	highp vec2 shadow_atlas_pixel_size;
-	highp vec2 directional_shadow_pixel_size;
-
-	uint directional_light_count;
-	mediump float dual_paraboloid_side;
-	highp float z_far;
-	highp float z_near;
-
-	bool ssao_enabled;
-	mediump float ssao_light_affect;
-	mediump float ssao_ao_affect;
-	bool roughness_limiter_enabled;
-
-	mediump float roughness_limiter_amount;
-	mediump float roughness_limiter_limit;
-	mediump float opaque_prepass_threshold;
-	uint roughness_limiter_pad;
-
-	bool fog_enabled;
-	highp float fog_density;
-	highp float fog_height;
-	highp float fog_height_density;
-
-	mediump vec3 fog_light_color;
-	mediump float fog_sun_scatter;
-
-	mediump float fog_aerial_perspective;
-	bool material_uv2_mode;
-
-	highp float time;
-	mediump float reflection_multiplier; // one normally, zero when rendering reflections
-
-	bool pancake_shadows;
-	float emissive_exposure_normalization;
-	float IBL_exposure_normalization;
-	uint pad3;
-};
-
 layout(set = 1, binding = 0, std140) uniform SceneDataBlock {
 	SceneData data;
+	SceneData prev_data;
 }
 scene_data_block;
 

+ 69 - 0
servers/rendering/renderer_rd/shaders/scene_data_inc.glsl

@@ -0,0 +1,69 @@
+// Scene data stores all our 3D rendering globals for a frame such as our matrices
+// where this information is independent of the different RD implementations.
+// This enables us to use this UBO in our main scene render shaders but also in
+// effects that need access to this data.
+
+struct SceneData {
+	highp mat4 projection_matrix;
+	highp mat4 inv_projection_matrix;
+	highp mat4 inv_view_matrix;
+	highp mat4 view_matrix;
+
+	// only used for multiview
+	highp mat4 projection_matrix_view[MAX_VIEWS];
+	highp mat4 inv_projection_matrix_view[MAX_VIEWS];
+	highp vec4 eye_offset[MAX_VIEWS];
+
+	highp vec2 viewport_size;
+	highp vec2 screen_pixel_size;
+
+	// Use vec4s because std140 doesn't play nice with vec2s, z and w are wasted.
+	highp vec4 directional_penumbra_shadow_kernel[32];
+	highp vec4 directional_soft_shadow_kernel[32];
+	highp vec4 penumbra_shadow_kernel[32];
+	highp vec4 soft_shadow_kernel[32];
+
+	mediump mat3 radiance_inverse_xform;
+
+	mediump vec4 ambient_light_color_energy;
+
+	mediump float ambient_color_sky_mix;
+	bool use_ambient_light;
+	bool use_ambient_cubemap;
+	bool use_reflection_cubemap;
+
+	highp vec2 shadow_atlas_pixel_size;
+	highp vec2 directional_shadow_pixel_size;
+
+	uint directional_light_count;
+	mediump float dual_paraboloid_side;
+	highp float z_far;
+	highp float z_near;
+
+	bool roughness_limiter_enabled;
+	mediump float roughness_limiter_amount;
+	mediump float roughness_limiter_limit;
+	mediump float opaque_prepass_threshold;
+
+	bool fog_enabled;
+	highp float fog_density;
+	highp float fog_height;
+	highp float fog_height_density;
+
+	mediump vec3 fog_light_color;
+	mediump float fog_sun_scatter;
+
+	mediump float fog_aerial_perspective;
+	highp float time;
+	mediump float reflection_multiplier; // one normally, zero when rendering reflections
+	bool material_uv2_mode;
+
+	vec2 taa_jitter;
+	float emissive_exposure_normalization;
+	float IBL_exposure_normalization;
+
+	bool pancake_shadows;
+	uint pad1;
+	uint pad2;
+	uint pad3;
+};

+ 246 - 0
servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.cpp

@@ -0,0 +1,246 @@
+/*************************************************************************/
+/*  render_scene_data_rd.cpp                                             */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "render_scene_data_rd.h"
+#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
+#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
+#include "servers/rendering/rendering_server_default.h"
+
+RID RenderSceneDataRD::create_uniform_buffer() {
+	return RD::get_singleton()->uniform_buffer_create(sizeof(UBODATA));
+}
+
+void RenderSceneDataRD::update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers) {
+	RendererSceneRenderRD *render_scene_render = RendererSceneRenderRD::get_singleton();
+
+	UBODATA ubo_data;
+	memset(&ubo_data, 0, sizeof(UBODATA));
+
+	// just for easy access..
+	UBO &ubo = ubo_data.ubo;
+	UBO &prev_ubo = ubo_data.prev_ubo;
+
+	Projection correction;
+	correction.set_depth_correction(p_flip_y);
+	correction.add_jitter_offset(taa_jitter);
+	Projection projection = correction * cam_projection;
+
+	//store camera into ubo
+	RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix);
+	RendererRD::MaterialStorage::store_camera(projection.inverse(), ubo.inv_projection_matrix);
+	RendererRD::MaterialStorage::store_transform(cam_transform, ubo.inv_view_matrix);
+	RendererRD::MaterialStorage::store_transform(cam_transform.affine_inverse(), ubo.view_matrix);
+
+	for (uint32_t v = 0; v < view_count; v++) {
+		projection = correction * view_projection[v];
+		RendererRD::MaterialStorage::store_camera(projection, ubo.projection_matrix_view[v]);
+		RendererRD::MaterialStorage::store_camera(projection.inverse(), ubo.inv_projection_matrix_view[v]);
+
+		ubo.eye_offset[v][0] = view_eye_offset[v].x;
+		ubo.eye_offset[v][1] = view_eye_offset[v].y;
+		ubo.eye_offset[v][2] = view_eye_offset[v].z;
+		ubo.eye_offset[v][3] = 0.0;
+	}
+
+	ubo.taa_jitter[0] = taa_jitter.x;
+	ubo.taa_jitter[1] = taa_jitter.y;
+
+	ubo.z_far = z_far;
+	ubo.z_near = z_near;
+
+	ubo.pancake_shadows = p_pancake_shadows;
+
+	RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_penumbra_shadow_kernel_get(), ubo.directional_penumbra_shadow_kernel);
+	RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->directional_soft_shadow_kernel_get(), ubo.directional_soft_shadow_kernel);
+	RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->penumbra_shadow_kernel_get(), ubo.penumbra_shadow_kernel);
+	RendererRD::MaterialStorage::store_soft_shadow_kernel(render_scene_render->soft_shadow_kernel_get(), ubo.soft_shadow_kernel);
+
+	ubo.viewport_size[0] = p_screen_size.x;
+	ubo.viewport_size[1] = p_screen_size.y;
+
+	Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
+	ubo.screen_pixel_size[0] = screen_pixel_size.x;
+	ubo.screen_pixel_size[1] = screen_pixel_size.y;
+
+	ubo.shadow_atlas_pixel_size[0] = shadow_atlas_pixel_size.x;
+	ubo.shadow_atlas_pixel_size[1] = shadow_atlas_pixel_size.y;
+
+	ubo.directional_shadow_pixel_size[0] = directional_shadow_pixel_size.x;
+	ubo.directional_shadow_pixel_size[1] = directional_shadow_pixel_size.y;
+
+	ubo.time = time;
+
+	ubo.directional_light_count = directional_light_count;
+	ubo.dual_paraboloid_side = dual_paraboloid_side;
+	ubo.opaque_prepass_threshold = opaque_prepass_threshold;
+	ubo.material_uv2_mode = material_uv2_mode;
+
+	ubo.fog_enabled = false;
+
+	if (p_debug_mode == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
+		ubo.use_ambient_light = true;
+		ubo.ambient_light_color_energy[0] = 1;
+		ubo.ambient_light_color_energy[1] = 1;
+		ubo.ambient_light_color_energy[2] = 1;
+		ubo.ambient_light_color_energy[3] = 1.0;
+		ubo.use_ambient_cubemap = false;
+		ubo.use_reflection_cubemap = false;
+	} else if (p_env.is_valid()) {
+		RS::EnvironmentBG env_bg = render_scene_render->environment_get_background(p_env);
+		RS::EnvironmentAmbientSource ambient_src = render_scene_render->environment_get_ambient_source(p_env);
+
+		float bg_energy_multiplier = render_scene_render->environment_get_bg_energy_multiplier(p_env);
+
+		ubo.ambient_light_color_energy[3] = bg_energy_multiplier;
+
+		ubo.ambient_color_sky_mix = render_scene_render->environment_get_ambient_sky_contribution(p_env);
+
+		//ambient
+		if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {
+			Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : render_scene_render->environment_get_bg_color(p_env);
+			color = color.srgb_to_linear();
+
+			ubo.ambient_light_color_energy[0] = color.r * bg_energy_multiplier;
+			ubo.ambient_light_color_energy[1] = color.g * bg_energy_multiplier;
+			ubo.ambient_light_color_energy[2] = color.b * bg_energy_multiplier;
+			ubo.use_ambient_light = true;
+			ubo.use_ambient_cubemap = false;
+		} else {
+			float energy = render_scene_render->environment_get_ambient_light_energy(p_env);
+			Color color = render_scene_render->environment_get_ambient_light(p_env);
+			color = color.srgb_to_linear();
+			ubo.ambient_light_color_energy[0] = color.r * energy;
+			ubo.ambient_light_color_energy[1] = color.g * energy;
+			ubo.ambient_light_color_energy[2] = color.b * energy;
+
+			Basis sky_transform = render_scene_render->environment_get_sky_orientation(p_env);
+			sky_transform = sky_transform.inverse() * cam_transform.basis;
+			RendererRD::MaterialStorage::store_transform_3x3(sky_transform, ubo.radiance_inverse_xform);
+
+			ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
+			ubo.use_ambient_light = ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
+		}
+
+		//specular
+		RS::EnvironmentReflectionSource ref_src = render_scene_render->environment_get_reflection_source(p_env);
+		if ((ref_src == RS::ENV_REFLECTION_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ref_src == RS::ENV_REFLECTION_SOURCE_SKY) {
+			ubo.use_reflection_cubemap = true;
+		} else {
+			ubo.use_reflection_cubemap = false;
+		}
+
+		ubo.fog_enabled = render_scene_render->environment_get_fog_enabled(p_env);
+		ubo.fog_density = render_scene_render->environment_get_fog_density(p_env);
+		ubo.fog_height = render_scene_render->environment_get_fog_height(p_env);
+		ubo.fog_height_density = render_scene_render->environment_get_fog_height_density(p_env);
+		ubo.fog_aerial_perspective = render_scene_render->environment_get_fog_aerial_perspective(p_env);
+
+		Color fog_color = render_scene_render->environment_get_fog_light_color(p_env).srgb_to_linear();
+		float fog_energy = render_scene_render->environment_get_fog_light_energy(p_env);
+
+		ubo.fog_light_color[0] = fog_color.r * fog_energy;
+		ubo.fog_light_color[1] = fog_color.g * fog_energy;
+		ubo.fog_light_color[2] = fog_color.b * fog_energy;
+
+		ubo.fog_sun_scatter = render_scene_render->environment_get_fog_sun_scatter(p_env);
+	} else {
+		if (p_reflection_probe_instance.is_valid() && RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(p_reflection_probe_instance)) {
+			ubo.use_ambient_light = false;
+		} else {
+			ubo.use_ambient_light = true;
+			Color clear_color = p_default_bg_color;
+			clear_color = clear_color.srgb_to_linear();
+			ubo.ambient_light_color_energy[0] = clear_color.r;
+			ubo.ambient_light_color_energy[1] = clear_color.g;
+			ubo.ambient_light_color_energy[2] = clear_color.b;
+			ubo.ambient_light_color_energy[3] = 1.0;
+		}
+
+		ubo.use_ambient_cubemap = false;
+		ubo.use_reflection_cubemap = false;
+	}
+
+	if (p_camera_attributes.is_valid()) {
+		ubo.emissive_exposure_normalization = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes);
+		ubo.IBL_exposure_normalization = 1.0;
+		if (p_env.is_valid()) {
+			RID sky_rid = render_scene_render->environment_get_sky(p_env);
+			if (sky_rid.is_valid()) {
+				float current_exposure = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_camera_attributes) * render_scene_render->environment_get_bg_intensity(p_env) / p_luminance_multiplier;
+				ubo.IBL_exposure_normalization = current_exposure / MAX(0.001, render_scene_render->get_sky()->sky_get_baked_exposure(sky_rid));
+			}
+		}
+	} else if (emissive_exposure_normalization > 0.0) {
+		// This branch is triggered when using render_material().
+		// Emissive is set outside the function.
+		ubo.emissive_exposure_normalization = emissive_exposure_normalization;
+		// IBL isn't used don't set it.
+	} else {
+		ubo.emissive_exposure_normalization = 1.0;
+		ubo.IBL_exposure_normalization = 1.0;
+	}
+
+	ubo.roughness_limiter_enabled = p_opaque_render_buffers && render_scene_render->screen_space_roughness_limiter_is_active();
+	ubo.roughness_limiter_amount = render_scene_render->screen_space_roughness_limiter_get_amount();
+	ubo.roughness_limiter_limit = render_scene_render->screen_space_roughness_limiter_get_limit();
+
+	if (calculate_motion_vectors) {
+		// Q : Should we make a complete copy or should we define a separate UBO with just the components we need?
+		memcpy(&prev_ubo, &ubo, sizeof(UBO));
+
+		Projection prev_correction;
+		prev_correction.set_depth_correction(true);
+		prev_correction.add_jitter_offset(prev_taa_jitter);
+		Projection prev_projection = prev_correction * prev_cam_projection;
+
+		//store camera into ubo
+		RendererRD::MaterialStorage::store_camera(prev_projection, prev_ubo.projection_matrix);
+		RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), prev_ubo.inv_projection_matrix);
+		RendererRD::MaterialStorage::store_transform(prev_cam_transform, prev_ubo.inv_view_matrix);
+		RendererRD::MaterialStorage::store_transform(prev_cam_transform.affine_inverse(), prev_ubo.view_matrix);
+
+		for (uint32_t v = 0; v < view_count; v++) {
+			prev_projection = prev_correction * view_projection[v];
+			RendererRD::MaterialStorage::store_camera(prev_projection, prev_ubo.projection_matrix_view[v]);
+			RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), prev_ubo.inv_projection_matrix_view[v]);
+		}
+		prev_ubo.taa_jitter[0] = prev_taa_jitter.x;
+		prev_ubo.taa_jitter[1] = prev_taa_jitter.y;
+		prev_ubo.time -= time_step;
+	}
+
+	uniform_buffer = p_uniform_buffer;
+	RD::get_singleton()->buffer_update(uniform_buffer, 0, sizeof(UBODATA), &ubo, RD::BARRIER_MASK_RASTER);
+}
+
+RID RenderSceneDataRD::get_uniform_buffer() {
+	return uniform_buffer;
+}

+ 157 - 0
servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h

@@ -0,0 +1,157 @@
+/*************************************************************************/
+/*  render_scene_data_rd.h                                               */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef RENDER_SCENE_DATA_RD_H
+#define RENDER_SCENE_DATA_RD_H
+
+#include "render_scene_buffers_rd.h"
+#include "servers/rendering/renderer_scene_render.h"
+#include "servers/rendering/rendering_device.h"
+
+// This is a container for data related to rendering a single frame of a viewport where we load this data into a UBO
+// that can be used by the main scene shader but also by various effects.
+
+class RenderSceneDataRD {
+public:
+	bool calculate_motion_vectors = false;
+
+	Transform3D cam_transform;
+	Projection cam_projection;
+	Vector2 taa_jitter;
+	bool cam_orthogonal = false;
+
+	// For stereo rendering
+	uint32_t view_count = 1;
+	Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS];
+	Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
+
+	Transform3D prev_cam_transform;
+	Projection prev_cam_projection;
+	Vector2 prev_taa_jitter;
+	Projection prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS];
+
+	float z_near = 0.0;
+	float z_far = 0.0;
+
+	float lod_distance_multiplier = 0.0;
+	Plane lod_camera_plane;
+	float screen_mesh_lod_threshold = 0.0;
+
+	uint32_t directional_light_count = 0;
+	float dual_paraboloid_side = 0.0;
+	float opaque_prepass_threshold = 0.0;
+	bool material_uv2_mode = false;
+	float emissive_exposure_normalization = 0.0;
+
+	Size2 shadow_atlas_pixel_size;
+	Size2 directional_shadow_pixel_size;
+
+	float time;
+	float time_step;
+
+	RID create_uniform_buffer();
+	void update_ubo(RID p_uniform_buffer, RS::ViewportDebugDraw p_debug_mode, RID p_env, RID p_reflection_probe_instance, RID p_camera_attributes, bool p_flip_y, bool p_pancake_shadows, const Size2i &p_screen_size, const Color &p_default_bg_color, float p_luminance_multiplier, bool p_opaque_render_buffers);
+	RID get_uniform_buffer();
+
+private:
+	RID uniform_buffer; // loaded into this uniform buffer (supplied externally)
+
+	// This struct is loaded into Set 1 - Binding 0, populated at start of rendering a frame, must match with shader code
+	struct UBO {
+		float projection_matrix[16];
+		float inv_projection_matrix[16];
+		float inv_view_matrix[16];
+		float view_matrix[16];
+
+		float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
+		float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
+		float eye_offset[RendererSceneRender::MAX_RENDER_VIEWS][4];
+
+		float viewport_size[2];
+		float screen_pixel_size[2];
+
+		float directional_penumbra_shadow_kernel[128]; //32 vec4s
+		float directional_soft_shadow_kernel[128];
+		float penumbra_shadow_kernel[128];
+		float soft_shadow_kernel[128];
+
+		float radiance_inverse_xform[12];
+
+		float ambient_light_color_energy[4];
+
+		float ambient_color_sky_mix;
+		uint32_t use_ambient_light;
+		uint32_t use_ambient_cubemap;
+		uint32_t use_reflection_cubemap;
+
+		float shadow_atlas_pixel_size[2];
+		float directional_shadow_pixel_size[2];
+
+		uint32_t directional_light_count;
+		float dual_paraboloid_side;
+		float z_far;
+		float z_near;
+
+		uint32_t roughness_limiter_enabled;
+		float roughness_limiter_amount;
+		float roughness_limiter_limit;
+		float opaque_prepass_threshold;
+
+		// Fog
+		uint32_t fog_enabled;
+		float fog_density;
+		float fog_height;
+		float fog_height_density;
+
+		float fog_light_color[3];
+		float fog_sun_scatter;
+
+		float fog_aerial_perspective;
+		float time;
+		float reflection_multiplier;
+		uint32_t material_uv2_mode;
+
+		float taa_jitter[2];
+		float emissive_exposure_normalization; // Needed to normalize emissive when using physical units.
+		float IBL_exposure_normalization; // Adjusts for baked exposure.
+
+		uint32_t pancake_shadows;
+		uint32_t pad1;
+		uint32_t pad2;
+		uint32_t pad3;
+	};
+
+	struct UBODATA {
+		UBO ubo;
+		UBO prev_ubo;
+	};
+};
+
+#endif // RENDER_SCENE_DATA_RD_H

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