summaryrefslogtreecommitdiff
path: root/modules/lightmapper_rd/lightmapper_rd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/lightmapper_rd/lightmapper_rd.cpp')
-rw-r--r--modules/lightmapper_rd/lightmapper_rd.cpp86
1 files changed, 37 insertions, 49 deletions
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
index 9394e5c47e..3b0fbb1c47 100644
--- a/modules/lightmapper_rd/lightmapper_rd.cpp
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -162,8 +162,8 @@ Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_
MeshInstance &mi = mesh_instances.write[m_i];
Size2i s = Size2i(mi.data.albedo_on_uv2->get_width(), mi.data.albedo_on_uv2->get_height());
sizes.push_back(s);
- atlas_size.width = MAX(atlas_size.width, s.width);
- atlas_size.height = MAX(atlas_size.height, s.height);
+ atlas_size.width = MAX(atlas_size.width, s.width + 2);
+ atlas_size.height = MAX(atlas_size.height, s.height + 2);
}
int max = nearest_power_of_2_templated(atlas_size.width);
@@ -186,10 +186,12 @@ Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_
//determine best texture array atlas size by bruteforce fitting
while (atlas_size.x <= p_max_texture_size && atlas_size.y <= p_max_texture_size) {
- Vector<Vector2i> source_sizes = sizes;
+ Vector<Vector2i> source_sizes;
Vector<int> source_indices;
- source_indices.resize(source_sizes.size());
+ source_sizes.resize(sizes.size());
+ source_indices.resize(sizes.size());
for (int i = 0; i < source_indices.size(); i++) {
+ source_sizes.write[i] = sizes[i] + Vector2i(2, 2); // Add padding between lightmaps
source_indices.write[i] = i;
}
Vector<Vector3i> atlas_offsets;
@@ -207,7 +209,7 @@ Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_
if (ofs.z > 0) {
//valid
ofs.z = slices;
- atlas_offsets.write[sidx] = ofs;
+ atlas_offsets.write[sidx] = ofs + Vector3i(1, 1, 0); // Center lightmap in the reserved oversized region
} else {
new_indices.push_back(sidx);
new_sources.push_back(source_sizes[i]);
@@ -272,7 +274,7 @@ Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_
return BAKE_OK;
}
-void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, AABB &bounds, int grid_size, Vector<Probe> &probe_positions, GenerateProbes p_generate_probes, Vector<int> &slice_triangle_count, Vector<int> &slice_seam_count, RID &vertex_buffer, RID &triangle_buffer, RID &box_buffer, RID &lights_buffer, RID &triangle_cell_indices_buffer, RID &probe_positions_buffer, RID &grid_texture, RID &grid_texture_sdf, RID &seams_buffer, BakeStepFunc p_step_function, void *p_bake_userdata) {
+void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, AABB &bounds, int grid_size, Vector<Probe> &probe_positions, GenerateProbes p_generate_probes, Vector<int> &slice_triangle_count, Vector<int> &slice_seam_count, RID &vertex_buffer, RID &triangle_buffer, RID &box_buffer, RID &lights_buffer, RID &triangle_cell_indices_buffer, RID &probe_positions_buffer, RID &grid_texture, RID &seams_buffer, BakeStepFunc p_step_function, void *p_bake_userdata) {
HashMap<Vertex, uint32_t, VertexHash> vertex_map;
//fill triangles array and vertex array
@@ -482,14 +484,6 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i
img->save_png("res://grid_layer_" + itos(1000 + i).substr(1, 3) + ".png");
}
#endif
- if (p_step_function) {
- p_step_function(0.45, TTR("Generating Signed Distance Field"), p_bake_userdata, true);
- }
-
- //generate SDF for raytracing
- Vector<uint32_t> euclidean_pos = Geometry3D::generate_edf(solid, Vector3i(grid_size, grid_size, grid_size), false);
- Vector<uint32_t> euclidean_neg = Geometry3D::generate_edf(solid, Vector3i(grid_size, grid_size, grid_size), true);
- Vector<int8_t> sdf8 = Geometry3D::generate_sdf8(euclidean_pos, euclidean_neg);
/*****************************/
/*** CREATE GPU STRUCTURES ***/
@@ -551,10 +545,6 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i
tf.format = RD::DATA_FORMAT_R32G32_UINT;
texdata.write[0] = grid_indices.to_byte_array();
grid_texture = rd->texture_create(tf, RD::TextureView(), texdata);
- //sdf
- tf.format = RD::DATA_FORMAT_R8_SNORM;
- texdata.write[0] = sdf8.to_byte_array();
- grid_texture_sdf = rd->texture_create(tf, RD::TextureView(), texdata);
}
}
@@ -755,8 +745,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
light_environment_tex = rd->texture_create(tfp, RD::TextureView(), tdata);
#ifdef DEBUG_TEXTURES
- panorama_tex->convert(Image::FORMAT_RGB8);
- panorama_tex->save_png("res://0_panorama.png");
+ panorama_tex->save_exr("res://0_panorama.exr", false);
#endif
}
}
@@ -770,7 +759,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
RID lights_buffer;
RID triangle_cell_indices_buffer;
RID grid_texture;
- RID grid_texture_sdf;
RID seams_buffer;
RID probe_positions_buffer;
@@ -783,11 +771,10 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
rd->free(lights_buffer); \
rd->free(triangle_cell_indices_buffer); \
rd->free(grid_texture); \
- rd->free(grid_texture_sdf); \
rd->free(seams_buffer); \
rd->free(probe_positions_buffer);
- _create_acceleration_structures(rd, atlas_size, atlas_slices, bounds, grid_size, probe_positions, p_generate_probes, slice_triangle_count, slice_seam_count, vertex_buffer, triangle_buffer, box_buffer, lights_buffer, triangle_cell_indices_buffer, probe_positions_buffer, grid_texture, grid_texture_sdf, seams_buffer, p_step_function, p_bake_userdata);
+ _create_acceleration_structures(rd, atlas_size, atlas_slices, bounds, grid_size, probe_positions, p_generate_probes, slice_triangle_count, slice_seam_count, vertex_buffer, triangle_buffer, box_buffer, lights_buffer, triangle_cell_indices_buffer, probe_positions_buffer, grid_texture, seams_buffer, p_step_function, p_bake_userdata);
if (p_step_function) {
p_step_function(0.47, TTR("Preparing shaders"), p_bake_userdata, true);
@@ -883,27 +870,20 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
- u.ids.push_back(grid_texture_sdf);
- base_uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 10;
u.ids.push_back(albedo_array_tex);
base_uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 11;
+ u.binding = 10;
u.ids.push_back(emission_array_tex);
base_uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 12;
+ u.binding = 11;
u.ids.push_back(sampler);
base_uniforms.push_back(u);
}
@@ -937,13 +917,11 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
Ref<Image> img;
img.instance();
img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAF, s);
- img->convert(Image::FORMAT_RGBA8);
- img->save_png("res://1_position_" + itos(i) + ".png");
+ img->save_exr("res://1_position_" + itos(i) + ".exr", false);
s = rd->texture_get_data(normal_tex, i);
img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
- img->convert(Image::FORMAT_RGBA8);
- img->save_png("res://1_normal_" + itos(i) + ".png");
+ img->save_exr("res://1_normal_" + itos(i) + ".exr", false);
}
#endif
@@ -966,27 +944,27 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
}
ERR_FAIL_COND_V(err != OK, BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES);
- //unoccluder
+ // Unoccluder
RID compute_shader_unocclude = rd->shader_create_from_bytecode(compute_shader->get_bytecode("unocclude"));
ERR_FAIL_COND_V(compute_shader_unocclude.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); // internal check, should not happen
RID compute_shader_unocclude_pipeline = rd->compute_pipeline_create(compute_shader_unocclude);
- //direct light
+ // Direct light
RID compute_shader_primary = rd->shader_create_from_bytecode(compute_shader->get_bytecode("primary"));
ERR_FAIL_COND_V(compute_shader_primary.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); // internal check, should not happen
RID compute_shader_primary_pipeline = rd->compute_pipeline_create(compute_shader_primary);
- //indirect light
+ // Indirect light
RID compute_shader_secondary = rd->shader_create_from_bytecode(compute_shader->get_bytecode("secondary"));
ERR_FAIL_COND_V(compute_shader_secondary.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
RID compute_shader_secondary_pipeline = rd->compute_pipeline_create(compute_shader_secondary);
- //dilate
+ // Dilate
RID compute_shader_dilate = rd->shader_create_from_bytecode(compute_shader->get_bytecode("dilate"));
ERR_FAIL_COND_V(compute_shader_dilate.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
RID compute_shader_dilate_pipeline = rd->compute_pipeline_create(compute_shader_dilate);
- //dilate
+ // Light probes
RID compute_shader_light_probes = rd->shader_create_from_bytecode(compute_shader->get_bytecode("light_probes"));
ERR_FAIL_COND_V(compute_shader_light_probes.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
RID compute_shader_light_probes_pipeline = rd->compute_pipeline_create(compute_shader_light_probes);
@@ -1153,8 +1131,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
Ref<Image> img;
img.instance();
img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
- img->convert(Image::FORMAT_RGBA8);
- img->save_png("res://2_light_primary_" + itos(i) + ".png");
+ img->save_exr("res://2_light_primary_" + itos(i) + ".exr", false);
}
#endif
@@ -1212,7 +1189,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 6;
- u.ids.push_back(light_environment_tex); //reuse unocclude tex
+ u.ids.push_back(light_environment_tex);
uniforms.push_back(u);
}
}
@@ -1298,7 +1275,15 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
}
}
}
+
+ if (b == 0) {
+ // This disables the environment for subsequent bounces
+ push_constant.environment_xform[3] = -99.0f;
+ }
}
+
+ // Restore the correct environment transform
+ push_constant.environment_xform[3] = 0.0f;
}
/* LIGHPROBES */
@@ -1449,8 +1434,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
Ref<Image> img;
img.instance();
img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
- img->convert(Image::FORMAT_RGBA8);
- img->save_png("res://4_light_secondary_" + itos(i) + ".png");
+ img->save_exr("res://4_light_secondary_" + itos(i) + ".exr", false);
}
#endif
@@ -1582,6 +1566,11 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
clear_colors.push_back(Color(0, 0, 0, 1));
for (int i = 0; i < atlas_slices; i++) {
int subslices = (p_bake_sh ? 4 : 1);
+
+ if (slice_seam_count[i] == 0) {
+ continue;
+ }
+
for (int k = 0; k < subslices; k++) {
RasterSeamsPushConstant seams_push_constant;
seams_push_constant.slice = uint32_t(i * subslices + k);
@@ -1654,8 +1643,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
Ref<Image> img;
img.instance();
img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
- img->convert(Image::FORMAT_RGBA8);
- img->save_png("res://5_blendseams" + itos(i) + ".png");
+ img->save_exr("res://5_blendseams" + itos(i) + ".exr", false);
}
#endif
if (p_step_function) {
@@ -1682,7 +1670,7 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
Ref<Image> img2;
img2.instance();
img2->create(probe_values.size(), 1, false, Image::FORMAT_RGBAF, probe_data);
- img2->save_png("res://6_lightprobes.png");
+ img2->save_exr("res://6_lightprobes.exr", false);
}
#endif
}