diff --git a/doc/classes/LightmapGI.xml b/doc/classes/LightmapGI.xml
index ec75d85898f..fa3bfe513f8 100644
--- a/doc/classes/LightmapGI.xml
+++ b/doc/classes/LightmapGI.xml
@@ -65,6 +65,9 @@
The quality preset to use when baking lightmaps. This affects bake times, but output file sizes remain mostly identical across quality levels.
To further speed up bake times, decrease [member bounces], disable [member use_denoiser] and increase the lightmap texel size on 3D scenes in the Import doc.
+
+ Scales the lightmap texel density of all meshes for the current bake. This is a multiplier that builds upon the existing lightmap texel size defined in each imported 3D scene, along with the per-mesh density multiplier (which is designed to be used when the same mesh is used at different scales). Lower values will result in faster bake times.
+
If [code]true[/code], uses a GPU-based denoising algorithm on the generated lightmap. This eliminates most noise within the generated lightmap at the cost of longer bake times. File sizes are generally not impacted significantly by the use of a denoiser, although lossless compression may do a better job at compressing a denoised image.
diff --git a/editor/plugins/lightmap_gi_editor_plugin.cpp b/editor/plugins/lightmap_gi_editor_plugin.cpp
index 11f60a166c9..3b1b1e47cb3 100644
--- a/editor/plugins/lightmap_gi_editor_plugin.cpp
+++ b/editor/plugins/lightmap_gi_editor_plugin.cpp
@@ -107,6 +107,9 @@ void LightmapGIEditorPlugin::_bake_select_file(const String &p_file) {
case LightmapGI::BAKE_ERROR_TEXTURE_SIZE_TOO_SMALL: {
EditorNode::get_singleton()->show_warning(TTR("Maximum texture size is too small for the lightmap images."));
} break;
+ case LightmapGI::BAKE_ERROR_LIGHTMAP_TOO_SMALL: {
+ EditorNode::get_singleton()->show_warning(TTR("Failed creating lightmap images. Make sure all meshes selected to bake have `lightmap_size_hint` value set high enough, and `texel_scale` value of LightmapGI is not too low."));
+ } break;
default: {
} break;
}
diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp
index 76933cd9561..92b783392da 100644
--- a/scene/3d/lightmap_gi.cpp
+++ b/scene/3d/lightmap_gi.cpp
@@ -734,15 +734,15 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa
MeshesFound &mf = meshes_found.write[m_i];
- Size2i lightmap_size = mf.mesh->get_lightmap_size_hint();
-
- if (lightmap_size == Size2i(0, 0)) {
+ Size2i mesh_lightmap_size = mf.mesh->get_lightmap_size_hint();
+ if (mesh_lightmap_size == Size2i(0, 0)) {
// TODO we should compute a size if no lightmap hint is set, as we did in 3.x.
// For now set to basic size to avoid crash.
- lightmap_size = Size2i(64, 64);
+ mesh_lightmap_size = Size2i(64, 64);
}
+ Size2i lightmap_size = Size2i(Size2(mesh_lightmap_size) * mf.lightmap_scale * texel_scale);
+ ERR_FAIL_COND_V(lightmap_size.x == 0 || lightmap_size.y == 0, BAKE_ERROR_LIGHTMAP_TOO_SMALL);
- lightmap_size *= mf.lightmap_scale;
TypedArray overrides;
overrides.resize(mf.overrides.size());
for (int i = 0; i < mf.overrides.size(); i++) {
@@ -1493,6 +1493,15 @@ float LightmapGI::get_bias() const {
return bias;
}
+void LightmapGI::set_texel_scale(float p_multiplier) {
+ ERR_FAIL_COND(p_multiplier < (0.01 - CMP_EPSILON));
+ texel_scale = p_multiplier;
+}
+
+float LightmapGI::get_texel_scale() const {
+ return texel_scale;
+}
+
void LightmapGI::set_max_texture_size(int p_size) {
ERR_FAIL_COND_MSG(p_size < 2048, vformat("The LightmapGI maximum texture size supplied (%d) is too small. The minimum allowed value is 2048.", p_size));
ERR_FAIL_COND_MSG(p_size > 16384, vformat("The LightmapGI maximum texture size supplied (%d) is too large. The maximum allowed value is 16384.", p_size));
@@ -1576,6 +1585,9 @@ void LightmapGI::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_environment_custom_energy", "energy"), &LightmapGI::set_environment_custom_energy);
ClassDB::bind_method(D_METHOD("get_environment_custom_energy"), &LightmapGI::get_environment_custom_energy);
+ ClassDB::bind_method(D_METHOD("set_texel_scale", "texel_scale"), &LightmapGI::set_texel_scale);
+ ClassDB::bind_method(D_METHOD("get_texel_scale"), &LightmapGI::get_texel_scale);
+
ClassDB::bind_method(D_METHOD("set_max_texture_size", "max_texture_size"), &LightmapGI::set_max_texture_size);
ClassDB::bind_method(D_METHOD("get_max_texture_size"), &LightmapGI::get_max_texture_size);
@@ -1609,6 +1621,7 @@ void LightmapGI::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_denoiser"), "set_use_denoiser", "is_using_denoiser");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "denoiser_strength", PROPERTY_HINT_RANGE, "0.001,0.2,0.001,or_greater"), "set_denoiser_strength", "get_denoiser_strength");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0.00001,0.1,0.00001,or_greater"), "set_bias", "get_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "texel_scale", PROPERTY_HINT_RANGE, "0.01,100.0,0.01"), "set_texel_scale", "get_texel_scale");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_texture_size", PROPERTY_HINT_RANGE, "2048,16384,1"), "set_max_texture_size", "get_max_texture_size");
ADD_GROUP("Environment", "environment_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "environment_mode", PROPERTY_HINT_ENUM, "Disabled,Scene,Custom Sky,Custom Color"), "set_environment_mode", "get_environment_mode");
diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h
index fec00756930..765e4a731dd 100644
--- a/scene/3d/lightmap_gi.h
+++ b/scene/3d/lightmap_gi.h
@@ -142,6 +142,7 @@ public:
BAKE_ERROR_CANT_CREATE_IMAGE,
BAKE_ERROR_USER_ABORTED,
BAKE_ERROR_TEXTURE_SIZE_TOO_SMALL,
+ BAKE_ERROR_LIGHTMAP_TOO_SMALL,
};
enum EnvironmentMode {
@@ -158,6 +159,7 @@ private:
int bounces = 3;
float bounce_indirect_energy = 1.0;
float bias = 0.0005;
+ float texel_scale = 1.0;
int max_texture_size = 16384;
bool interior = false;
EnvironmentMode environment_mode = ENVIRONMENT_MODE_SCENE;
@@ -284,6 +286,9 @@ public:
void set_bias(float p_bias);
float get_bias() const;
+ void set_texel_scale(float p_multiplier);
+ float get_texel_scale() const;
+
void set_max_texture_size(int p_size);
int get_max_texture_size() const;