计算着色器中的计算失败。 HLSL DX11

时间:2016-02-05 17:24:27

标签: directx directx-11 hlsl compute-shader

我是计算着色器的新手,我刚刚开始实现一个Nbody模拟的实现,我遇到了一个我自己无法解决的问题。

这是计算文件中包含的所有内容,入口点是ParticleComputeShader。我只调度1个线程并在着色器中创建1024。我调试和调整时只有1024个粒子,因此每个线程都有自己的粒子来与之相关。

问题似乎是distance != 0.0f,并且计算与距离有关。在我进行检查之前,它将位置返回为1.QNaN,因此它在代码中的某处除以0。我对此的看法是,我使用j错误地访问了StructuredBuffer,并且正在搞砸接下来的几个计算。

另一个注意事项:Position.w是粒子的质量。

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);


}

任何帮助将不胜感激。着色器适用于简单输入 - &gt;当我在任何时候尝试使用比inputConstantParticleData[dispatchThreadID.x]更多的输入缓冲区时,输出才开始出现麻烦。

2 个答案:

答案 0 :(得分:1)

你不能真正在HLSL中设置全局变量。编译器允许它们,因为如果您通过FX使用着色器,那么将通过常量缓冲区为您设置全局变量。很高兴看到你解决了它,只想发布为什么将float定义为局部变量来解决问题。

答案 1 :(得分:0)

此代码的问题在于命名空间变量Constants::BIG_G无法正常工作或使用。将其移到函数内部,只是简单地将其声明为float BIG_G,解决了我遇到的问题。