fgm24/Assets/Scripts/ComputeShaders/BloodCompute.compute

143 lines
2.9 KiB
Plaintext

#pragma kernel InitDust
#pragma kernel UpdateDust
struct Particle {
float3 position;
float3 velocity;
uint enabled;
uint airborne;
};
RWStructuredBuffer<float4> positions;
RWStructuredBuffer<Particle> particles;
RWStructuredBuffer<uint> numParticlesConsumed;
RWStructuredBuffer<uint> freeParticles;
uint numParticles;
uint particlesToInitialize;
float3 particleInitPos;
float3 initialVelocity;
float deltaTime;
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);
randState = hash(randState);
float3 iv = initialVelocity * scaleToRange01(randState);
particles[i].velocity = iv + nvel;
particles[i].position = particleInitPos;
particles[i].position.z = 0.01;
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);
}