【问题标题】:Output of Compute Shader with error (inconsistent value)计算着色器的输出有错误(不一致的值)
【发布时间】:2017-03-08 15:31:04
【问题描述】:

我在使用 ComputeShader 的 unity3D 中遇到问题。

我的目标:找到所有面向相机的法线(两个向量的点 > 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]);
}

【问题讨论】:

  • 能否提供您的调试日志输出?

标签: c# unity3d hlsl compute-shader


【解决方案1】:

由于您使用了 apppend/counter 缓冲区,因此您似乎错过了重置计数器的调用。

这可以使用:

outputBuffer.SetCounterValue(0);

调度调用之前。

如果您不重置计数器,它将保留以前的值作为起点(从而增加每次调用)

查看link了解更多信息

【讨论】:

    【解决方案2】:

    对不起,我忘了回答

    我找到了答案

    问题确实是计数器,但也是值的恢复方法。

    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];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2015-11-10
      • 1970-01-01
      相关资源
      最近更新 更多