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;