From 1e5f0a86ca668a621dfaad1a8289ee53b68528d2 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 21 Mar 2023 02:22:22 +0100 Subject: [PATCH] Allow more flexible adjustments of VisualInstance3D Lightmap Scale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Any floating-point value greater than 0.01 can now be used. Prior to this change, only factors of 1×, 2× and 4× and 8× could be used. --- doc/classes/GeometryInstance3D.xml | 16 ++++++---- doc/classes/LightmapGI.xml | 1 + scene/3d/lightmap_gi.cpp | 6 ++-- scene/3d/lightmap_gi.h | 2 +- scene/3d/visual_instance_3d.cpp | 48 ++++++++++++++++++++++++++++-- scene/3d/visual_instance_3d.h | 11 +++++-- 6 files changed, 67 insertions(+), 17 deletions(-) diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml index f4075af18697..0c45154c8af0 100644 --- a/doc/classes/GeometryInstance3D.xml +++ b/doc/classes/GeometryInstance3D.xml @@ -39,8 +39,12 @@ The extra distance added to the GeometryInstance3D's bounding box ([AABB]) to increase its cull box. - + + The texel density to use for lightmapping in [LightmapGI]. + + The texel density to use for lightmapping in [LightmapGI]. Greater scale values provide higher resolution in the lightmap, which can result in sharper shadows for lights that have both direct and indirect light baked. However, greater scale values will also increase the space taken by the mesh in the lightmap texture, which increases the memory, storage, and bake time requirements. When using a single mesh at different scales, consider adjusting this value to keep the lightmap texel density consistent across meshes. + For example, doubling [member gi_lightmap_texel_scale] doubles the lightmap texture resolution for this object [i]on each axis[/i], so it will [i]quadruple[/i] the texel count. The global illumination mode to use for the whole geometry. To avoid inconsistent results, use a mode that matches the purpose of the mesh during gameplay (static/dynamic). @@ -111,19 +115,19 @@ Dynamic global illumination mode. Use for dynamic objects that contribute to global illumination. This GI mode is only effective when using [VoxelGI], but it has a higher performance impact than [constant GI_MODE_STATIC]. When using other GI methods, this will act the same as [constant GI_MODE_DISABLED]. When using [LightmapGI], the object will receive indirect lighting using lightmap probes instead of using the baked lightmap texture. - + The standard texel density for lightmapping with [LightmapGI]. - + Multiplies texel density by 2× for lightmapping with [LightmapGI]. To ensure consistency in texel density, use this when scaling a mesh by a factor between 1.5 and 3.0. - + Multiplies texel density by 4× for lightmapping with [LightmapGI]. To ensure consistency in texel density, use this when scaling a mesh by a factor between 3.0 and 6.0. - + Multiplies texel density by 8× for lightmapping with [LightmapGI]. To ensure consistency in texel density, use this when scaling a mesh by a factor greater than 6.0. - + Represents the size of the [enum LightmapScale] enum. diff --git a/doc/classes/LightmapGI.xml b/doc/classes/LightmapGI.xml index 139bf6e4d161..0a492364eca0 100644 --- a/doc/classes/LightmapGI.xml +++ b/doc/classes/LightmapGI.xml @@ -70,6 +70,7 @@ 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. + For example, doubling [member texel_scale] doubles the lightmap texture resolution for all objects [i]on each axis[/i], so it will [i]quadruple[/i] the texel count. 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/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index c658bfd799de..cdbd95d9302b 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -333,9 +333,7 @@ void LightmapGI::_find_meshes_and_lights(Node *p_at_node, Vector &m mf.node_path = get_path_to(mi); mf.subindex = -1; mf.mesh = mesh; - - static const int lightmap_scale[GeometryInstance3D::LIGHTMAP_SCALE_MAX] = { 1, 2, 4, 8 }; - mf.lightmap_scale = lightmap_scale[mi->get_lightmap_scale()]; + mf.lightmap_scale = mi->get_lightmap_texel_scale(); Ref all_override = mi->get_material_override(); for (int i = 0; i < mesh->get_surface_count(); i++) { @@ -369,7 +367,7 @@ void LightmapGI::_find_meshes_and_lights(Node *p_at_node, Vector &m mf.xform = xf * mesh_xf; mf.node_path = get_path_to(s); mf.subindex = i / 2; - mf.lightmap_scale = 1; + mf.lightmap_scale = 1.0; mf.mesh = mesh; meshes.push_back(mf); diff --git a/scene/3d/lightmap_gi.h b/scene/3d/lightmap_gi.h index 0476061c6077..faa8b84fa177 100644 --- a/scene/3d/lightmap_gi.h +++ b/scene/3d/lightmap_gi.h @@ -194,7 +194,7 @@ class LightmapGI : public VisualInstance3D { NodePath node_path; int32_t subindex = 0; Ref mesh; - int32_t lightmap_scale = 0; + float lightmap_scale = 0.0; Vector> overrides; }; diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp index a59754c8cc4e..2c7a004dd068 100644 --- a/scene/3d/visual_instance_3d.cpp +++ b/scene/3d/visual_instance_3d.cpp @@ -454,14 +454,48 @@ AABB GeometryInstance3D::get_custom_aabb() const { return custom_aabb; } +void GeometryInstance3D::set_lightmap_texel_scale(float p_scale) { + lightmap_texel_scale = p_scale; +} + +float GeometryInstance3D::get_lightmap_texel_scale() const { + return lightmap_texel_scale; +} + +#ifndef DISABLE_DEPRECATED void GeometryInstance3D::set_lightmap_scale(LightmapScale p_scale) { ERR_FAIL_INDEX(p_scale, LIGHTMAP_SCALE_MAX); - lightmap_scale = p_scale; + switch (p_scale) { + case GeometryInstance3D::LIGHTMAP_SCALE_1X: + lightmap_texel_scale = 1.0f; + break; + case GeometryInstance3D::LIGHTMAP_SCALE_2X: + lightmap_texel_scale = 2.0f; + break; + case GeometryInstance3D::LIGHTMAP_SCALE_4X: + lightmap_texel_scale = 4.0f; + break; + case GeometryInstance3D::LIGHTMAP_SCALE_8X: + lightmap_texel_scale = 8.0f; + break; + case GeometryInstance3D::LIGHTMAP_SCALE_MAX: + break; // Can't happen, but silences warning. + } } GeometryInstance3D::LightmapScale GeometryInstance3D::get_lightmap_scale() const { - return lightmap_scale; + // Return closest approximation. + if (lightmap_texel_scale < 1.5f) { + return GeometryInstance3D::LIGHTMAP_SCALE_1X; + } else if (lightmap_texel_scale < 3.0f) { + return GeometryInstance3D::LIGHTMAP_SCALE_2X; + } else if (lightmap_texel_scale < 6.0f) { + return GeometryInstance3D::LIGHTMAP_SCALE_4X; + } + + return GeometryInstance3D::LIGHTMAP_SCALE_8X; } +#endif // DISABLE_DEPRECATED void GeometryInstance3D::set_gi_mode(GIMode p_mode) { switch (p_mode) { @@ -565,8 +599,13 @@ void GeometryInstance3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_extra_cull_margin", "margin"), &GeometryInstance3D::set_extra_cull_margin); ClassDB::bind_method(D_METHOD("get_extra_cull_margin"), &GeometryInstance3D::get_extra_cull_margin); + ClassDB::bind_method(D_METHOD("set_lightmap_texel_scale", "scale"), &GeometryInstance3D::set_lightmap_texel_scale); + ClassDB::bind_method(D_METHOD("get_lightmap_texel_scale"), &GeometryInstance3D::get_lightmap_texel_scale); + +#ifndef DISABLE_DEPRECATED ClassDB::bind_method(D_METHOD("set_lightmap_scale", "scale"), &GeometryInstance3D::set_lightmap_scale); ClassDB::bind_method(D_METHOD("get_lightmap_scale"), &GeometryInstance3D::get_lightmap_scale); +#endif // DISABLE_DEPRECATED ClassDB::bind_method(D_METHOD("set_gi_mode", "mode"), &GeometryInstance3D::set_gi_mode); ClassDB::bind_method(D_METHOD("get_gi_mode"), &GeometryInstance3D::get_gi_mode); @@ -591,7 +630,10 @@ void GeometryInstance3D::_bind_methods() { ADD_GROUP("Global Illumination", "gi_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Static,Dynamic"), "set_gi_mode", "get_gi_mode"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, String::utf8("1×,2×,4×,8×")), "set_lightmap_scale", "get_lightmap_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gi_lightmap_texel_scale", PROPERTY_HINT_RANGE, "0.01,10,0.0001,or_greater"), "set_lightmap_texel_scale", "get_lightmap_texel_scale"); +#ifndef DISABLE_DEPRECATED + ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, String::utf8("1×,2×,4×,8×"), PROPERTY_USAGE_NONE), "set_lightmap_scale", "get_lightmap_scale"); +#endif // DISABLE_DEPRECATED ADD_GROUP("Visibility Range", "visibility_range_"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "visibility_range_begin", PROPERTY_HINT_RANGE, "0.0,4096.0,0.01,or_greater,suffix:m"), "set_visibility_range_begin", "get_visibility_range_begin"); diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h index 9b02c928b7ac..073fa74573d6 100644 --- a/scene/3d/visual_instance_3d.h +++ b/scene/3d/visual_instance_3d.h @@ -134,7 +134,7 @@ class GeometryInstance3D : public VisualInstance3D { float extra_cull_margin = 0.0; AABB custom_aabb; - LightmapScale lightmap_scale = LIGHTMAP_SCALE_1X; + float lightmap_texel_scale = 1.0f; GIMode gi_mode = GI_MODE_STATIC; bool ignore_occlusion_culling = false; @@ -185,8 +185,13 @@ class GeometryInstance3D : public VisualInstance3D { void set_gi_mode(GIMode p_mode); GIMode get_gi_mode() const; - void set_lightmap_scale(LightmapScale p_scale); + void set_lightmap_texel_scale(float p_scale); + float get_lightmap_texel_scale() const; + +#ifndef DISABLE_DEPRECATED + void set_lightmap_scale(GeometryInstance3D::LightmapScale p_scale); LightmapScale get_lightmap_scale() const; +#endif // DISABLE_DEPRECATED void set_instance_shader_parameter(const StringName &p_name, const Variant &p_value); Variant get_instance_shader_parameter(const StringName &p_name) const; @@ -203,8 +208,8 @@ class GeometryInstance3D : public VisualInstance3D { }; VARIANT_ENUM_CAST(GeometryInstance3D::ShadowCastingSetting); -VARIANT_ENUM_CAST(GeometryInstance3D::LightmapScale); VARIANT_ENUM_CAST(GeometryInstance3D::GIMode); +VARIANT_ENUM_CAST(GeometryInstance3D::LightmapScale); VARIANT_ENUM_CAST(GeometryInstance3D::VisibilityRangeFadeMode); #endif // VISUAL_INSTANCE_3D_H