我是計算着色器的新手,我剛剛開始爲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個線程」。我現在明白了。 –