计算着色器中的计算失败。华龙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 为什么 将浮点数定义为局部变量解决了这个问题。
我对计算着色器还很陌生,我刚刚开始实施一个用于 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 为什么 将浮点数定义为局部变量解决了这个问题。