Merge pull request #58102 from JFonS/big_lightmap
This commit is contained in:
commit
9343c66815
|
@ -166,15 +166,13 @@ Error LightmapperCPU::_layout_atlas(int p_max_size, Vector2i *r_atlas_size, int
|
|||
}
|
||||
|
||||
float mem_utilization = static_cast<float>(mem_occupied) / mem_used;
|
||||
if (slices * atlas_size.y <= 16384) { // Maximum Image size
|
||||
if (mem_used < best_atlas_memory || (mem_used == best_atlas_memory && mem_utilization > best_atlas_mem_utilization)) {
|
||||
best_atlas_size = atlas_size;
|
||||
best_atlas_offsets = curr_atlas_offsets;
|
||||
best_atlas_slices = slices;
|
||||
best_atlas_memory = mem_used;
|
||||
best_atlas_mem_utilization = mem_utilization;
|
||||
best_scaled_sizes = scaled_sizes;
|
||||
}
|
||||
if (mem_used < best_atlas_memory || (mem_used == best_atlas_memory && mem_utilization > best_atlas_mem_utilization)) {
|
||||
best_atlas_size = atlas_size;
|
||||
best_atlas_offsets = curr_atlas_offsets;
|
||||
best_atlas_slices = slices;
|
||||
best_atlas_memory = mem_used;
|
||||
best_atlas_mem_utilization = mem_utilization;
|
||||
best_scaled_sizes = scaled_sizes;
|
||||
}
|
||||
|
||||
if (recovery_percent == 0) {
|
||||
|
@ -1430,22 +1428,24 @@ LightmapperCPU::BakeError LightmapperCPU::bake(BakeQuality p_quality, bool p_use
|
|||
parameters.environment_panorama->lock();
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < mesh_instances.size(); i++) {
|
||||
if (!mesh_instances[i].generate_lightmap) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p_step_function) {
|
||||
float p = float(i) / n_lit_meshes;
|
||||
bool cancelled = p_step_function(0.4 + p * 0.4, vformat("%s (%d/%d)", TTR("Indirect lighting"), i, mesh_instances.size()), p_bake_userdata, false);
|
||||
if (cancelled) {
|
||||
return BAKE_ERROR_USER_ABORTED;
|
||||
if (parameters.bounces > 0) {
|
||||
for (unsigned int i = 0; i < mesh_instances.size(); i++) {
|
||||
if (!mesh_instances[i].generate_lightmap) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!scene_lightmaps[i].empty()) {
|
||||
if (_parallel_run(scene_lightmaps[i].size(), "Computing indirect light", &LightmapperCPU::_compute_indirect_light, scene_lightmaps[i].ptr(), p_substep_function)) {
|
||||
return BAKE_ERROR_USER_ABORTED;
|
||||
if (p_step_function) {
|
||||
float p = float(i) / n_lit_meshes;
|
||||
bool cancelled = p_step_function(0.4 + p * 0.4, vformat("%s (%d/%d)", TTR("Indirect lighting"), i, mesh_instances.size()), p_bake_userdata, false);
|
||||
if (cancelled) {
|
||||
return BAKE_ERROR_USER_ABORTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!scene_lightmaps[i].empty()) {
|
||||
if (_parallel_run(scene_lightmaps[i].size(), "Computing indirect light", &LightmapperCPU::_compute_indirect_light, scene_lightmaps[i].ptr(), p_substep_function)) {
|
||||
return BAKE_ERROR_USER_ABORTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -954,23 +954,35 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_data_sa
|
|||
bool use_srgb = use_color && !use_hdr;
|
||||
|
||||
if (gen_atlas) {
|
||||
Ref<Image> large_image;
|
||||
large_image.instance();
|
||||
large_image->create(images[0]->get_width(), images[0]->get_height() * images.size(), false, images[0]->get_format());
|
||||
for (int i = 0; i < images.size(); i++) {
|
||||
large_image->blit_rect(images[i], Rect2(0, 0, images[0]->get_width(), images[0]->get_height()), Point2(0, images[0]->get_height() * i));
|
||||
}
|
||||
int slice_count = images.size();
|
||||
int slice_width = images[0]->get_width();
|
||||
int slice_height = images[0]->get_height();
|
||||
|
||||
Ref<TextureLayered> texture;
|
||||
int slices_per_texture = Image::MAX_HEIGHT / slice_height;
|
||||
int texture_count = Math::ceil(slice_count / (float)slices_per_texture);
|
||||
|
||||
Vector<Ref<TextureLayered>> textures;
|
||||
textures.resize(texture_count);
|
||||
String base_path = p_data_save_path.get_basename();
|
||||
|
||||
if (ResourceLoader::import) {
|
||||
_save_image(base_path, large_image, use_srgb);
|
||||
int last_count = slice_count % slices_per_texture;
|
||||
for (int i = 0; i < texture_count; i++) {
|
||||
String texture_path = texture_count > 1 ? base_path + "_" + itos(i) : base_path;
|
||||
int texture_slice_count = (i == texture_count - 1 && last_count != 0) ? last_count : slices_per_texture;
|
||||
|
||||
Ref<Image> large_image;
|
||||
large_image.instance();
|
||||
large_image->create(slice_width, slice_height * texture_slice_count, false, images[0]->get_format());
|
||||
|
||||
for (int j = 0; j < texture_slice_count; j++) {
|
||||
large_image->blit_rect(images[i * slices_per_texture + j], Rect2(0, 0, slice_width, slice_height), Point2(0, slice_height * j));
|
||||
}
|
||||
_save_image(texture_path, large_image, use_srgb);
|
||||
|
||||
Ref<ConfigFile> config;
|
||||
config.instance();
|
||||
if (FileAccess::exists(base_path + ".import")) {
|
||||
config->load(base_path + ".import");
|
||||
if (FileAccess::exists(texture_path + ".import")) {
|
||||
config->load(texture_path + ".import");
|
||||
} else {
|
||||
// Set only if settings don't exist, to keep user choice
|
||||
config->set_value("params", "compress/mode", 0);
|
||||
|
@ -983,49 +995,28 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_data_sa
|
|||
config->set_value("params", "flags/mipmaps", false);
|
||||
config->set_value("params", "flags/srgb", use_srgb);
|
||||
config->set_value("params", "slices/horizontal", 1);
|
||||
config->set_value("params", "slices/vertical", images.size());
|
||||
config->save(base_path + ".import");
|
||||
config->set_value("params", "slices/vertical", texture_slice_count);
|
||||
|
||||
ResourceLoader::import(base_path);
|
||||
texture = ResourceLoader::load(base_path); //if already loaded, it will be updated on refocus?
|
||||
} else {
|
||||
base_path += ".texarr";
|
||||
Ref<TextureLayered> tex;
|
||||
bool set_path = true;
|
||||
if (ResourceCache::has(base_path)) {
|
||||
tex = Ref<Resource>((Resource *)ResourceCache::get(base_path));
|
||||
set_path = false;
|
||||
}
|
||||
config->save(texture_path + ".import");
|
||||
|
||||
if (!tex.is_valid()) {
|
||||
tex.instance();
|
||||
}
|
||||
|
||||
tex->create(images[0]->get_width(), images[0]->get_height(), images.size(), images[0]->get_format(), Texture::FLAGS_DEFAULT);
|
||||
for (int i = 0; i < images.size(); i++) {
|
||||
tex->set_layer_data(images[i], i);
|
||||
}
|
||||
|
||||
ResourceSaver::save(base_path, tex, ResourceSaver::FLAG_CHANGE_PATH);
|
||||
if (set_path) {
|
||||
tex->set_path(base_path);
|
||||
}
|
||||
texture = tex;
|
||||
ResourceLoader::import(texture_path);
|
||||
textures.write[i] = ResourceLoader::load(texture_path); //if already loaded, it will be updated on refocus?
|
||||
}
|
||||
|
||||
for (int i = 0; i < lightmapper->get_bake_mesh_count(); i++) {
|
||||
if (meshes_found[i].generate_lightmap) {
|
||||
Dictionary d = lightmapper->get_bake_mesh_userdata(i);
|
||||
NodePath np = d["path"];
|
||||
int32_t subindex = -1;
|
||||
if (d.has("subindex")) {
|
||||
subindex = d["subindex"];
|
||||
}
|
||||
|
||||
Rect2 uv_rect = lightmapper->get_bake_mesh_uv_scale(i);
|
||||
int slice_index = lightmapper->get_bake_mesh_texture_slice(i);
|
||||
data->add_user(np, texture, slice_index, uv_rect, subindex);
|
||||
if (!meshes_found[i].generate_lightmap) {
|
||||
continue;
|
||||
}
|
||||
Dictionary d = lightmapper->get_bake_mesh_userdata(i);
|
||||
NodePath np = d["path"];
|
||||
int32_t subindex = -1;
|
||||
if (d.has("subindex")) {
|
||||
subindex = d["subindex"];
|
||||
}
|
||||
|
||||
Rect2 uv_rect = lightmapper->get_bake_mesh_uv_scale(i);
|
||||
int slice_index = lightmapper->get_bake_mesh_texture_slice(i);
|
||||
data->add_user(np, textures[slice_index / slices_per_texture], slice_index % slices_per_texture, uv_rect, subindex);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < lightmapper->get_bake_mesh_count(); i++) {
|
||||
|
|
Loading…
Reference in New Issue