From d6752ceb3ca7b05c384f3c330dddf73bb41bdb56 Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Mon, 31 Jan 2022 01:14:04 +0100 Subject: [PATCH] Adjusted shaders to fix deformation Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- projects/wobble_bobble/shaders/grid.frag | 2 +- projects/wobble_bobble/shaders/particle.inc | 18 ++++---- .../shaders/transform_particles_to_grid.comp | 11 ++++- .../shaders/update_grid_forces.comp | 42 ++++++++++------- .../shaders/update_particle_deformation.comp | 46 +++++++++++++------ .../shaders/update_particle_velocities.comp | 11 +++-- projects/wobble_bobble/src/main.cpp | 30 ++++++++++-- 7 files changed, 109 insertions(+), 51 deletions(-) diff --git a/projects/wobble_bobble/shaders/grid.frag b/projects/wobble_bobble/shaders/grid.frag index 00c405d1..c3dc1fb2 100644 --- a/projects/wobble_bobble/shaders/grid.frag +++ b/projects/wobble_bobble/shaders/grid.frag @@ -19,7 +19,7 @@ void main() { vec3 surface = vec3(passPos.x + 0.5f, passPos.y + 0.5f, z * 2.0f); vec3 velocity = vec3(0.5f) + 0.5f * normalize(passVelocity.xyz); - outColor = surface; + outColor = velocity; } else { discard; } diff --git a/projects/wobble_bobble/shaders/particle.inc b/projects/wobble_bobble/shaders/particle.inc index 6ce314ab..ae584f1a 100644 --- a/projects/wobble_bobble/shaders/particle.inc +++ b/projects/wobble_bobble/shaders/particle.inc @@ -41,14 +41,14 @@ float weight_C(float x) { } } -float voxel_particle_weight(vec3 voxel, ParticleMinimal particle) { +vec3 voxel_particle_weight(vec3 voxel, ParticleMinimal particle) { if (particle.size <= 0.0f) { - return 0.0f; + return vec3(0.0f); } vec3 delta = abs(particle.position - voxel) / particle.size; - return weight_C(delta.x) * weight_C(delta.y) * weight_C(delta.z); + return vec3(weight_C(delta.x), weight_C(delta.y), weight_C(delta.z)); } float grad_weight_A(float x) { @@ -78,9 +78,9 @@ float grad_weight_C(float x) { } } -float voxel_particle_grad_weight(vec3 voxel, ParticleMinimal particle) { +vec3 voxel_particle_grad_weight(vec3 voxel, ParticleMinimal particle) { if (particle.size <= 0.0f) { - return 0.0f; + return vec3(0.0f); } vec3 sign_delta = (particle.position - voxel) / particle.size; @@ -88,12 +88,12 @@ float voxel_particle_grad_weight(vec3 voxel, ParticleMinimal particle) { vec3 sign = sign(sign_delta); vec3 weight = vec3( - weight_C(delta.x), - weight_C(delta.y), - weight_C(delta.z) + grad_weight_C(delta.x), + grad_weight_C(delta.y), + grad_weight_C(delta.z) ); - return dot(weight, sign); + return weight * sign; } #endif // PARTICLE_INC \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/transform_particles_to_grid.comp b/projects/wobble_bobble/shaders/transform_particles_to_grid.comp index bfd902b5..d582986d 100644 --- a/projects/wobble_bobble/shaders/transform_particles_to_grid.comp +++ b/projects/wobble_bobble/shaders/transform_particles_to_grid.comp @@ -10,6 +10,7 @@ layout(set=0, binding=0, std430) buffer particleBuffer { }; layout(set=0, binding=1, rgba32f) restrict writeonly uniform image3D gridImage; +layout(set=0, binding=2, rgba32f) restrict writeonly uniform image3D gridCopyImage; #define SHARED_PARTICLES_BATCH_SIZE 64 @@ -38,9 +39,11 @@ void main() { memoryBarrierShared(); for (uint i = 0; i < SHARED_PARTICLES_BATCH_SIZE; i++) { + vec3 weight = voxel_particle_weight(position, shared_particles[i]); + gridValue += ( vec4(shared_particles[i].velocity, shared_particles[i].mass) * - voxel_particle_weight(position, shared_particles[i]) + weight.x * weight.y * weight.z ); } } @@ -51,5 +54,11 @@ void main() { gridValue ); + imageStore( + gridCopyImage, + ivec3(gl_GlobalInvocationID), + gridValue + ); + memoryBarrierImage(); } \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/update_grid_forces.comp b/projects/wobble_bobble/shaders/update_grid_forces.comp index 752c3eff..4ea302e7 100644 --- a/projects/wobble_bobble/shaders/update_grid_forces.comp +++ b/projects/wobble_bobble/shaders/update_grid_forces.comp @@ -7,8 +7,9 @@ layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in; #include "particle.inc" -layout(set=0, binding=0, rgba32f) uniform image3D gridImage; -layout(set=0, binding=1, std430) buffer particleBuffer { +layout(set=0, binding=0, rgba32f) restrict readonly uniform image3D gridImage; +layout(set=0, binding=1, rgba32f) restrict writeonly uniform image3D gridForceImage; +layout(set=0, binding=2, std430) buffer particleBuffer { Particle particles []; }; @@ -23,7 +24,7 @@ shared Particle shared_particles [SHARED_PARTICLES_BATCH_SIZE]; void main() { const vec3 position = (vec3(gl_GlobalInvocationID) + vec3(0.5f)) / imageSize(gridImage); - const float elasticity_module = 1200.5f * 1000000.0f; // 10..15 = Wood + const float elasticity_module = 2.5f * 1000000.0f; // 10..15 = Wood memoryBarrierImage(); @@ -60,23 +61,30 @@ void main() { float volume = 4.0f / 3.0f * PI * size * size * size; mat3 deformation = mat3(shared_particles[gl_LocalInvocationIndex].deformation); - mat3 epsilon = deformation - mat3(1.0f); - mat3 delta = elasticity_module * epsilon; - mat3 delta_cauchy = determinant(deformation) * delta * inverse(transpose(deformation)); + float J = determinant(deformation); - vec3 weight_gradient = vec3( - voxel_particle_grad_weight(position, shared_particles[gl_LocalInvocationIndex].minimal) - ); + if ((abs(J) > 0.0f) && (volume > 0.0f)) { + mat3 epsilon = deformation - mat3(1.0f); + mat3 delta = elasticity_module * epsilon; + mat3 delta_cauchy = J * delta * inverse(transpose(deformation)); - force -= ( - volume * - delta_cauchy * - weight_gradient - ); + vec3 weight_gradient = voxel_particle_grad_weight( + position, + shared_particles[gl_LocalInvocationIndex].minimal + ); + + force -= ( + volume * + delta_cauchy * + weight_gradient + ); + } } } - velocity += force * dt / mass; + if (mass > 0.0f) { + velocity += force * dt / mass; + } bvec3 lowerID = lessThanEqual(gl_GlobalInvocationID, ivec3(0)); bvec3 negativeVelocity = lessThan(velocity, vec3(0.0f)); @@ -90,10 +98,10 @@ void main() { (lowerID.z && negativeVelocity.z) || (greaterID.z && positiveVelocity.z) ); - velocity = mix(velocity, -velocity, invert) - gridSample.xyz; + velocity = mix(velocity, -velocity, invert); imageStore( - gridImage, + gridForceImage, ivec3(gl_GlobalInvocationID), vec4(velocity, mass) ); diff --git a/projects/wobble_bobble/shaders/update_particle_deformation.comp b/projects/wobble_bobble/shaders/update_particle_deformation.comp index 7bfc923b..9711d48a 100644 --- a/projects/wobble_bobble/shaders/update_particle_deformation.comp +++ b/projects/wobble_bobble/shaders/update_particle_deformation.comp @@ -9,30 +9,46 @@ layout(set=0, binding=0, std430) buffer particleBuffer { Particle particles []; }; -layout(set=0, binding=1) uniform texture3D gridTextureIn; +layout(set=0, binding=1) uniform texture3D gridImage; layout(set=0, binding=2) uniform sampler gridSampler; -layout( push_constant ) uniform constants { - float t; - float dt; -}; - void main() { memoryBarrierBuffer(); memoryBarrierImage(); - ParticleMinimal particle = particles[gl_GlobalInvocationID.x].minimal; - mat3 deformation = mat3(particles[gl_GlobalInvocationID.x].deformation); + if (gl_GlobalInvocationID.x < particles.length()) { + ParticleMinimal minimal = particles[gl_GlobalInvocationID.x].minimal; + mat3 deformation = mat3(particles[gl_GlobalInvocationID.x].deformation); + + ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0); + ivec3 gridWindow = ivec3(minimal.size * 2.0f * gridResolution); + + mat3 velocity_gradient = mat3(0.0f); + + uint i, j, k; + + for (i = -gridWindow.x; i <= gridWindow.x; i++) { + for (j = -gridWindow.y; j <= gridWindow.y; j++) { + for (k = -gridWindow.z; k <= gridWindow.z; k++) { + vec3 offset = vec3(i, j, k) / gridResolution; + vec3 voxel = minimal.position + offset; + + if (length(offset) < minimal.size * 2.0f) { + vec4 gridSample = texture(sampler3D(gridImage, gridSampler), voxel); - mat3 grad_velocity = mat3( - textureGrad(sampler3D(gridTextureIn, gridSampler), particle.position, vec3(1.0f, 0.0f, 0.0f), vec3(0.0f)).xyz, - textureGrad(sampler3D(gridTextureIn, gridSampler), particle.position, vec3(0.0f, 1.0f, 0.0f), vec3(0.0f)).xyz, - textureGrad(sampler3D(gridTextureIn, gridSampler), particle.position, vec3(0.0f, 0.0f, 1.0f), vec3(0.0f)).xyz - ); + velocity_gradient += outerProduct( + gridSample.xyz, + voxel_particle_grad_weight(voxel, minimal) + ); + } + } + } + } - mat3 deformation_elastic = (mat3(1.0f) + grad_velocity * dt) * deformation; + mat3 deformation_elastic = (mat3(1.0f) + velocity_gradient) * deformation; - particles[gl_GlobalInvocationID.x].deformation = mat4(deformation_elastic); + particles[gl_GlobalInvocationID.x].deformation = mat4(deformation_elastic); + } memoryBarrierBuffer(); } \ No newline at end of file diff --git a/projects/wobble_bobble/shaders/update_particle_velocities.comp b/projects/wobble_bobble/shaders/update_particle_velocities.comp index 2c4f9e4f..123ac83a 100644 --- a/projects/wobble_bobble/shaders/update_particle_velocities.comp +++ b/projects/wobble_bobble/shaders/update_particle_velocities.comp @@ -10,7 +10,8 @@ layout(set=0, binding=0, std430) buffer particleBuffer { }; layout(set=0, binding=1) uniform texture3D gridImage; -layout(set=0, binding=2) uniform sampler gridSampler; +layout(set=0, binding=2) uniform texture3D gridOldImage; +layout(set=0, binding=3) uniform sampler gridSampler; void main() { memoryBarrierBuffer(); @@ -20,7 +21,7 @@ void main() { ParticleMinimal minimal = particles[gl_GlobalInvocationID.x].minimal; ivec3 gridResolution = textureSize(sampler3D(gridImage, gridSampler), 0); - ivec3 gridWindow = ivec3(minimal.size * 4.0f * gridResolution); + ivec3 gridWindow = ivec3(minimal.size * 2.0f * gridResolution); vec3 velocity = vec3(minimal.velocity); @@ -34,7 +35,11 @@ void main() { if (length(offset) < minimal.size * 2.0f) { vec4 gridSample = texture(sampler3D(gridImage, gridSampler), voxel); - velocity += voxel_particle_weight(voxel, minimal) * gridSample.xyz; + vec4 gridOldSample = texture(sampler3D(gridOldImage, gridSampler), voxel); + + vec3 weight = voxel_particle_weight(voxel, minimal); + + velocity += (weight.x * weight.y * weight.z) * (gridSample.xyz - gridOldSample.xyz); } } } diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp index b7ab85c6..f386cc15 100644 --- a/projects/wobble_bobble/src/main.cpp +++ b/projects/wobble_bobble/src/main.cpp @@ -40,7 +40,7 @@ void distributeParticles(Particle *particles, size_t count, const glm::vec3& cen particles[i].position = center + offset; particles[i].size = size; - particles[i].velocity = glm::vec3(0.0f, 1.0f, 0.0f); + particles[i].velocity = glm::vec3(0.0f, 0.1f, 0.0f); volume += size; } @@ -153,6 +153,17 @@ int main(int argc, const char **argv) { grid.switchLayout(vk::ImageLayout::eGeneral); + vkcv::Image gridCopy = core.createImage( + grid.getFormat(), + grid.getWidth(), + grid.getHeight(), + grid.getDepth(), + false, + true + ); + + gridCopy.switchLayout(vk::ImageLayout::eGeneral); + /* TODO: clear grid via compute shader? std::vector<glm::vec4> grid_vec (grid.getWidth() * grid.getHeight() * grid.getDepth()); @@ -185,6 +196,7 @@ int main(int argc, const char **argv) { vkcv::DescriptorWrites writes; writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particles.getHandle())); writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(1, grid.getHandle())); + writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(2, gridCopy.getHandle())); core.writeDescriptorSet(transformParticlesToGridSets[0], writes); } @@ -210,8 +222,9 @@ int main(int argc, const char **argv) { { vkcv::DescriptorWrites writes; - writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(0, grid.getHandle())); - writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(1, particles.getHandle())); + writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(0, gridCopy.getHandle())); + writes.storageImageWrites.push_back(vkcv::StorageImageDescriptorWrite(1, grid.getHandle())); + writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(2, particles.getHandle())); core.writeDescriptorSet(updateGridForcesSets[0], writes); } @@ -241,7 +254,8 @@ int main(int argc, const char **argv) { vkcv::DescriptorWrites writes; writes.storageBufferWrites.push_back(vkcv::BufferDescriptorWrite(0, particles.getHandle())); writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(1, grid.getHandle())); - writes.samplerWrites.push_back(vkcv::SamplerDescriptorWrite(2, gridSampler)); + writes.sampledImageWrites.push_back(vkcv::SampledImageDescriptorWrite(2, gridCopy.getHandle())); + writes.samplerWrites.push_back(vkcv::SamplerDescriptorWrite(3, gridSampler)); core.writeDescriptorSet(updateParticleVelocitiesSets[0], writes); } @@ -467,6 +481,7 @@ int main(int argc, const char **argv) { core.recordBeginDebugLabel(cmdStream, "TRANSFORM PARTICLES TO GRID", { 0.47f, 0.77f, 0.85f, 1.0f }); core.prepareImageForStorage(cmdStream, grid.getHandle()); + core.prepareImageForStorage(cmdStream, gridCopy.getHandle()); core.recordComputeDispatchToCmdStream( cmdStream, @@ -479,6 +494,7 @@ int main(int argc, const char **argv) { ); core.recordImageMemoryBarrier(cmdStream, grid.getHandle()); + core.recordImageMemoryBarrier(cmdStream, gridCopy.getHandle()); core.recordEndDebugLabel(cmdStream); if (!initializedParticleVolumes) { @@ -508,6 +524,8 @@ int main(int argc, const char **argv) { ) }, timePushConstants ); + + core.recordImageMemoryBarrier(cmdStream, grid.getHandle()); core.recordEndDebugLabel(cmdStream); core.recordBeginDebugLabel(cmdStream, "UPDATE PARTICLE DEFORMATION", { 0.78f, 0.89f, 0.94f, 1.0f }); @@ -520,13 +538,15 @@ int main(int argc, const char **argv) { { vkcv::DescriptorSetUsage( 0, core.getDescriptorSet(updateParticleDeformationSets[0]).vulkanHandle ) }, - timePushConstants + vkcv::PushConstants(0) ); core.recordBufferMemoryBarrier(cmdStream, particles.getHandle()); core.recordEndDebugLabel(cmdStream); core.recordBeginDebugLabel(cmdStream, "UPDATE PARTICLE VELOCITIES", { 0.78f, 0.89f, 0.94f, 1.0f }); + core.prepareImageForSampling(cmdStream, gridCopy.getHandle()); + core.recordComputeDispatchToCmdStream( cmdStream, updateParticleVelocitiesPipeline, -- GitLab