From 76a7e73c6d4d9f6d4b5815b715a9d1ca2e8daeb4 Mon Sep 17 00:00:00 2001
From: Tobias Frisch <tfrisch@uni-koblenz.de>
Date: Thu, 3 Feb 2022 02:02:07 +0100
Subject: [PATCH] Normalized weights via calculated sum of weights

Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de>
---
 projects/wobble_bobble/shaders/grid.vert      |  2 +-
 ...olumes.comp => init_particle_weights.comp} | 25 +++----
 projects/wobble_bobble/shaders/particle.inc   |  9 ++-
 projects/wobble_bobble/src/main.cpp           | 73 ++++++++++---------
 4 files changed, 54 insertions(+), 55 deletions(-)
 rename projects/wobble_bobble/shaders/{init_particle_volumes.comp => init_particle_weights.comp} (67%)

diff --git a/projects/wobble_bobble/shaders/grid.vert b/projects/wobble_bobble/shaders/grid.vert
index d0068e47..3636d87b 100644
--- a/projects/wobble_bobble/shaders/grid.vert
+++ b/projects/wobble_bobble/shaders/grid.vert
@@ -38,7 +38,7 @@ void main()	{
 
     float mass = gridData.w;
     float density = mass / sphere_volume(size);
-    float alpha = clamp(density / 100000000.0f, 0.0f, 1.0f);
+    float alpha = clamp(density / 10000.0f, 0.0f, 1.0f);
 
     passPos = vertexPos;
     passVelocity = gridData.xyz;
diff --git a/projects/wobble_bobble/shaders/init_particle_volumes.comp b/projects/wobble_bobble/shaders/init_particle_weights.comp
similarity index 67%
rename from projects/wobble_bobble/shaders/init_particle_volumes.comp
rename to projects/wobble_bobble/shaders/init_particle_weights.comp
index c7c64be3..3530bfa1 100644
--- a/projects/wobble_bobble/shaders/init_particle_volumes.comp
+++ b/projects/wobble_bobble/shaders/init_particle_weights.comp
@@ -16,12 +16,16 @@ void main()	{
     if (gl_GlobalInvocationID.x < particles.length()) {
         ParticleMinimal minimal = particles[gl_GlobalInvocationID.x].minimal;
 
+        minimal.weight_sum = 1.0f;
+
+        barrier();
+        memoryBarrierBuffer();
+
         ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0);
         ivec3 gridWindow = ivec3(minimal.size * 2.0f * gridResolution);
 
-        float volume = sphere_volume(minimal.size);
+        float weight_sum = 0.0f;
 
-        float mass = 0.0f;
         int i, j, k;
 
         barrier();
@@ -33,9 +37,7 @@ void main()	{
                     vec3 offset = vec3(i, j, k) / gridResolution;
                     vec3 voxel = minimal.position + offset;
 
-                    vec4 gridSample = texture(sampler3D(gridImage, gridSampler), voxel);
-
-                    mass += gridSample.w * voxel_particle_weight(voxel, minimal);
+                    weight_sum += voxel_particle_weight(voxel, minimal);
                 }
             }
         }
@@ -43,17 +45,8 @@ void main()	{
         barrier();
         memoryBarrierBuffer();
 
-        if (volume > 0.0f) {
-            float density = minimal.mass / volume;
-
-            //volume = minimal.mass / (mass / volume);
-            //mass = density * volume;
+        if (weight_sum > 0.0f) {
+            particles[gl_GlobalInvocationID.x].minimal.weight_sum = weight_sum;
         }
-
-        barrier();
-        memoryBarrierBuffer();
-
-        particles[gl_GlobalInvocationID.x].minimal.size = sphere_radius(volume);
-        particles[gl_GlobalInvocationID.x].minimal.mass = mass;
     }
 }
\ No newline at end of file
diff --git a/projects/wobble_bobble/shaders/particle.inc b/projects/wobble_bobble/shaders/particle.inc
index 06608c2b..595db9ab 100644
--- a/projects/wobble_bobble/shaders/particle.inc
+++ b/projects/wobble_bobble/shaders/particle.inc
@@ -6,6 +6,9 @@ struct ParticleMinimal {
     float size;
     vec3 velocity;
     float mass;
+	
+	vec3 pad;
+	float weight_sum;
 };
 
 struct Particle {
@@ -64,7 +67,9 @@ float voxel_particle_weight(vec3 voxel, ParticleMinimal particle) {
 		weight_C(delta.z)
 	);
 	
-	return weight.x * weight.y * weight.z;
+	return (
+		weight.x * weight.y * weight.z
+	) / particle.weight_sum;
 }
 
 float grad_weight_A(float x) {
@@ -119,7 +124,7 @@ vec3 voxel_particle_grad_weight(vec3 voxel, ParticleMinimal particle) {
 			grad_weight.x * weight.y * weight.z,
 			grad_weight.y * weight.z * weight.x,
 			grad_weight.z * weight.x * weight.y
-	);
+	) / particle.weight_sum;
 }
 
 #endif // PARTICLE_INC
\ No newline at end of file
diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp
index 5294f1ae..19a22b10 100644
--- a/projects/wobble_bobble/src/main.cpp
+++ b/projects/wobble_bobble/src/main.cpp
@@ -11,6 +11,10 @@ struct Particle {
 	float size;
 	glm::vec3 velocity;
 	float mass;
+	
+	glm::vec3 pad;
+	float weight_sum;
+	
 	glm::mat4 deformation;
 };
 
@@ -72,6 +76,9 @@ void distributeParticles(Particle *particles, size_t count, const glm::vec3& cen
 	for (size_t i = 0; i < count; i++) {
 		particles[i].mass = (mass * sphere_volume(particles[i].size) / volume);
 		particles[i].deformation = glm::mat4(1.0f);
+		
+		particles[i].pad = glm::vec3(0.0f);
+		particles[i].weight_sum = 1.0f;
 	}
 }
 
