diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp index 17b64a626bc..82837484877 100644 --- a/modules/lightmapper_rd/lightmapper_rd.cpp +++ b/modules/lightmapper_rd/lightmapper_rd.cpp @@ -79,7 +79,11 @@ void LightmapperRD::add_directional_light(const String &p_name, bool p_static, c l.size = Math::tan(Math::deg_to_rad(p_angular_distance)); l.shadow_blur = p_shadow_blur; lights.push_back(l); - light_names.push_back(p_name); + + LightMetadata md; + md.name = p_name; + md.type = LIGHT_TYPE_DIRECTIONAL; + light_metadata.push_back(md); } void LightmapperRD::add_omni_light(const String &p_name, bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_energy, float p_range, float p_attenuation, float p_size, float p_shadow_blur) { @@ -99,7 +103,11 @@ void LightmapperRD::add_omni_light(const String &p_name, bool p_static, const Ve l.size = p_size; l.shadow_blur = p_shadow_blur; lights.push_back(l); - light_names.push_back(p_name); + + LightMetadata md; + md.name = p_name; + md.type = LIGHT_TYPE_OMNI; + light_metadata.push_back(md); } void LightmapperRD::add_spot_light(const String &p_name, bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size, float p_shadow_blur) { @@ -124,7 +132,11 @@ void LightmapperRD::add_spot_light(const String &p_name, bool p_static, const Ve l.size = p_size; l.shadow_blur = p_shadow_blur; lights.push_back(l); - light_names.push_back(p_name); + + LightMetadata md; + md.name = p_name; + md.type = LIGHT_TYPE_SPOT; + light_metadata.push_back(md); } void LightmapperRD::add_probe(const Vector3 &p_position) { @@ -620,6 +632,7 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i /*****************************/ lights.sort(); + light_metadata.sort(); Vector seam_buffer_vec; seam_buffer_vec.resize(seams.size() * 2); @@ -1083,32 +1096,19 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d return bake_error; } - // The index of the directional light used for shadowmasking. - int shadowmask_light_idx = -1; - - // If there are no valid directional lights for shadowmasking, the entire - // scene would be shadowed and this saves baking time. + // Find any directional light suitable for shadowmasking. if (p_bake_shadowmask) { - int shadowmask_lights_count = 0; - + bool found = false; for (int i = 0; i < lights.size(); i++) { if (lights[i].type == LightType::LIGHT_TYPE_DIRECTIONAL && !lights[i].static_bake) { - if (shadowmask_light_idx < 0) { - shadowmask_light_idx = i; - } - - shadowmask_lights_count += 1; + found = true; + break; } } - if (shadowmask_light_idx < 0) { + if (!found) { p_bake_shadowmask = false; WARN_PRINT("Shadowmask disabled: no directional light with their bake mode set to dynamic exists."); - - } else if (shadowmask_lights_count > 1) { - WARN_PRINT( - vformat("%d directional lights detected for shadowmask baking. Only %s will be used.", - shadowmask_lights_count, light_names[shadowmask_light_idx])); } } @@ -1300,6 +1300,29 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d const uint32_t cluster_size = 16; _create_acceleration_structures(rd, atlas_size, atlas_slices, bounds, grid_size, cluster_size, probe_positions, p_generate_probes, slice_triangle_count, slice_seam_count, vertex_buffer, triangle_buffer, lights_buffer, triangle_indices_buffer, cluster_indices_buffer, cluster_aabbs_buffer, probe_positions_buffer, grid_texture, seams_buffer, p_step_function, p_bake_userdata); + // The index of the directional light used for shadowmasking. + int shadowmask_light_idx = -1; + + // Find the directional light index in the sorted lights array. + if (p_bake_shadowmask) { + int shadowmask_lights_count = 0; + + for (int i = 0; i < lights.size(); i++) { + if (lights[i].type == LightType::LIGHT_TYPE_DIRECTIONAL && !lights[i].static_bake) { + if (shadowmask_light_idx < 0) { + shadowmask_light_idx = i; + } + shadowmask_lights_count += 1; + } + } + + if (shadowmask_lights_count > 1) { + WARN_PRINT( + vformat("%d directional lights detected for shadowmask baking. Only %s will be used.", + shadowmask_lights_count, light_metadata[shadowmask_light_idx].name)); + } + } + // Create global bake parameters buffer. BakeParameters bake_parameters; bake_parameters.world_size[0] = bounds.size.x; diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h index a6fa3c24afa..b962303a2b9 100644 --- a/modules/lightmapper_rd/lightmapper_rd.h +++ b/modules/lightmapper_rd/lightmapper_rd.h @@ -88,6 +88,15 @@ class LightmapperRD : public Lightmapper { } }; + struct LightMetadata { + String name; + uint32_t type = LIGHT_TYPE_DIRECTIONAL; + + bool operator<(const LightMetadata &p_light) const { + return type < p_light.type; + } + }; + struct Vertex { float position[3] = {}; float normal_z = 0.0; @@ -203,7 +212,7 @@ class LightmapperRD : public Lightmapper { Vector mesh_instances; Vector lights; - Vector light_names; + Vector light_metadata; struct TriangleSort { uint32_t cell_index = 0;