Skip to content
Snippets Groups Projects
update_particle_deformation.comp 1.87 KiB
#version 450
#extension GL_GOOGLE_include_directive : enable

layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;

#include "particle.inc"

layout(set=0, binding=0, std430) restrict buffer particleBuffer {
    Particle particles [];
};

layout(set=0, binding=1) uniform texture3D gridImage;
layout(set=0, binding=2) uniform sampler gridSampler;

layout( push_constant ) uniform constants {
    float K;
    float E;
    float t;
    float dt;
};

void main()	{
    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);

        int 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;

                    vec4 gridSample = texture(sampler3D(gridImage, gridSampler), voxel);

                    velocity_gradient += outerProduct(
                        gridSample.xyz,
                        voxel_particle_grad_weight(voxel, minimal)
                    );
                }
            }
        }

        barrier();
        memoryBarrierBuffer();

        mat3 deformation_elastic = deformation;

        if (dt > 0.0f) {
            deformation_elastic = (mat3(1.0f) + dt * velocity_gradient) * deformation;
        }

        barrier();
        memoryBarrierBuffer();

        particles[gl_GlobalInvocationID.x].deformation = mat4(deformation_elastic);
    }
}