I'm fairly new to compute shaders and I've just started an implementation of one for an Nbody simulation and I've come across a problem that I can't solve on my own.
Here's everything that is contained in the compute file and the entry point is ParticleComputeShader. I am only dispatching 1 thread and creating 1024 in the shader. There are only 1024 particles while I debug and tweak it so each thread has it's own particle to relate to.
The problem seems to be distance != 0.0f
and the calculation related to the distance. Before I had the check in it was returning the position as 1.QNaN so it was dividing by 0 somewhere in the code. My thoughts on this is that I'm incorrectly accessing the StructuredBuffer using j
and it's screwing up the next few calculations.
Another note: Position.w is the mass of the particle.
struct ConstantParticleData
{
float4 position;
float4 velocity;
};
struct ParticleData
{
float4 position;
float4 velocity;
};
namespace Constants
{
float BIG_G = 6.674e-11f;
float SOFTEN = 0.01f;
}
StructuredBuffer<ConstantParticleData> inputConstantParticleData : register( t0 );
RWStructuredBuffer<ParticleData> outputParticleData : register( u0 );
[numthreads(1024, 1, 1)]
void ParticleComputeShader( int3 dispatchThreadID : SV_DispatchThreadID )
{
float3 acceleration = float3(0.0f, 0.0f, 0.0f);
for(int j = 0; j < 1024; j++)
{
float3 r_ij;
r_ij.x = inputConstantParticleData[j].position.x - inputConstantParticleData[dispatchThreadID.x].position.x;
r_ij.y = inputConstantParticleData[j].position.y - inputConstantParticleData[dispatchThreadID.x].position.y;
r_ij.z = inputConstantParticleData[j].position.z - inputConstantParticleData[dispatchThreadID.x].position.z;
float distance = 0.0f;
distance = length(r_ij);
if(distance != 0.0f)
{
float bottomLine = pow(distance, 2) + pow(Constants::SOFTEN, 2);
acceleration += Constants::BIG_G * ((inputConstantParticleData[j].position.w * r_ij) /
pow(bottomLine, 1.5));
}
}
acceleration = acceleration / inputConstantParticleData[dispatchThreadID.x].position.w;
outputParticleData[dispatchThreadID.x].velocity = inputConstantParticleData[dispatchThreadID.x].velocity +
float4(acceleration.x, acceleration.y, acceleration.z, 0.0f);
outputParticleData[dispatchThreadID.x].position = inputConstantParticleData[dispatchThreadID.x].position +
float4(outputParticleData[dispatchThreadID.x].velocity.x,
outputParticleData[dispatchThreadID.x].velocity.y,
outputParticleData[dispatchThreadID.x].velocity.z,
0.0f);
}
Any help will be appreciated. The shader works for simple input -> output and only started to begin giving troubles when I tried to use more of the input buffer than inputConstantParticleData[dispatchThreadID.x]
at any one time.