我在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 :(得分:1)
由于您使用了apppend / counter缓冲区,因此您似乎错过了重置计数器的调用。
这可以使用:
完成outputBuffer.SetCounterValue(0);
在派遣电话之前。
如果您没有重置计数器,它会将之前的值保留为起点(从而增加每次通话)
有关详细信息,请参阅此link
答案 1 :(得分: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];