@@ -214,33 +221,33 @@ int main(int argc, const char **argv) {
 	
 	vkcv::shader::GLSLCompiler compiler;
 	
-	std::vector<vkcv::DescriptorSetHandle> transformParticlesToGridSets;
-	vkcv::ComputePipelineHandle transformParticlesToGridPipeline = createComputePipeline(
+	std::vector<vkcv::DescriptorSetHandle> initParticleWeightsSets;
+	vkcv::ComputePipelineHandle initParticleWeightsPipeline = createComputePipeline(
 			core, compiler,
-			"shaders/transform_particles_to_grid.comp",
-			transformParticlesToGridSets
+			"shaders/init_particle_weights.comp",
+			initParticleWeightsSets
 	);
 	
 	{
 		vkcv::DescriptorWrites writes;
 		writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particles.getHandle()));
-		writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(1, gridCopy.getHandle()));
-		core.writeDescriptorSet(transformParticlesToGridSets[0], writes);
+		writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(1, gridCopy.getHandle()));
+		writes.samplerWrites.push_back(vkcv::SamplerDescriptorWrite(2, gridSampler));
+		core.writeDescriptorSet(initParticleWeightsSets[0], writes);
 	}
 	
-	std::vector<vkcv::DescriptorSetHandle> initParticleVolumesSets;
-	vkcv::ComputePipelineHandle initParticleVolumesPipeline = createComputePipeline(
+	std::vector<vkcv::DescriptorSetHandle> transformParticlesToGridSets;
+	vkcv::ComputePipelineHandle transformParticlesToGridPipeline = createComputePipeline(
 			core, compiler,
-			"shaders/init_particle_volumes.comp",
-			initParticleVolumesSets
+			"shaders/transform_particles_to_grid.comp",
+			transformParticlesToGridSets
 	);
 	
 	{
 		vkcv::DescriptorWrites writes;
 		writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particles.getHandle()));
-		writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(1, gridCopy.getHandle()));
-		writes.samplerWrites.push_back(vkcv::SamplerDescriptorWrite(2, gridSampler));
-		core.writeDescriptorSet(initParticleVolumesSets[0], writes);
+		writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(1, gridCopy.getHandle()));
+		core.writeDescriptorSet(transformParticlesToGridSets[0], writes);
 	}
 	
 	std::vector<vkcv::DescriptorSetHandle> updateGridForcesSets;
@@ -547,7 +554,6 @@ int main(int argc, const char **argv) {
 			1
 	));
 	
-	bool initializedParticleVolumes = false;
 	bool renderGrid = true;
 	
 	// Glass is glass and glass breaks...
@@ -619,6 +625,23 @@ int main(int argc, const char **argv) {
 		const uint32_t dispatchSizeGrid [3] = { 16, 16, 16 };
 		const uint32_t dispatchSizeParticles [3] = { static_cast<uint32_t>(particles.getCount() + 63) / 64, 1, 1 };
 		
+		core.recordBeginDebugLabel(cmdStream, "INIT PARTICLE WEIGHTS", { 0.78f, 0.89f, 0.94f, 1.0f });
+		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
+		core.prepareImageForSampling(cmdStream, grid.getHandle());
+		
+		core.recordComputeDispatchToCmdStream(
+				cmdStream,
+				initParticleWeightsPipeline,
+				dispatchSizeParticles,
+				{ vkcv::DescriptorSetUsage(
+						0, core.getDescriptorSet(initParticleWeightsSets[0]).vulkanHandle
+				) },
+				vkcv::PushConstants(0)
+		);
+		
+		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
+		core.recordEndDebugLabel(cmdStream);
+		
 		core.recordBeginDebugLabel(cmdStream, "TRANSFORM PARTICLES TO GRID", { 0.47f, 0.77f, 0.85f, 1.0f });
 		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
 		core.prepareImageForStorage(cmdStream, gridCopy.getHandle());
@@ -636,27 +659,6 @@ int main(int argc, const char **argv) {
 		core.recordImageMemoryBarrier(cmdStream, gridCopy.getHandle());
 		core.recordEndDebugLabel(cmdStream);
 		
-		if (!initializedParticleVolumes) {
-			core.recordBeginDebugLabel(cmdStream, "INIT PARTICLE VOLUMES", { 0.78f, 0.89f, 0.94f, 1.0f });
-			core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
-			core.prepareImageForSampling(cmdStream, gridCopy.getHandle());
-			
-			core.recordComputeDispatchToCmdStream(
-					cmdStream,
-					initParticleVolumesPipeline,
-					dispatchSizeParticles,
-					{ vkcv::DescriptorSetUsage(
-							0, core.getDescriptorSet(initParticleVolumesSets[0]).vulkanHandle
-					) },
-					vkcv::PushConstants(0)
-			);
-			
-			core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
-			core.recordEndDebugLabel(cmdStream);
-			
-			initializedParticleVolumes = true;
-		}
-		
 		core.recordBeginDebugLabel(cmdStream, "UPDATE GRID FORCES", { 0.47f, 0.77f, 0.85f, 1.0f });
 		core.recordBufferMemoryBarrier(cmdStream, particles.getHandle());
 		core.prepareImageForStorage(cmdStream, grid.getHandle());
@@ -834,7 +836,6 @@ int main(int argc, const char **argv) {
 		ImGui::SameLine(0.0f, 10.0f);
 		if (ImGui::Button("Reset##particle_velocity")) {
 			resetParticles(particles, initialVelocity, density, radius);
-			initializedParticleVolumes = false;
 		}
 		
 		ImGui::End();
-- 
GitLab