Browse Source

GPULightmapper's triangles and their bounding box will be in-sync

Previously the bounding boxes and triangles were maintained in two separate
arrays (Vectors). As the triangle vector was sorted and the bounding-box array
was not , the order of both arrays differed. This meant that the index in one
was different than the other, which caused lookup issues.

To prevent this, the bounding-box is now part of the triangle structure so that
there is a single structure that cannot become out-of-sync anymore.
William Deurwaarder 4 years ago
parent
commit
e11dd6500a

+ 3 - 0
modules/lightmapper_rd/SCsub

@@ -7,6 +7,9 @@ env_lightmapper_rd = env_modules.Clone()
 env_lightmapper_rd.GLSL_HEADER("lm_raster.glsl")
 env_lightmapper_rd.GLSL_HEADER("lm_raster.glsl")
 env_lightmapper_rd.GLSL_HEADER("lm_compute.glsl")
 env_lightmapper_rd.GLSL_HEADER("lm_compute.glsl")
 env_lightmapper_rd.GLSL_HEADER("lm_blendseams.glsl")
 env_lightmapper_rd.GLSL_HEADER("lm_blendseams.glsl")
+env_lightmapper_rd.Depends("lm_raster.glsl.gen.h", "lm_common_inc.glsl")
+env_lightmapper_rd.Depends("lm_compute.glsl.gen.h", "lm_common_inc.glsl")
+env_lightmapper_rd.Depends("lm_blendseams.glsl.gen.h", "lm_common_inc.glsl")
 
 
 # Godot source files
 # Godot source files
 env_lightmapper_rd.add_source_files(env.modules_sources, "*.cpp")
 env_lightmapper_rd.add_source_files(env.modules_sources, "*.cpp")

+ 16 - 32
modules/lightmapper_rd/lightmapper_rd.cpp

@@ -274,13 +274,12 @@ Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_
 	return BAKE_OK;
 	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 &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 &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;
 	HashMap<Vertex, uint32_t, VertexHash> vertex_map;
 
 
 	//fill triangles array and vertex array
 	//fill triangles array and vertex array
 	LocalVector<Triangle> triangles;
 	LocalVector<Triangle> triangles;
 	LocalVector<Vertex> vertex_array;
 	LocalVector<Vertex> vertex_array;
-	LocalVector<Box> box_array;
 	LocalVector<Seam> seams;
 	LocalVector<Seam> seams;
 
 
 	slice_triangle_count.resize(atlas_slices);
 	slice_triangle_count.resize(atlas_slices);
@@ -387,16 +386,13 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i
 				}
 				}
 			}
 			}
 
 
-			Box box;
-			box.min_bounds[0] = taabb.position.x;
-			box.min_bounds[1] = taabb.position.y;
-			box.min_bounds[2] = taabb.position.z;
-			box.max_bounds[0] = taabb.position.x + MAX(taabb.size.x, 0.0001);
-			box.max_bounds[1] = taabb.position.y + MAX(taabb.size.y, 0.0001);
-			box.max_bounds[2] = taabb.position.z + MAX(taabb.size.z, 0.0001);
-			box.pad0 = box.pad1 = 0; //make valgrind not complain
-			box_array.push_back(box);
-
+			t.min_bounds[0] = taabb.position.x;
+			t.min_bounds[1] = taabb.position.y;
+			t.min_bounds[2] = taabb.position.z;
+			t.max_bounds[0] = taabb.position.x + MAX(taabb.size.x, 0.0001);
+			t.max_bounds[1] = taabb.position.y + MAX(taabb.size.y, 0.0001);
+			t.max_bounds[2] = taabb.position.z + MAX(taabb.size.z, 0.0001);
+			t.pad0 = t.pad1 = 0; //make valgrind not complain
 			triangles.push_back(t);
 			triangles.push_back(t);
 			slice_triangle_count.write[t.slice]++;
 			slice_triangle_count.write[t.slice]++;
 		}
 		}
@@ -505,9 +501,6 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i
 		Vector<uint8_t> tb = triangles.to_byte_array();
 		Vector<uint8_t> tb = triangles.to_byte_array();
 		triangle_buffer = rd->storage_buffer_create(tb.size(), tb);
 		triangle_buffer = rd->storage_buffer_create(tb.size(), tb);
 
 
