Browse Source

Merge pull request #57104 from clayjohn/VULKAN-sky-conflict

Rémi Verschelde 3 years ago
parent
commit
11cefc2b28

+ 1 - 1
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

@@ -1390,7 +1390,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
 				projection = correction * p_render_data->cam_projection;
 				projection = correction * p_render_data->cam_projection;
 			}
 			}
 
 
-			sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this);
+			sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this);
 
 
 			RID sky_rid = env->sky;
 			RID sky_rid = env->sky;
 			if (sky_rid.is_valid()) {
 			if (sky_rid.is_valid()) {

+ 1 - 1
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

@@ -633,7 +633,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 				projection = correction * p_render_data->cam_projection;
 				projection = correction * p_render_data->cam_projection;
 			}
 			}
 
 
-			sky.setup(env, p_render_data->render_buffers, projection, p_render_data->cam_transform, screen_size, this);
+			sky.setup(env, p_render_data->render_buffers, *p_render_data->lights, projection, p_render_data->cam_transform, screen_size, this);
 
 
 			RID sky_rid = env->sky;
 			RID sky_rid = env->sky;
 			if (sky_rid.is_valid()) {
 			if (sky_rid.is_valid()) {

+ 4 - 38
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -3263,7 +3263,6 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 
 
 	r_directional_light_count = 0;
 	r_directional_light_count = 0;
 	r_positional_light_count = 0;
 	r_positional_light_count = 0;
-	sky.sky_scene_state.ubo.directional_light_count = 0;
 
 
 	Plane camera_plane(-p_camera_transform.basis.get_axis(Vector3::AXIS_Z).normalized(), p_camera_transform.origin);
 	Plane camera_plane(-p_camera_transform.basis.get_axis(Vector3::AXIS_Z).normalized(), p_camera_transform.origin);
 
 
@@ -3284,43 +3283,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 		RS::LightType type = storage->light_get_type(base);
 		RS::LightType type = storage->light_get_type(base);
 		switch (type) {
 		switch (type) {
 			case RS::LIGHT_DIRECTIONAL: {
 			case RS::LIGHT_DIRECTIONAL: {
-				//	Copy to SkyDirectionalLightData
-				if (r_directional_light_count < sky.sky_scene_state.max_directional_lights) {
-					RendererSceneSkyRD::SkyDirectionalLightData &sky_light_data = sky.sky_scene_state.directional_lights[r_directional_light_count];
-					Transform3D light_transform = li->transform;
-					Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
-
-					sky_light_data.direction[0] = world_direction.x;
-					sky_light_data.direction[1] = world_direction.y;
-					sky_light_data.direction[2] = -world_direction.z;
-
-					float sign = storage->light_is_negative(base) ? -1 : 1;
-					sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
-
-					Color linear_col = storage->light_get_color(base).to_linear();
-					sky_light_data.color[0] = linear_col.r;
-					sky_light_data.color[1] = linear_col.g;
-					sky_light_data.color[2] = linear_col.b;
-
-					sky_light_data.enabled = true;
-
-					float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
-					if (angular_diameter > 0.0) {
-						// I know tan(0) is 0, but let's not risk it with numerical precision.
-						// technically this will keep expanding until reaching the sun, but all we care
-						// is expand until we reach the radius of the near plane (there can't be more occluders than that)
-						angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
-						if (storage->light_has_shadow(base)) {
-							r_directional_light_soft_shadows = true;
-						}
-					} else {
-						angular_diameter = 0.0;
-					}
-					sky_light_data.size = angular_diameter;
-					sky.sky_scene_state.ubo.directional_light_count++;
-				}
-
-				if (r_directional_light_count >= cluster.max_directional_lights || storage->light_directional_is_sky_only(base)) {
+				if (r_directional_light_count >= cluster.max_directional_lights) {
 					continue;
 					continue;
 				}
 				}
 
 
@@ -3397,6 +3360,9 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
 					// technically this will keep expanding until reaching the sun, but all we care
 					// technically this will keep expanding until reaching the sun, but all we care
 					// is expand until we reach the radius of the near plane (there can't be more occluders than that)
 					// is expand until we reach the radius of the near plane (there can't be more occluders than that)
 					angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
 					angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
+					if (storage->light_has_shadow(base)) {
+						r_directional_light_soft_shadows = true;
+					}
 				} else {
 				} else {
 					angular_diameter = 0.0;
 					angular_diameter = 0.0;
 				}
 				}

+ 55 - 3
servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp

@@ -1040,8 +1040,8 @@ RendererSceneSkyRD::~RendererSceneSkyRD() {
 	RD::get_singleton()->free(index_buffer); //array gets freed as dependency
 	RD::get_singleton()->free(index_buffer); //array gets freed as dependency
 }
 }
 
 
-void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
-	ERR_FAIL_COND(!p_env); // I guess without an environment we also can't have a sky...
+void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
+	ERR_FAIL_COND(!p_env);
 
 
 	SkyMaterialData *material = nullptr;
 	SkyMaterialData *material = nullptr;
 	Sky *sky = get_sky(p_env->sky);
 	Sky *sky = get_sky(p_env->sky);
@@ -1122,15 +1122,67 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b
 		}
 		}
 
 
 		if (shader_data->uses_light) {
 		if (shader_data->uses_light) {
+			sky_scene_state.ubo.directional_light_count = 0;
+			// Run through the list of lights in the scene and pick out the Directional Lights.
+			// This can't be done in RenderSceneRenderRD::_setup lights because that needs to be called
+			// after the depth prepass, but this runs before the depth prepass
+			for (int i = 0; i < (int)p_lights.size(); i++) {
+				RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_lights[i]);
+				if (!li) {
+					continue;
+				}
+				RID base = li->light;
+
+				ERR_CONTINUE(base.is_null());
+
+				RS::LightType type = storage->light_get_type(base);
+				if (type == RS::LIGHT_DIRECTIONAL) {
+					SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count];
+					Transform3D light_transform = li->transform;
+					Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
+
+					sky_light_data.direction[0] = world_direction.x;
+					sky_light_data.direction[1] = world_direction.y;
+					sky_light_data.direction[2] = -world_direction.z;
+
+					float sign = storage->light_is_negative(base) ? -1 : 1;
+					sky_light_data.energy = sign * storage->light_get_param(base, RS::LIGHT_PARAM_ENERGY);
+
+					Color linear_col = storage->light_get_color(base).to_linear();
+					sky_light_data.color[0] = linear_col.r;
+					sky_light_data.color[1] = linear_col.g;
+					sky_light_data.color[2] = linear_col.b;
+
+					sky_light_data.enabled = true;
+
+					float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+					if (angular_diameter > 0.0) {
+						// I know tan(0) is 0, but let's not risk it with numerical precision.
+						// technically this will keep expanding until reaching the sun, but all we care
+						// is expand until we reach the radius of the near plane (there can't be more occluders than that)
+						angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
+					} else {
+						angular_diameter = 0.0;
+					}
+					sky_light_data.size = angular_diameter;
+					sky_scene_state.ubo.directional_light_count++;
+					if (sky_scene_state.ubo.directional_light_count >= sky_scene_state.max_directional_lights) {
+						break;
+					}
+				}
+			}
 			// Check whether the directional_light_buffer changes
 			// Check whether the directional_light_buffer changes
-			bool light_data_dirty = false;
+			bool light_data_dirty = true;
 
 
+			// Light buffer is dirty if we have fewer or more lights
+			// If we have fewer lights, make sure that old lights are disabled
 			if (sky_scene_state.ubo.directional_light_count != sky_scene_state.last_frame_directional_light_count) {
 			if (sky_scene_state.ubo.directional_light_count != sky_scene_state.last_frame_directional_light_count) {
 				light_data_dirty = true;
 				light_data_dirty = true;
 				for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) {
 				for (uint32_t i = sky_scene_state.ubo.directional_light_count; i < sky_scene_state.max_directional_lights; i++) {
 					sky_scene_state.directional_lights[i].enabled = false;
 					sky_scene_state.directional_lights[i].enabled = false;
 				}
 				}
 			}
 			}
+
 			if (!light_data_dirty) {
 			if (!light_data_dirty) {
 				for (uint32_t i = 0; i < sky_scene_state.ubo.directional_light_count; i++) {
 				for (uint32_t i = 0; i < sky_scene_state.ubo.directional_light_count; i++) {
 					if (sky_scene_state.directional_lights[i].direction[0] != sky_scene_state.last_frame_directional_lights[i].direction[0] ||
 					if (sky_scene_state.directional_lights[i].direction[0] != sky_scene_state.last_frame_directional_lights[i].direction[0] ||

+ 1 - 1
servers/rendering/renderer_rd/renderer_scene_sky_rd.h

@@ -292,7 +292,7 @@ public:
 	void set_texture_format(RD::DataFormat p_texture_format);
 	void set_texture_format(RD::DataFormat p_texture_format);
 	~RendererSceneSkyRD();
 	~RendererSceneSkyRD();
 
 
-	void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
+	void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
 	void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
 	void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
 	void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer
 	void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer
 	void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
 	void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);