From 1b0c21fc87b119ac9ff212330bff0e0ce9e97ee4 Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Tue, 21 Jan 2025 17:34:42 +0100 Subject: [PATCH] Save LightmapGI shadowmask to a lossless WebP image to reduce file size This doesn't affect the size of the exported project (which uses a VRAM-compressed copy by default), but it reduces the size of the files that are committed to version control or included within MRP ZIPs. When you iterate on lightmaps frequently and commit new versions of them, this can add up to saving dozens if not hundreds of megabytes over time. This change is fully backwards-compatible and forwards-compatible with existing projects that use PNG shadowmask textures, as the shadowmask path is saved in LightmapGIData. --- scene/3d/lightmap_gi.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/scene/3d/lightmap_gi.cpp b/scene/3d/lightmap_gi.cpp index 37380fd2b46..ad8b925979f 100644 --- a/scene/3d/lightmap_gi.cpp +++ b/scene/3d/lightmap_gi.cpp @@ -834,7 +834,7 @@ LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref
  • blit_rect(images[i * slices_per_texture + j], Rect2i(0, 0, slice_width, slice_height), Point2i(0, slice_height * j)); } - const String atlas_path = (texture_count > 1 ? p_base_name + "_" + itos(i) : p_base_name) + (p_is_shadowmask ? ".png" : ".exr"); + const String atlas_path = (texture_count > 1 ? p_base_name + "_" + itos(i) : p_base_name) + (p_is_shadowmask ? ".webp" : ".exr"); const String config_path = atlas_path + ".import"; Ref config; @@ -865,7 +865,19 @@ LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref
  • save_png(atlas_path); + // Downsize the image if needed to fit within the WebP format limitations. + // In practice, the maximum usable texture size is typically 16384×16384, + // so this only changes the size by 1 pixel which is unnoticeable. + constexpr int WEBP_SIZE_LIMIT = 16383; + if (texture_image->get_width() > WEBP_SIZE_LIMIT) { + texture_image->resize(WEBP_SIZE_LIMIT, texture_image->get_height() * WEBP_SIZE_LIMIT / texture_image->get_width()); + } else if (texture_image->get_height() > WEBP_SIZE_LIMIT) { + texture_image->resize(texture_image->get_width() * WEBP_SIZE_LIMIT / texture_image->get_height(), WEBP_SIZE_LIMIT); + } + // Save as lossless WebP instead of PNG to reduce file size in the project files. + // The exported project size will remain identical, but this reduces the size of the file + // that is committed to version control. + save_err = texture_image->save_webp(atlas_path); } else { save_err = texture_image->save_exr(atlas_path, false); }