diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml
index b8d46755c71c..1a690298545a 100644
--- a/doc/classes/Light3D.xml
+++ b/doc/classes/Light3D.xml
@@ -48,7 +48,7 @@
The light's strength multiplier (this is not a physical unit). For [OmniLight3D] and [SpotLight3D], changing this value will only change the light color's intensity, not the light's radius.
- Secondary multiplier used with indirect light (light bounces). Used with [VoxelGI] and SDFGI (see [member Environment.sdfgi_enabled]).
+ Secondary multiplier used with indirect light (light bounces). Used with [VoxelGI], [LightmapGI] and SDFGI (see [member Environment.sdfgi_enabled]). For [VoxelGI], only effective if [member light_bake_mode] is [constant BAKE_DYNAMIC] or [constant BAKE_STATIC]. For [LightmapGI], only effective if [member light_bake_mode] is [constant BAKE_DYNAMIC].
[b]Note:[/b] This property is ignored if [member light_energy] is equal to [code]0.0[/code], as the light won't be present at all in the GI shader.
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
index 11715040c286..798e9b13f408 100644
--- a/modules/lightmapper_rd/lightmapper_rd.cpp
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -50,7 +50,7 @@ void LightmapperRD::add_mesh(const MeshData &p_mesh) {
mesh_instances.push_back(mi);
}
-void LightmapperRD::add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) {
+void LightmapperRD::add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_angular_distance) {
Light l;
l.type = LIGHT_TYPE_DIRECTIONAL;
l.direction[0] = p_direction.x;
@@ -60,12 +60,13 @@ void LightmapperRD::add_directional_light(bool p_static, const Vector3 &p_direct
l.color[1] = p_color.g;
l.color[2] = p_color.b;
l.energy = p_energy;
+ l.indirect_multiplier = p_indirect_multiplier;
l.static_bake = p_static;
l.size = p_angular_distance;
lights.push_back(l);
}
-void LightmapperRD::add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size) {
+void LightmapperRD::add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_size) {
Light l;
l.type = LIGHT_TYPE_OMNI;
l.position[0] = p_position.x;
@@ -77,12 +78,13 @@ void LightmapperRD::add_omni_light(bool p_static, const Vector3 &p_position, con
l.color[1] = p_color.g;
l.color[2] = p_color.b;
l.energy = p_energy;
+ l.indirect_multiplier = p_indirect_multiplier;
l.static_bake = p_static;
l.size = p_size;
lights.push_back(l);
}
-void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) {
+void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) {
Light l;
l.type = LIGHT_TYPE_SPOT;
l.position[0] = p_position.x;
@@ -99,6 +101,7 @@ void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, con
l.color[1] = p_color.g;
l.color[2] = p_color.b;
l.energy = p_energy;
+ l.indirect_multiplier = p_indirect_multiplier;
l.static_bake = p_static;
l.size = p_size;
lights.push_back(l);
diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h
index 503f5f7009a6..dbce476d304f 100644
--- a/modules/lightmapper_rd/lightmapper_rd.h
+++ b/modules/lightmapper_rd/lightmapper_rd.h
@@ -49,16 +49,21 @@ class LightmapperRD : public Lightmapper {
struct Light {
float position[3] = {};
uint32_t type = LIGHT_TYPE_DIRECTIONAL;
+
float direction[3] = {};
float energy = 0.0;
+
float color[3] = {};
float size = 0.0;
+
float range = 0.0;
float attenuation = 0.0;
float cos_spot_angle = 0.0;
float inv_spot_attenuation = 0.0;
+
uint32_t static_bake = 0;
- uint32_t pad[3] = {};
+ float indirect_multiplier = 1.0;
+ uint32_t pad[2] = {};
bool operator<(const Light &p_light) const {
return type < p_light.type;
@@ -236,9 +241,9 @@ class LightmapperRD : public Lightmapper {
public:
virtual void add_mesh(const MeshData &p_mesh) override;
- virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) override;
- virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size) override;
- virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) override;
+ virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_angular_distance) override;
+ virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_size) override;
+ virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) override;
virtual void add_probe(const Vector3 &p_position) override;
virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_bake_userdata = nullptr) override;
diff --git a/modules/lightmapper_rd/lm_common_inc.glsl b/modules/lightmapper_rd/lm_common_inc.glsl
index 58523dc1f87f..41699e1e0c41 100644
--- a/modules/lightmapper_rd/lm_common_inc.glsl
+++ b/modules/lightmapper_rd/lm_common_inc.glsl
@@ -52,7 +52,8 @@ struct Light {
float inv_spot_attenuation;
bool static_bake;
- uint pad[3];
+ float indirect_multiplier;
+ uint pad[2];
};
layout(set = 0, binding = 4, std430) restrict readonly buffer Lights {
diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl
index 7bb8346c47e2..a10dc6fea521 100644
--- a/modules/lightmapper_rd/lm_compute.glsl
+++ b/modules/lightmapper_rd/lm_compute.glsl
@@ -371,7 +371,7 @@ void main() {
#endif
} else {
- dynamic_light += light;
+ dynamic_light += light * lights.data[i].indirect_multiplier;
}
}
}
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index 825742da35bd..9374e9c6e76e 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -887,13 +887,13 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
Color linear_color = light->get_color().to_linear();
if (Object::cast_to(light)) {
DirectionalLight3D *l = Object::cast_to(light);
- lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_STATIC, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_SIZE));
+ lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_STATIC, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_INDIRECT_ENERGY), l->get_param(Light3D::PARAM_SIZE));
} else if (Object::cast_to(light)) {
OmniLight3D *l = Object::cast_to(light);
- lightmapper->add_omni_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
+ lightmapper->add_omni_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_INDIRECT_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
} else if (Object::cast_to(light)) {
SpotLight3D *l = Object::cast_to(light);
- lightmapper->add_spot_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SPOT_ANGLE), l->get_param(Light3D::PARAM_SPOT_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
+ lightmapper->add_spot_light(light->get_bake_mode() == Light3D::BAKE_STATIC, xf.origin, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), linear_color, l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_INDIRECT_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SPOT_ANGLE), l->get_param(Light3D::PARAM_SPOT_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
}
}
for (int i = 0; i < probes_found.size(); i++) {
diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h
index f641c99ec1bc..ee079c841873 100644
--- a/scene/3d/lightmapper.h
+++ b/scene/3d/lightmapper.h
@@ -174,9 +174,9 @@ class Lightmapper : public RefCounted {
};
virtual void add_mesh(const MeshData &p_mesh) = 0;
- virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) = 0;
- virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size) = 0;
- virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) = 0;
+ virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_angular_distance) = 0;
+ virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_size) = 0;
+ virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_indirect_multiplier, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) = 0;
virtual void add_probe(const Vector3 &p_position) = 0;
virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr) = 0;