-		Vector<uint8_t> bb = box_array.to_byte_array();
-		box_buffer = rd->storage_buffer_create(bb.size(), bb);
-
 		Vector<uint8_t> tib = triangle_indices.to_byte_array();
 		Vector<uint8_t> tib = triangle_indices.to_byte_array();
 		triangle_cell_indices_buffer = rd->storage_buffer_create(tib.size(), tib);
 		triangle_cell_indices_buffer = rd->storage_buffer_create(tib.size(), tib);
 
 
@@ -755,7 +748,6 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
 	Vector<int> slice_triangle_count;
 	Vector<int> slice_triangle_count;
 	RID vertex_buffer;
 	RID vertex_buffer;
 	RID triangle_buffer;
 	RID triangle_buffer;
-	RID box_buffer;
 	RID lights_buffer;
 	RID lights_buffer;
 	RID triangle_cell_indices_buffer;
 	RID triangle_cell_indices_buffer;
 	RID grid_texture;
 	RID grid_texture;
@@ -767,14 +759,13 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
 #define FREE_BUFFERS                        \
 #define FREE_BUFFERS                        \
 	rd->free(vertex_buffer);                \
 	rd->free(vertex_buffer);                \
 	rd->free(triangle_buffer);              \
 	rd->free(triangle_buffer);              \
-	rd->free(box_buffer);                   \
 	rd->free(lights_buffer);                \
 	rd->free(lights_buffer);                \
 	rd->free(triangle_cell_indices_buffer); \
 	rd->free(triangle_cell_indices_buffer); \
 	rd->free(grid_texture);                 \
 	rd->free(grid_texture);                 \
 	rd->free(seams_buffer);                 \
 	rd->free(seams_buffer);                 \
 	rd->free(probe_positions_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, 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, lights_buffer, triangle_cell_indices_buffer, probe_positions_buffer, grid_texture, seams_buffer, p_step_function, p_bake_userdata);
 
 
 	if (p_step_function) {
 	if (p_step_function) {
 		p_step_function(0.47, TTR("Preparing shaders"), p_bake_userdata, true);
 		p_step_function(0.47, TTR("Preparing shaders"), p_bake_userdata, true);
@@ -828,62 +819,55 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
 			RD::Uniform u;
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.binding = 3;
 			u.binding = 3;
-			u.ids.push_back(box_buffer);
-			base_uniforms.push_back(u);
-		}
-		{
-			RD::Uniform u;
-			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
-			u.binding = 4;
 			u.ids.push_back(triangle_cell_indices_buffer);
 			u.ids.push_back(triangle_cell_indices_buffer);
 			base_uniforms.push_back(u);
 			base_uniforms.push_back(u);
 		}
 		}
 		{
 		{
 			RD::Uniform u;
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
-			u.binding = 5;
+			u.binding = 4;
 			u.ids.push_back(lights_buffer);
 			u.ids.push_back(lights_buffer);
 			base_uniforms.push_back(u);
 			base_uniforms.push_back(u);
 		}
 		}
 		{
 		{
 			RD::Uniform u;
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
-			u.binding = 6;
+			u.binding = 5;
 			u.ids.push_back(seams_buffer);
 			u.ids.push_back(seams_buffer);
 			base_uniforms.push_back(u);
 			base_uniforms.push_back(u);
 		}
 		}
 		{
 		{
 			RD::Uniform u;
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
 			u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
-			u.binding = 7;
+			u.binding = 6;
 			u.ids.push_back(probe_positions_buffer);
 			u.ids.push_back(probe_positions_buffer);
 			base_uniforms.push_back(u);
 			base_uniforms.push_back(u);
 		}
 		}
 		{
 		{
 			RD::Uniform u;
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			u.binding = 8;
+			u.binding = 7;
 			u.ids.push_back(grid_texture);
 			u.ids.push_back(grid_texture);
 			base_uniforms.push_back(u);
 			base_uniforms.push_back(u);
 		}
 		}
 		{
 		{
 			RD::Uniform u;
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			u.binding = 9;
+			u.binding = 8;
 			u.ids.push_back(albedo_array_tex);
 			u.ids.push_back(albedo_array_tex);
 			base_uniforms.push_back(u);
 			base_uniforms.push_back(u);
 		}
 		}
 		{
 		{
 			RD::Uniform u;
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
 			u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
-			u.binding = 10;
+			u.binding = 9;
 			u.ids.push_back(emission_array_tex);
 			u.ids.push_back(emission_array_tex);
 			base_uniforms.push_back(u);
 			base_uniforms.push_back(u);
 		}
 		}
 		{
 		{
 			RD::Uniform u;
 			RD::Uniform u;
 			u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
 			u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
-			u.binding = 11;
+			u.binding = 10;
 			u.ids.push_back(sampler);
 			u.ids.push_back(sampler);
 			base_uniforms.push_back(u);
 			base_uniforms.push_back(u);
 		}
 		}

