#pragma kernel InitDust #pragma kernel UpdateDust struct Particle { float3 position; float3 velocity; uint enabled; uint airborne; }; RWStructuredBuffer positions; RWStructuredBuffer particles; RWStructuredBuffer numParticlesConsumed; RWStructuredBuffer freeParticles; uint numParticles; uint particlesToInitialize; float3 particleInitPos; float deltaTime; // float3 attractPos; // float3 xAxis; // float attractRadius; // float attractForce; float3 mop1Pos; float3 mop2Pos; float CleanRadius; float size; float gravity; float particleVel; // Hash function www.cs.ubc.ca/~rbridson/docs/schechter-sca08-turbulence.pdf uint hash(uint state) { state ^= 2747636419u; state *= 2654435769u; state ^= state >> 16; state *= 2654435769u; state ^= state >> 16; state *= 2654435769u; return state; } float scaleToRange01(uint state) { return state / 4294967295.0; } [numthreads(64,1,1)] void InitDust (uint3 id : SV_DispatchThreadID) { if (id.x > particlesToInitialize) { return; } uint i = freeParticles[id.x]; // if (particles[id.x].enabled != 0 || numParticlesInitialized[0] >= numParticles ) { while (i <= numParticles) { if (i == numParticles) { return; } if (particles[i].enabled == 0) { break; } i++; } uint randState = i; randState = hash(randState); float dv = scaleToRange01(randState) * 3.14f*2.0f; float dx = cos(dv); float dy = sin(dv); randState = hash(randState); float dz = scaleToRange01(randState); float3 nvel = float3(dx, dy, dz) * particleVel; randState = hash(randState); nvel.xy *= scaleToRange01(randState); particles[i].velocity = nvel; particles[i].position = particleInitPos; particles[i].position.z = 1; particles[i].enabled = 1; particles[i].airborne = 1; positions[i] = float4(particles[i].position, 1 * size); // particles[i].position = positions[i].xyz; // InterlockedAdd(numParticlesInitialized[0],1); } [numthreads(64,1,1)] void UpdateDust (uint3 id : SV_DispatchThreadID) { uint i = id.x; if (particles[i].enabled == 0) { return; } float3 pos = particles[i].position; if (particles[i].position.z > 0) { particles[i].velocity.z -= gravity * deltaTime; } else { particles[i].velocity -= particles[i].velocity * deltaTime * 15; if (particles[i].airborne == 1) { particles[i].airborne = 0; // Increase splattered particles InterlockedAdd(numParticlesConsumed[1],1); } float3 offset1 = mop1Pos - pos; offset1.z = 0; float dist1 = dot(offset1, offset1); float3 offset2 = mop2Pos - pos; offset2.z = 0; float dist2 = dot(offset2, offset2); float dist = min(dist1, dist2); if (dist < CleanRadius) { particles[i].enabled = 0; // Increase cleaned particles InterlockedAdd(numParticlesConsumed[0],1); } } particles[i].position += particles[i].velocity * deltaTime; positions[i] = float4(particles[i].position, particles[i].enabled * size); }