|
38 | 38 |
|
39 | 39 | #include "lightmap_gi.h" |
40 | 40 |
|
| 41 | +#include "core/config/engine.h" |
41 | 42 | #include "core/config/project_settings.h" |
42 | 43 | #include "core/io/config_file.h" |
43 | 44 | #include "core/math/delaunay_3d.h" |
|
48 | 49 | #include "scene/resources/environment.h" |
49 | 50 | #include "scene/resources/image_texture.h" |
50 | 51 | #include "scene/resources/sky.h" |
| 52 | +#include "scene/resources/texture.h" |
51 | 53 |
|
52 | 54 | #include "modules/modules_enabled.gen.h" // For lightmapper_rd. |
53 | 55 |
|
@@ -840,57 +842,88 @@ LightmapGI::BakeError LightmapGI::_save_and_reimport_atlas_textures(const Ref<Li |
840 | 842 | texture_image->blit_rect(images[i * slices_per_texture + j], Rect2i(0, 0, slice_width, slice_height), Point2i(0, slice_height * j)); |
841 | 843 | } |
842 | 844 |
|
843 | | - const String atlas_path = (texture_count > 1 ? p_base_name + "_" + itos(i) : p_base_name) + (p_is_shadowmask ? ".png" : ".exr"); |
844 | | - const String config_path = atlas_path + ".import"; |
| 845 | + if (Engine::get_singleton()->is_editor_hint()) { |
| 846 | + const String atlas_path = (texture_count > 1 ? p_base_name + "_" + itos(i) : p_base_name) + (p_is_shadowmask ? ".png" : ".exr"); |
| 847 | + const String config_path = atlas_path + ".import"; |
845 | 848 |
|
846 | | - Ref<ConfigFile> config; |
847 | | - config.instantiate(); |
848 | | - |
849 | | - // Load an import configuration if present. |
850 | | - if (FileAccess::exists(config_path)) { |
851 | | - config->load(config_path); |
852 | | - } |
| 849 | + Ref<ConfigFile> config; |
| 850 | + config.instantiate(); |
| 851 | + // Load an import configuration if present. |
| 852 | + if (FileAccess::exists(config_path)) { |
| 853 | + config->load(config_path); |
| 854 | + } |
853 | 855 |
|
854 | | - config->set_value("remap", "importer", "2d_array_texture"); |
855 | | - config->set_value("remap", "type", "CompressedTexture2DArray"); |
856 | | - if (!config->has_section_key("params", "compress/mode")) { |
857 | | - // Do not override an existing compression mode. |
858 | | - config->set_value("params", "compress/mode", 2); |
859 | | - } |
860 | | - config->set_value("params", "compress/channel_pack", 1); |
861 | | - config->set_value("params", "mipmaps/generate", false); |
862 | | - config->set_value("params", "slices/horizontal", 1); |
863 | | - config->set_value("params", "slices/vertical", texture_slice_count); |
| 856 | + config->set_value("remap", "importer", "2d_array_texture"); |
| 857 | + config->set_value("remap", "type", "CompressedTexture2DArray"); |
| 858 | + if (!config->has_section_key("params", "compress/mode")) { |
| 859 | + // Do not override an existing compression mode. |
| 860 | + config->set_value("params", "compress/mode", 3); |
| 861 | + } |
| 862 | + config->set_value("params", "compress/channel_pack", 1); |
| 863 | + config->set_value("params", "mipmaps/generate", false); |
| 864 | + config->set_value("params", "slices/horizontal", 1); |
| 865 | + config->set_value("params", "slices/vertical", texture_slice_count); |
864 | 866 |
|
865 | | - config->save(config_path); |
| 867 | + config->save(config_path); |
866 | 868 |
|
867 | | - if (supersampling_enabled) { |
868 | | - texture_image->resize(texture_image->get_width() / supersampling_factor, texture_image->get_height() / supersampling_factor, Image::INTERPOLATE_TRILINEAR); |
869 | | - } |
| 869 | + if (supersampling_enabled) { |
| 870 | + texture_image->resize(texture_image->get_width() / supersampling_factor, texture_image->get_height() / supersampling_factor, Image::INTERPOLATE_TRILINEAR); |
| 871 | + } |
870 | 872 |
|
871 | | - // Save the file. |
872 | | - Error save_err; |
873 | | - if (p_is_shadowmask) { |
874 | | - save_err = texture_image->save_png(atlas_path); |
875 | | - } else { |
876 | | - save_err = texture_image->save_exr(atlas_path, false); |
877 | | - } |
| 873 | + // Save the file. |
| 874 | + Error save_err; |
| 875 | + if (p_is_shadowmask) { |
| 876 | + save_err = texture_image->save_png(atlas_path); |
| 877 | + } else { |
| 878 | + save_err = texture_image->save_exr(atlas_path, false); |
| 879 | + } |
878 | 880 |
|
879 | | - ERR_FAIL_COND_V(save_err, LightmapGI::BAKE_ERROR_CANT_CREATE_IMAGE); |
| 881 | + ERR_FAIL_COND_V(save_err, LightmapGI::BAKE_ERROR_CANT_CREATE_IMAGE); |
880 | 882 |
|
881 | | - // Reimport the file. |
882 | | - ResourceLoader::import(atlas_path); |
883 | | - Ref<TextureLayered> t = ResourceLoader::load(atlas_path); // If already loaded, it will be updated on refocus? |
884 | | - ERR_FAIL_COND_V(t.is_null(), LightmapGI::BAKE_ERROR_CANT_CREATE_IMAGE); |
| 883 | + // Reimport the file. |
| 884 | + Error import_err = ResourceLoader::import(atlas_path); |
| 885 | + ERR_FAIL_COND_V(import_err != OK, LightmapGI::BAKE_ERROR_CANT_CREATE_IMAGE); |
| 886 | + Ref<TextureLayered> t = ResourceLoader::load(atlas_path); // If already loaded, it will be updated on refocus? |
| 887 | + ERR_FAIL_COND_V(t.is_null(), LightmapGI::BAKE_ERROR_CANT_CREATE_IMAGE); |
885 | 888 |
|
886 | | - // Store the atlas in the array. |
887 | | - r_textures[i] = t; |
| 889 | + // Store the atlas in the array. |
| 890 | + r_textures[i] = t; |
| 891 | + } else { |
| 892 | + const String atlas_path = (texture_count > 1 ? p_base_name + "_" + itos(i) : p_base_name) + (p_is_shadowmask ? ".png" : ".exr"); |
| 893 | + if (supersampling_enabled) { |
| 894 | + texture_image->resize(texture_image->get_width() / supersampling_factor, texture_image->get_height() / supersampling_factor, Image::INTERPOLATE_TRILINEAR); |
| 895 | + } |
| 896 | + Vector<Ref<Image>> slice_images; |
| 897 | + slice_images.resize(texture_slice_count); |
| 898 | + for (int j = 0; j < texture_slice_count; j++) { |
| 899 | + slice_images.set(j, images[i * slices_per_texture + j]); |
| 900 | + } |
| 901 | + Ref<Texture2DArray> texs; |
| 902 | + texs.instantiate(); |
| 903 | + texs->create_from_images(slice_images); |
| 904 | + |
| 905 | + Error err = ResourceSaver::save(texs, atlas_path); |
| 906 | + ERR_FAIL_COND_V(err, BAKE_ERROR_CANT_CREATE_IMAGE); |
| 907 | + Ref<TextureLayered> t = ResourceLoader::load(atlas_path); |
| 908 | + ERR_FAIL_COND_V(t.is_null(), BAKE_ERROR_CANT_CREATE_IMAGE); |
| 909 | + r_textures[i] = t; |
| 910 | + } |
888 | 911 | } |
889 | 912 |
|
890 | 913 | return LightmapGI::BAKE_ERROR_OK; |
891 | 914 | } |
892 | 915 |
|
893 | | -LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_path, Lightmapper::BakeStepFunc p_bake_step, void *p_bake_userdata) { |
| 916 | +bool LightmapGI::_dummy_bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh) { |
| 917 | + // No reporting needed, but baking logic is identical |
| 918 | + return true; |
| 919 | +} |
| 920 | + |
| 921 | +LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_path) { |
| 922 | + // is dummy bake func needed? |
| 923 | + return _bake(p_from_node, p_image_data_path, _dummy_bake_func_step, nullptr); |
| 924 | +} |
| 925 | + |
| 926 | +LightmapGI::BakeError LightmapGI::_bake(Node *p_from_node, String p_image_data_path, Lightmapper::BakeStepFunc p_bake_step, void *p_bake_userdata) { |
894 | 927 | if (p_image_data_path.is_empty()) { |
895 | 928 | if (get_light_data().is_null()) { |
896 | 929 | return BAKE_ERROR_NO_SAVE_PATH; |
@@ -1240,14 +1273,39 @@ LightmapGI::BakeError LightmapGI::bake(Node *p_from_node, String p_image_data_pa |
1240 | 1273 | } |
1241 | 1274 |
|
1242 | 1275 | if (env.is_valid()) { |
1243 | | - environment_image = RS::get_singleton()->environment_bake_panorama(env->get_rid(), true, Size2i(128, 64)); |
| 1276 | + // environment_image = RS::get_singleton()->environment_bake_panorama(env->get_rid(), true, Size2i(128, 64)); |
1244 | 1277 | environment_transform = Basis::from_euler(env->get_sky_rotation()).inverse(); |
| 1278 | + |
| 1279 | + Sky::RadianceSize old_radiance_size = Sky::RADIANCE_SIZE_MAX; |
| 1280 | + if (!Engine::get_singleton()->is_editor_hint()) { |
| 1281 | + Ref<Sky> sky = env->get_sky(); |
| 1282 | + if (sky.is_valid()) { |
| 1283 | + old_radiance_size = sky->get_radiance_size(); |
| 1284 | + sky->set_radiance_size(Sky::RADIANCE_SIZE_128); |
| 1285 | + } |
| 1286 | + } |
| 1287 | + environment_image = RS::get_singleton()->environment_bake_panorama(env->get_rid(), true, Size2i(128, 128)); |
| 1288 | + if (old_radiance_size != Sky::RADIANCE_SIZE_MAX) { // If it's not max, it's been set and needs resetting |
| 1289 | + Ref<Sky> sky = env->get_sky(); |
| 1290 | + if (sky.is_valid()) { |
| 1291 | + sky->set_radiance_size(old_radiance_size); |
| 1292 | + } |
| 1293 | + } |
1245 | 1294 | } |
1246 | 1295 | } |
1247 | 1296 | } break; |
1248 | 1297 | case ENVIRONMENT_MODE_CUSTOM_SKY: { |
1249 | 1298 | if (environment_custom_sky.is_valid()) { |
1250 | | - environment_image = RS::get_singleton()->sky_bake_panorama(environment_custom_sky->get_rid(), environment_custom_energy, true, Size2i(128, 64)); |
| 1299 | + // environment_image = RS::get_singleton()->sky_bake_panorama(environment_custom_sky->get_rid(), environment_custom_energy, true, Size2i(128, 64)); |
| 1300 | + Sky::RadianceSize old_radiance_size = Sky::RADIANCE_SIZE_MAX; |
| 1301 | + if (!Engine::get_singleton()->is_editor_hint()) { |
| 1302 | + old_radiance_size = environment_custom_sky->get_radiance_size(); |
| 1303 | + environment_custom_sky->set_radiance_size(Sky::RADIANCE_SIZE_128); |
| 1304 | + } |
| 1305 | + environment_image = RS::get_singleton()->sky_bake_panorama(environment_custom_sky->get_rid(), environment_custom_energy, true, Size2i(128, 128)); |
| 1306 | + if (old_radiance_size != Sky::RADIANCE_SIZE_MAX) { |
| 1307 | + environment_custom_sky->set_radiance_size(old_radiance_size); |
| 1308 | + } |
1251 | 1309 | } |
1252 | 1310 |
|
1253 | 1311 | } break; |
@@ -1899,6 +1957,7 @@ void LightmapGI::_bind_methods() { |
1899 | 1957 | ClassDB::bind_method(D_METHOD("get_camera_attributes"), &LightmapGI::get_camera_attributes); |
1900 | 1958 |
|
1901 | 1959 | // ClassDB::bind_method(D_METHOD("bake", "from_node"), &LightmapGI::bake, DEFVAL(Variant())); |
| 1960 | + ClassDB::bind_method(D_METHOD("bake", "from_node", "image_data_path"), &LightmapGI::bake, DEFVAL("")); |
1902 | 1961 |
|
1903 | 1962 | ADD_GROUP("Tweaks", ""); |
1904 | 1963 | ADD_PROPERTY(PropertyInfo(Variant::INT, "quality", PROPERTY_HINT_ENUM, "Low,Medium,High,Ultra"), "set_bake_quality", "get_bake_quality"); |
|
0 commit comments