我是计算着色器的新手,我刚刚开始实现一个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]
更多的输入缓冲区时,输出才开始出现麻烦。
答案 0 :(得分:1)
你不能真正在HLSL中设置全局变量。编译器允许它们,因为如果您通过FX使用着色器,那么将通过常量缓冲区为您设置全局变量。很高兴看到你解决了它,只想发布为什么将float定义为局部变量来解决问题。
答案 1 :(得分:0)
此代码的问题在于命名空间变量Constants::BIG_G
无法正常工作或使用。将其移到函数内部,只是简单地将其声明为float BIG_G
,解决了我遇到的问题。