Browse Source

Merge pull request #96771 from clayjohn/RD-static-lighting

Avoid calculating dynamic lights when lights are already baked using the static bake mode in the Forward+ renderer
Thaddeus Crews 8 months ago
parent
commit
a167afd70a

+ 11 - 17
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -1302,15 +1302,12 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
 					int32_t shadow_id = light_storage->light_instance_get_shadow_id(light_instance);
 					int32_t shadow_id = light_storage->light_instance_get_shadow_id(light_instance);
 
 
 					if (light_storage->light_has_shadow(light) && shadow_id >= 0) {
 					if (light_storage->light_has_shadow(light) && shadow_id >= 0) {
-						// Skip static lights when a lightmap is used.
-						if (!inst->lightmap_instance.is_valid() || light_storage->light_get_bake_mode(light) != RenderingServer::LIGHT_BAKE_STATIC) {
-							GeometryInstanceGLES3::LightPass pass;
-							pass.light_id = light_storage->light_instance_get_gl_id(light_instance);
-							pass.shadow_id = shadow_id;
-							pass.light_instance_rid = light_instance;
-							pass.is_omni = true;
-							inst->light_passes.push_back(pass);
-						}
+						GeometryInstanceGLES3::LightPass pass;
+						pass.light_id = light_storage->light_instance_get_gl_id(light_instance);
+						pass.shadow_id = shadow_id;
+						pass.light_instance_rid = light_instance;
+						pass.is_omni = true;
+						inst->light_passes.push_back(pass);
 					} else {
 					} else {
 						// Lights without shadow can all go in base pass.
 						// Lights without shadow can all go in base pass.
 						inst->omni_light_gl_cache.push_back((uint32_t)light_storage->light_instance_get_gl_id(light_instance));
 						inst->omni_light_gl_cache.push_back((uint32_t)light_storage->light_instance_get_gl_id(light_instance));
@@ -1328,14 +1325,11 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
 					int32_t shadow_id = light_storage->light_instance_get_shadow_id(light_instance);
 					int32_t shadow_id = light_storage->light_instance_get_shadow_id(light_instance);
 
 
 					if (light_storage->light_has_shadow(light) && shadow_id >= 0) {
 					if (light_storage->light_has_shadow(light) && shadow_id >= 0) {
-						// Skip static lights when a lightmap is used.
-						if (!inst->lightmap_instance.is_valid() || light_storage->light_get_bake_mode(light) != RenderingServer::LIGHT_BAKE_STATIC) {
-							GeometryInstanceGLES3::LightPass pass;
-							pass.light_id = light_storage->light_instance_get_gl_id(light_instance);
-							pass.shadow_id = shadow_id;
-							pass.light_instance_rid = light_instance;
-							inst->light_passes.push_back(pass);
-						}
+						GeometryInstanceGLES3::LightPass pass;
+						pass.light_id = light_storage->light_instance_get_gl_id(light_instance);
+						pass.shadow_id = shadow_id;
+						pass.light_instance_rid = light_instance;
+						inst->light_passes.push_back(pass);
 					} else {
 					} else {
 						// Lights without shadow can all go in base pass.
 						// Lights without shadow can all go in base pass.
 						inst->spot_light_gl_cache.push_back((uint32_t)light_storage->light_instance_get_gl_id(light_instance));
 						inst->spot_light_gl_cache.push_back((uint32_t)light_storage->light_instance_get_gl_id(light_instance));

+ 11 - 10
drivers/gles3/shaders/scene.glsl

@@ -275,6 +275,10 @@ struct DirectionalLightData {
 layout(std140) uniform DirectionalLights { // ubo:7
 layout(std140) uniform DirectionalLights { // ubo:7
 	DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
 	DirectionalLightData directional_lights[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
 };
 };
+
+#define LIGHT_BAKE_DISABLED 0u
+#define LIGHT_BAKE_STATIC 1u
+#define LIGHT_BAKE_DYNAMIC 2u
 #endif // !DISABLE_LIGHT_DIRECTIONAL
 #endif // !DISABLE_LIGHT_DIRECTIONAL
 
 
 // Omni and spot light data.
 // Omni and spot light data.
@@ -723,6 +727,11 @@ void main() {
 #ifdef BASE_PASS
 #ifdef BASE_PASS
 #ifndef DISABLE_LIGHT_DIRECTIONAL
 #ifndef DISABLE_LIGHT_DIRECTIONAL
 	for (uint i = uint(0); i < scene_data.directional_light_count; i++) {
 	for (uint i = uint(0); i < scene_data.directional_light_count; i++) {
+#if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP)
+		if (directional_lights[i].bake_mode == LIGHT_BAKE_STATIC) {
+			continue;
+		}
+#endif
 		light_compute(normal_interp, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].color * directional_lights[i].energy, true, roughness,
 		light_compute(normal_interp, normalize(directional_lights[i].direction), normalize(view), directional_lights[i].color * directional_lights[i].energy, true, roughness,
 				diffuse_light_interp.rgb,
 				diffuse_light_interp.rgb,
 				specular_light_interp.rgb);
 				specular_light_interp.rgb);
@@ -2138,11 +2147,7 @@ void main() {
 		if (i >= omni_light_count) {
 		if (i >= omni_light_count) {
 			break;
 			break;
 		}
 		}
-#if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP)
-		if (omni_lights[omni_light_indices[i]].bake_mode == LIGHT_BAKE_STATIC) {
-			continue;
-		}
-#endif
+
 		light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 1.0, albedo, alpha, screen_uv,
 		light_process_omni(omni_light_indices[i], vertex, view, normal, f0, roughness, metallic, 1.0, albedo, alpha, screen_uv,
 #ifdef LIGHT_BACKLIGHT_USED
 #ifdef LIGHT_BACKLIGHT_USED
 				backlight,
 				backlight,
@@ -2166,11 +2171,7 @@ void main() {
 		if (i >= spot_light_count) {
 		if (i >= spot_light_count) {
 			break;
 			break;
 		}
 		}
-#if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP)
-		if (spot_lights[spot_light_indices[i]].bake_mode == LIGHT_BAKE_STATIC) {
-			continue;
-		}
-#endif
+
 		light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 1.0, albedo, alpha, screen_uv,
 		light_process_spot(spot_light_indices[i], vertex, view, normal, f0, roughness, metallic, 1.0, albedo, alpha, screen_uv,
 #ifdef LIGHT_BACKLIGHT_USED
 #ifdef LIGHT_BACKLIGHT_USED
 				backlight,
 				backlight,

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

@@ -2211,6 +2211,10 @@ void fragment_shader(in SceneData scene_data) {
 				continue; //not masked
 				continue; //not masked
 			}
 			}
 
 
+			if (directional_lights.data[i].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+				continue; // Statically baked light and object uses lightmap, skip
+			}
+
 #ifdef LIGHT_TRANSMITTANCE_USED
 #ifdef LIGHT_TRANSMITTANCE_USED
 			float transmittance_z = transmittance_depth;
 			float transmittance_z = transmittance_depth;
 #ifndef SHADOWS_DISABLED
 #ifndef SHADOWS_DISABLED

+ 8 - 0
servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl

@@ -1445,6 +1445,10 @@ void main() {
 				continue; //not masked
 				continue; //not masked
 			}
 			}
 
 
+			if (directional_lights.data[i].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+				continue; // Statically baked light and object uses lightmap, skip.
+			}
+
 			float shadow = 1.0;
 			float shadow = 1.0;
 
 
 			if (directional_lights.data[i].shadow_opacity > 0.001) {
 			if (directional_lights.data[i].shadow_opacity > 0.001) {
@@ -1560,6 +1564,10 @@ void main() {
 				continue; //not masked
 				continue; //not masked
 			}
 			}
 
 
+			if (directional_lights.data[i].bake_mode == LIGHT_BAKE_STATIC && bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) {
+				continue; // Statically baked light and object uses lightmap, skip.
+			}
+
 			// We're not doing light transmittence
 			// We're not doing light transmittence
 
 
 			float shadow = 1.0;
 			float shadow = 1.0;

+ 2 - 1
servers/rendering/renderer_rd/storage_rd/light_storage.cpp

@@ -676,12 +676,13 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
 					angular_diameter = 0.0;
 					angular_diameter = 0.0;
 				}
 				}
 
 
+				light_data.bake_mode = light->bake_mode;
+
 				if (light_data.shadow_opacity > 0.001) {
 				if (light_data.shadow_opacity > 0.001) {
 					RS::LightDirectionalShadowMode smode = light->directional_shadow_mode;
 					RS::LightDirectionalShadowMode smode = light->directional_shadow_mode;
 
 
 					light_data.soft_shadow_scale = light->param[RS::LIGHT_PARAM_SHADOW_BLUR];
 					light_data.soft_shadow_scale = light->param[RS::LIGHT_PARAM_SHADOW_BLUR];
 					light_data.softshadow_angle = angular_diameter;
 					light_data.softshadow_angle = angular_diameter;
-					light_data.bake_mode = light->bake_mode;
 
 
 					if (angular_diameter <= 0.0) {
 					if (angular_diameter <= 0.0) {
 						light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->directional_shadow_quality_radius_get(); // Only use quality radius for PCF
 						light_data.soft_shadow_scale *= RendererSceneRenderRD::get_singleton()->directional_shadow_quality_radius_get(); // Only use quality radius for PCF

+ 4 - 0
servers/rendering/renderer_scene_cull.cpp

@@ -3044,6 +3044,10 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
 								continue;
 								continue;
 							}
 							}
 
 
+							if ((RSG::light_storage->light_get_bake_mode(E->base) == RS::LIGHT_BAKE_STATIC) && idata.instance->lightmap) {
+								continue;
+							}
+
 							instance_pair_buffer[idx++] = light->instance;
 							instance_pair_buffer[idx++] = light->instance;
 							if (idx == MAX_INSTANCE_PAIRS) {
 							if (idx == MAX_INSTANCE_PAIRS) {
 								break;
 								break;