+ 4 - 7
modules/lightmapper_rd/lightmapper_rd.h

@@ -157,16 +157,13 @@ class LightmapperRD : public Lightmapper {
 		}
 		}
 	};
 	};
 
 
-	struct Box {
+	struct Triangle {
+		uint32_t indices[3] = {};
+		uint32_t slice = 0;
 		float min_bounds[3] = {};
 		float min_bounds[3] = {};
 		float pad0 = 0.0;
 		float pad0 = 0.0;
 		float max_bounds[3] = {};
 		float max_bounds[3] = {};
 		float pad1 = 0.0;
 		float pad1 = 0.0;
-	};
-
-	struct Triangle {
-		uint32_t indices[3] = {};
-		uint32_t slice = 0;
 		bool operator<(const Triangle &p_triangle) const {
 		bool operator<(const Triangle &p_triangle) const {
 			return slice < p_triangle.slice;
 			return slice < p_triangle.slice;
 		}
 		}
@@ -231,7 +228,7 @@ class LightmapperRD : public Lightmapper {
 	Vector<Color> probe_values;
 	Vector<Color> probe_values;
 
 
 	BakeError _blit_meshes_into_atlas(int p_max_texture_size, Vector<Ref<Image>> &albedo_images, Vector<Ref<Image>> &emission_images, AABB &bounds, Size2i &atlas_size, int &atlas_slices, BakeStepFunc p_step_function, void *p_bake_userdata);
 	BakeError _blit_meshes_into_atlas(int p_max_texture_size, Vector<Ref<Image>> &albedo_images, Vector<Ref<Image>> &emission_images, AABB &bounds, Size2i &atlas_size, int &atlas_slices, BakeStepFunc p_step_function, void *p_bake_userdata);
-	void _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);
+	void _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 &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);
 	void _raster_geometry(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, int grid_size, AABB bounds, float p_bias, Vector<int> slice_triangle_count, RID position_tex, RID unocclude_tex, RID normal_tex, RID raster_depth_buffer, RID rasterize_shader, RID raster_base_uniform);
 	void _raster_geometry(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, int grid_size, AABB bounds, float p_bias, Vector<int> slice_triangle_count, RID position_tex, RID unocclude_tex, RID normal_tex, RID raster_depth_buffer, RID rasterize_shader, RID raster_base_uniform);
 
 
 public:
 public:

+ 11 - 19
modules/lightmapper_rd/lm_common_inc.glsl

@@ -16,26 +16,18 @@ vertices;
 struct Triangle {
 struct Triangle {
 	uvec3 indices;
 	uvec3 indices;
 	uint slice;
 	uint slice;
-};
-
-layout(set = 0, binding = 2, std430) restrict readonly buffer Triangles {
-	Triangle data[];
-}
-triangles;
-
-struct Box {
 	vec3 min_bounds;
 	vec3 min_bounds;
 	uint pad0;
 	uint pad0;
 	vec3 max_bounds;
 	vec3 max_bounds;
 	uint pad1;
 	uint pad1;
 };
 };
 
 
-layout(set = 0, binding = 3, std430) restrict readonly buffer Boxes {
-	Box data[];
+layout(set = 0, binding = 2, std430) restrict readonly buffer Triangles {
+	Triangle data[];
 }
 }
-boxes;
+triangles;
 
 
-layout(set = 0, binding = 4, std430) restrict readonly buffer GridIndices {
+layout(set = 0, binding = 3, std430) restrict readonly buffer GridIndices {
 	uint data[];
 	uint data[];
 }
 }
 grid_indices;
 grid_indices;
@@ -63,7 +55,7 @@ struct Light {
 	uint pad[3];
 	uint pad[3];
 };
 };
 
 
