2
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

95 lines
3.2 KiB
Plaintext

2 years ago
#pragma kernel Advect
#pragma kernel AddParticles
#include "FLUID_DYNAMICS_MAIN.compute"
RWStructuredBuffer<float> _ParticlesIn;
RWStructuredBuffer<float> _ParticlesOut;
float _Radius;
float2 _Position;
float _Value;
const uint2 _ParticleSize;
[numthreads(THREAD_COUNT, THREAD_COUNT, 1)]
void AddParticles(uint3 id : SV_DispatchThreadID)
{
if (id.x >= _ParticleSize.x || id.y >= _ParticleSize.y) { return; }
const uint pos = id.y*_ParticleSize.x + id.x;
const float2 splat_pos = _Position*_ParticleSize;
const float val = _ParticlesIn[pos];
float result = val;
float len = distance(splat_pos, (float2) id);
if (len <= _Radius)
{
result = clamp(val + _Value*(_Radius - len) / _Radius, 0.0f, 255.0f);
}
_ParticlesOut[pos] = result;
}
RWStructuredBuffer<float2> _Velocity;
RWStructuredBuffer<float2> _Obstacles;
const uint2 _VelocitySize;
float _Dissipation;
float _ElapsedTime;
float _Speed;
float2 GetVelocity(float2 fPos)
{
const int2 zero = int2(0, 0);
const int2 SizeBounds = int2(_VelocitySize.x - 1, _VelocitySize.y - 1);
const int2 top_right = clamp(ceil(fPos), zero, SizeBounds);
const int2 bottom_left = clamp(floor(fPos), zero, SizeBounds);
const float2 delta = fPos - bottom_left;
const float2 lt = _Velocity[top_right.y*_VelocitySize.x + bottom_left.x];
const float2 rt = _Velocity[top_right.y*_VelocitySize.x + top_right.x];
const float2 lb = _Velocity[bottom_left.y*_VelocitySize.x + bottom_left.x];
const float2 rb = _Velocity[bottom_left.y*_VelocitySize.x + top_right.x];
const float2 h1 = lerp(lt, rt, delta.x);
const float2 h2 = lerp(lb, rb, delta.x);
return lerp(h2, h1, delta.y) * (_ParticleSize / (float2)_VelocitySize);
}
[numthreads(THREAD_COUNT, THREAD_COUNT, 1)]
void Advect(uint3 id : SV_DispatchThreadID)
{
if (id.x >= _ParticleSize.x || id.y >= _ParticleSize.y) { return; }
const uint particle_pos = id.y*_ParticleSize.x + id.x;
const float2 fNormalisedPos = float2(id.x / (float)_ParticleSize.x, id.y / (float)_ParticleSize.y) * _VelocitySize;
const uint obstacle_pos = ((uint)fNormalisedPos.y)*_VelocitySize.x + ((uint)fNormalisedPos.x);
const float2 obstacle = _Obstacles[obstacle_pos];
if (obstacle.x > 0.0 || obstacle.y > 0.0)
{
_ParticlesOut[particle_pos] = 0.0;
}
else
{
const float2 vel = GetVelocity(fNormalisedPos);
const float2 final_pos = float2(id.x - vel.x*_ElapsedTime*_Speed, id.y - vel.y*_ElapsedTime*_Speed);
const int2 zero = int2(0, 0);
const int2 SizeBounds = int2(_ParticleSize.x - 1, _ParticleSize.y - 1);
const int2 top_right = clamp(ceil(final_pos), zero, SizeBounds);
const int2 bottom_left = clamp(floor(final_pos), zero, SizeBounds);
const float2 delta = final_pos - bottom_left;
const float lt = _ParticlesIn[top_right.y*_ParticleSize.x + bottom_left.x];
const float rt = _ParticlesIn[top_right.y*_ParticleSize.x + top_right.x];
const float lb = _ParticlesIn[bottom_left.y*_ParticleSize.x + bottom_left.x];
const float rb = _ParticlesIn[bottom_left.y*_ParticleSize.x + top_right.x];
const float h1 = lerp(lt, rt, delta.x);
const float h2 = lerp(lb, rb, delta.x);
_ParticlesOut[particle_pos] = lerp(h2, h1, delta.y) * _Dissipation;
}
}