2024-02-03 12:22:55 +01:00
|
|
|
#pragma kernel InitDust
|
|
|
|
#pragma kernel UpdateDust
|
|
|
|
|
|
|
|
struct Particle {
|
|
|
|
float3 position;
|
|
|
|
float3 velocity;
|
|
|
|
uint enabled;
|
2024-02-03 13:32:30 +01:00
|
|
|
uint airborne;
|
2024-02-03 12:22:55 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
RWStructuredBuffer<float4> positions;
|
|
|
|
RWStructuredBuffer<Particle> particles;
|
|
|
|
RWStructuredBuffer<uint> numParticlesConsumed;
|
|
|
|
RWStructuredBuffer<uint> 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;
|
2024-02-03 22:18:28 +01:00
|
|
|
particles[i].position.z = 0.01;
|
2024-02-03 12:22:55 +01:00
|
|
|
particles[i].enabled = 1;
|
2024-02-03 13:32:30 +01:00
|
|
|
particles[i].airborne = 1;
|
2024-02-03 12:22:55 +01:00
|
|
|
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;
|
|
|
|
|
2024-02-03 13:32:30 +01:00
|
|
|
if (particles[i].airborne == 1) {
|
|
|
|
particles[i].airborne = 0;
|
|
|
|
|
|
|
|
// Increase splattered particles
|
|
|
|
InterlockedAdd(numParticlesConsumed[1],1);
|
|
|
|
}
|
2024-02-03 12:22:55 +01:00
|
|
|
|
|
|
|
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;
|
2024-02-03 13:32:30 +01:00
|
|
|
// Increase cleaned particles
|
2024-02-03 12:22:55 +01:00
|
|
|
InterlockedAdd(numParticlesConsumed[0],1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
particles[i].position += particles[i].velocity * deltaTime;
|
|
|
|
positions[i] = float4(particles[i].position, particles[i].enabled * size);
|
|
|
|
}
|
|
|
|
|