计算着色器中的计算失败。华龙DX11

Calculation failing in the compute shader. HLSL DX11

我对计算着色器还很陌生,我刚刚开始实施一个用于 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);


}

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

这段代码的问题是命名空间变量 Constants::BIG_G 没有工作或没有被正确使用。将其移动到函数内部并简单地将其声明为 float BIG_G 解决了我遇到的问题。

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