2016-02-05 70 views
0

我是計算着色器的新手,我剛剛開始爲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]更多的輸入緩衝區時,纔開始給出麻煩。

+0

你說你調度時只調度一個線程,但爲什麼是numthreads(1024,1,1)如果是這種情況? –

+0

我以爲你可以調度1,並在着色器本身內創建1024個線程。我認爲這些價值觀是獨立的。我可能歪曲了我的意思;我只調度1個實例(1,1,1),但我有着色器運行1024(1024,1,1)線程。如果這不是它的工作原理,我很樂意聽到更多,但這就是我解讀MSDN文檔的方式。 – DHudson

+0

你是對的,儘管在最初的問題中正確的術語應該是「我只調度1個線程組」,而不是「1個線程」。我現在明白了。 –

回答

0

此代碼的問題在於名稱空間變量Constants::BIG_G未能正常工作或正在被正確使用。將它移到函數的內部,只需簡單地將其聲明爲float BIG_G即可解決我遇到的問題。

1

你不能真的在HLSL中設置全局變量。編譯器允許它們,因爲如果你通過FX使用着色器,那將通過常量緩衝區爲你設置全局變量。很高興看到你解決了這個問題,只想發帖爲什麼將浮點數定義爲局部變量解決了問題。