Search code examples
directxdirectx-11hlslcompute-shader

Calculation failing in the compute shader. HLSL DX11


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.


Solution

  • The problem with this code was that the Namespace variable Constants::BIG_G was not working or being used correctly. Moving this to inside of the function and just declaring it simply as float BIG_G fixed the problems I was having.