2017-03-08 29 views
1

Unity3D與ComputeShader存在問題。具有錯誤(不一致的值)的計算着色器的輸出

我的目標:找到所面臨的相機(二矢量的點> 0)

由於我的相機和我的模式是固定的所有法線,我希望得到永遠的正常等量我的計算着色器的輸出。但是,每次使用計算着色器時,計數都會增加,導致我面對攝像機的許多法線優於網格中的數字,並且它很快達到我有10e9個法線的點。有時這個值是負值。

我爲此使用了一個附加緩衝區,而我的hlsh只測試該點,並將該值附加到緩衝區。

我的問題是:問題在哪裏?

我懷疑與GPU內存有問題,但我找不到爲什麼(首次HLSL/unity3)

C#: 注:關鍵是另一個測試

public static Vector3[] KeyCam(Vector3 key, Vector3 cam, Vector3[] normal) { 
ComputeShader shader = (ComputeShader) Resources.Load("ComputeShader/Normal"); 
int _kernel = shader.FindKernel("KeyCam"); 

#region init Buffer 
ComputeBuffer inputBuffer = new ComputeBuffer(normal.Length, sizeof(float) * 3); 
inputBuffer.SetData(normal); 
ComputeBuffer outputBuffer = new ComputeBuffer(normal.Length, sizeof(float) * 3, ComputeBufferType.Append); 
#endregion 

#region set 
shader.SetBuffer(_kernel, "input", inputBuffer); 
shader.SetBuffer(_kernel, "output", outputBuffer); 
shader.SetVector("key", key); 
shader.SetVector("cam", cam); 
#endregion 

shader.Dispatch(_kernel, 1, 1, 1); 

#region get count 
//https://sites.google.com/site/aliadevlog/counting-buffers-in-directcompute 
ComputeBuffer countBuffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.IndirectArguments); 
ComputeBuffer.CopyCount(outputBuffer, countBuffer, 0); 

//Debug.Log("Copy buffer : " + countBuffer.count); 
int[] counter = new int[1] { 0 }; 
countBuffer.GetData(counter); 
countBuffer.Release(); 
int c = counter[0]; 
#endregion 

//int c = GetAppendCount(outputBuffer); 
Debug.Log("Normals : " + c +"/"+normal.Length); 
if(c <= 0) 
    return null; 

Vector3[] output = new Vector3[c]; 
outputBuffer.GetData(output); 

inputBuffer.Release(); 
outputBuffer.Release(); 

return output; 
    } 

HLSL:

#pragma kernel KeyCam 
StructuredBuffer<float3> input; 
float3 key; 
float3 cam; 
AppendStructuredBuffer<float3> output; 

[numthreads(64,1,1)] 
void KeyCam(uint3 id : SV_DispatchThreadID) { 

    if (dot(input[id.x], cam) >= 0.05) 
     output.Append(input[id.x]); 
} 
+0

能否請您提供您的調試日誌輸出? – Tannz0rz

回答

1

由於您使用了apppend/counter緩衝區,所以您似乎錯過了重置計數器的調用。

outputBuffer.SetCounterValue(0); 

調度呼叫前:

這是可以做到用。

如果不重置計數器,它會保持先前的值作爲出發點(並因此增加每次調用)

請參閱本link更多信息

0

對不起,我忘了回答

我找到了答案後

問題確實是計數器,但也是恢復價值的方法。

outputBuffer.SetCounterValue(0); 

和值

 ComputeBuffer counter = new ComputeBuffer(4, sizeof(int), ComputeBufferType.IndirectArguments); 
     int[] Counts = new int[] { 0, 1, 0, 0 }; 
     counter.SetData(Counts); 

     counter.SetData(Counts); 
     ComputeBuffer.CopyCount(outputBuffer, counter, 0); 
     counter.GetData(Counts); 
     counter.Release(); 
     return Counts[0];