-layout(set = 0, binding = 5, std430) restrict readonly buffer Lights {
+layout(set = 0, binding = 4, std430) restrict readonly buffer Lights {
 	Light data[];
 	Light data[];
 }
 }
 lights;
 lights;
@@ -73,19 +65,19 @@ struct Seam {
 	uvec2 b;
 	uvec2 b;
 };
 };
 
 
-layout(set = 0, binding = 6, std430) restrict readonly buffer Seams {
+layout(set = 0, binding = 5, std430) restrict readonly buffer Seams {
 	Seam data[];
 	Seam data[];
 }
 }
 seams;
 seams;
 
 
-layout(set = 0, binding = 7, std430) restrict readonly buffer Probes {
+layout(set = 0, binding = 6, std430) restrict readonly buffer Probes {
 	vec4 data[];
 	vec4 data[];
 }
 }
 probe_positions;
 probe_positions;
 
 
-layout(set = 0, binding = 8) uniform utexture3D grid;
+layout(set = 0, binding = 7) uniform utexture3D grid;
 
 
-layout(set = 0, binding = 9) uniform texture2DArray albedo_tex;
-layout(set = 0, binding = 10) uniform texture2DArray emission_tex;
+layout(set = 0, binding = 8) uniform texture2DArray albedo_tex;
+layout(set = 0, binding = 9) uniform texture2DArray emission_tex;
 
 
-layout(set = 0, binding = 11) uniform sampler linear_sampler;
+layout(set = 0, binding = 10) uniform sampler linear_sampler;

+ 7 - 6
modules/lightmapper_rd/lm_compute.glsl

@@ -160,18 +160,19 @@ bool trace_ray(vec3 p_from, vec3 p_to
 				uint tidx = grid_indices.data[cell_data.y + i];
 				uint tidx = grid_indices.data[cell_data.y + i];
 
 
 				//Ray-Box test
 				//Ray-Box test
-				vec3 t0 = (boxes.data[tidx].min_bounds - p_from) * inv_dir;
-				vec3 t1 = (boxes.data[tidx].max_bounds - p_from) * inv_dir;
+				Triangle triangle = triangles.data[tidx];
+				vec3 t0 = (triangle.min_bounds - p_from) * inv_dir;
+				vec3 t1 = (triangle.max_bounds - p_from) * inv_dir;
 				vec3 tmin = min(t0, t1), tmax = max(t0, t1);
 				vec3 tmin = min(t0, t1), tmax = max(t0, t1);
 
 
-				if (max(tmin.x, max(tmin.y, tmin.z)) <= min(tmax.x, min(tmax.y, tmax.z))) {
+				if (max(tmin.x, max(tmin.y, tmin.z)) > min(tmax.x, min(tmax.y, tmax.z))) {
 					continue; //ray box failed
 					continue; //ray box failed
 				}
 				}
 
 
 				//prepare triangle vertices
 				//prepare triangle vertices
-				vec3 vtx0 = vertices.data[triangles.data[tidx].indices.x].position;
-				vec3 vtx1 = vertices.data[triangles.data[tidx].indices.y].position;
-				vec3 vtx2 = vertices.data[triangles.data[tidx].indices.z].position;
+				vec3 vtx0 = vertices.data[triangle.indices.x].position;
+				vec3 vtx1 = vertices.data[triangle.indices.y].position;
+				vec3 vtx2 = vertices.data[triangle.indices.z].position;
 #if defined(MODE_UNOCCLUDE)
 #if defined(MODE_UNOCCLUDE)
 				vec3 normal = -normalize(cross((vtx0 - vtx1), (vtx0 - vtx2)));
 				vec3 normal = -normalize(cross((vtx0 - vtx1), (vtx0 - vtx2)));