diff --git a/projects/sph/shaders/force.comp b/projects/sph/shaders/force.comp index 6d5f31d2a8b2e1774c6ee7d091085226e1eacabb..694ddbdf7009d4e493a5f8dd8ba462e42d1e8b68 100644 --- a/projects/sph/shaders/force.comp +++ b/projects/sph/shaders/force.comp @@ -67,17 +67,20 @@ shared ParticleData particle_data [256]; void main() { uint id = gl_GlobalInvocationID.x; - if(id >= int(particleCount)) - { - return; + if (id >= int(particleCount)) { + particle_data[gl_LocalInvocationIndex].position = vec3(0.0f); + particle_data[gl_LocalInvocationIndex].density = 0.0f; + particle_data[gl_LocalInvocationIndex].velocity = vec3(0.0f); + particle_data[gl_LocalInvocationIndex].pressure = 0.0f; + } else { + particle_data[gl_LocalInvocationIndex].position = inParticle[id].position; + particle_data[gl_LocalInvocationIndex].density = inParticle[id].density; + particle_data[gl_LocalInvocationIndex].velocity = inParticle[id].velocity; + particle_data[gl_LocalInvocationIndex].pressure = inParticle[id].pressure; } uint index_offset = gl_WorkGroupID.x * gl_WorkGroupSize.x; - - particle_data[gl_LocalInvocationIndex].position = inParticle[id].position; - particle_data[gl_LocalInvocationIndex].density = inParticle[id].density; - particle_data[gl_LocalInvocationIndex].velocity = inParticle[id].velocity; - particle_data[gl_LocalInvocationIndex].pressure = inParticle[id].pressure; + uint group_size = min(index_offset + gl_WorkGroupSize.x, int(particleCount)) - index_offset; memoryBarrierShared(); barrier(); @@ -85,8 +88,8 @@ void main() { const float h6 = pow(h, 6); externalForce = particle_data[gl_LocalInvocationIndex].density * gravity * vec3(-gravityDir.x,gravityDir.y,gravityDir.z); - for(uint j = 1; j < gl_WorkGroupSize.x; j++) { - uint i = (gl_LocalInvocationIndex + j) % gl_WorkGroupSize.x; + for(uint j = 1; j < group_size; j++) { + uint i = (gl_LocalInvocationIndex + j) % group_size; vec3 dir = particle_data[gl_LocalInvocationIndex].position - particle_data[i].position; float dist = length(dir); @@ -120,7 +123,7 @@ void main() { } } - for(uint i = index_offset + gl_WorkGroupSize.x; i < int(particleCount); i++) + for(uint i = index_offset + group_size; i < int(particleCount); i++) { vec3 dir = particle_data[gl_LocalInvocationIndex].position - inParticle[i].position; float dist = length(dir); @@ -139,9 +142,11 @@ void main() { viscosityForce *= viscosity; - outParticle[id].force = externalForce + pressureForce + viscosityForce; - outParticle[id].density = particle_data[gl_LocalInvocationIndex].density; - outParticle[id].pressure = particle_data[gl_LocalInvocationIndex].pressure; - outParticle[id].position = particle_data[gl_LocalInvocationIndex].position; - outParticle[id].velocity = particle_data[gl_LocalInvocationIndex].velocity; + if (id < int(particleCount)) { + outParticle[id].force = externalForce + pressureForce + viscosityForce; + outParticle[id].density = particle_data[gl_LocalInvocationIndex].density; + outParticle[id].pressure = particle_data[gl_LocalInvocationIndex].pressure; + outParticle[id].position = particle_data[gl_LocalInvocationIndex].position; + outParticle[id].velocity = particle_data[gl_LocalInvocationIndex].velocity; + } } diff --git a/projects/sph/shaders/pressure.comp b/projects/sph/shaders/pressure.comp index 903da585a0b527fbd35df6bb0c6abcfa052ad3e4..8fa2e4762bddb3b9b28d8a3c184ceaaf7ab4421c 100644 --- a/projects/sph/shaders/pressure.comp +++ b/projects/sph/shaders/pressure.comp @@ -53,20 +53,20 @@ void main() { uint id = gl_GlobalInvocationID.x; - if(id >= int(particleCount)) - { - return; + if (id >= int(particleCount)) { + position_data[gl_LocalInvocationIndex] = vec3(0.0f); + } else { + position_data[gl_LocalInvocationIndex] = inParticle[id].position; } uint index_offset = gl_WorkGroupID.x * gl_WorkGroupSize.x; - - position_data[gl_LocalInvocationIndex] = inParticle[id].position; + uint group_size = min(index_offset + gl_WorkGroupSize.x, int(particleCount)) - index_offset; memoryBarrierShared(); barrier(); - for(uint j = 1; j < gl_WorkGroupSize.x; j++) { - uint i = (gl_LocalInvocationIndex + j) % gl_WorkGroupSize.x; + for(uint j = 1; j < group_size; j++) { + uint i = (gl_LocalInvocationIndex + j) % group_size; float dist = distance(position_data[gl_LocalInvocationIndex], position_data[i]); densitySum += mass * poly6(dist); @@ -78,15 +78,17 @@ void main() { densitySum += mass * poly6(dist); } - for(uint i = index_offset + gl_WorkGroupSize.x; i < int(particleCount); i++) + for(uint i = index_offset + group_size; i < int(particleCount); i++) { float dist = distance(position_data[gl_LocalInvocationIndex], inParticle[i].position); densitySum += mass * poly6(dist); } - outParticle[id].density = max(densitySum,0.0000001f); - outParticle[id].pressure = max((densitySum - offset), 0.0000001f) * gasConstant; - outParticle[id].position = position_data[gl_LocalInvocationIndex]; - outParticle[id].velocity = inParticle[id].velocity; - outParticle[id].force = inParticle[id].force; + if (id < int(particleCount)) { + outParticle[id].density = max(densitySum, 0.0000001f); + outParticle[id].pressure = max((densitySum - offset), 0.0000001f) * gasConstant; + outParticle[id].position = position_data[gl_LocalInvocationIndex]; + outParticle[id].velocity = inParticle[id].velocity; + outParticle[id].force = inParticle[id].force; + } }