我是计算着色器的新手,我刚刚开始为Nbody模拟实现一个,我遇到了一个我自己无法解决的问题。计算着色器中的计算失败。 HLSL DX11
以下是计算文件中包含的所有内容,入口点是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]
更多的输入缓冲区时,才开始给出麻烦。
你说你调度时只调度一个线程,但为什么是numthreads(1024,1,1)如果是这种情况? –
我以为你可以调度1,并在着色器本身内创建1024个线程。我认为这些价值观是独立的。我可能歪曲了我的意思;我只调度1个实例(1,1,1),但我有着色器运行1024(1024,1,1)线程。如果这不是它的工作原理,我很乐意听到更多,但这就是我解读MSDN文档的方式。 – DHudson
你是对的,尽管在最初的问题中正确的术语应该是“我只调度1个线程组”,而不是“1个线程”。我现在明白了。 –