Unity:在GPU上重新计算网格

时间:2017-03-21 09:46:09

标签: unity3d unity5

我在网上搜索了一段时间,但找不到我当前问题的好答案:在统一中,可见对象由网格组成。在OpenGL术语中,网格是一个VertexBuffer,理想情况下一次传输到GPU,然后输入到顶点着色器。

现在,在某些特定点上,我想重新计算GPU上的给定网格。例如,如果我的VertexBuffer具有200 Vector3<float>的空间,它是Cube的一部分,我想调用ComputeShader(?)来更新每个Vector3<float>,以便网格现在是一个球体

我知道我可以使用CPU重新分配网格,但在我的场景中这太慢了。

所以问题是,如何将VertexBuffer或Mesh传递给ComputeShader?我想直接修改VertexBuffer。

感谢您的想法,资源,提示!

1 个答案:

答案 0 :(得分:2)

计算着色器设置简单。

像这样编写一个Compute着色器

#pragma kernel CSMain

#define thread_group_size_x 4
#define thread_group_size_y 4

//A struct that simple holds a position
struct PositionStruct
{
    float3 pos;
};

RWStructuredBuffer<PositionStruct> output;

[numthreads(thread_group_size_x,thread_group_size_y,1)]

void CSMain (uint3 id : SV_DispatchThreadID)
{
   int idx = id.x + id.y * thread_group_size_x * 32;
   float spacing = 1.0;

   float3 pos = float3(id.x*spacing, id.y*spacing, id.z*spacing);

   pos = UpdateVertex(pos,idx);

   output[idx].pos = pos;
}

float3 UpdateVertex(float3 p, int idx)
{
    //Do your stuff here
    return p;
}

现在创建调度此计算文件的C#文件。

public class ComputeShaderScript: MonoBehaviour
{
public Shader shader;
public ComputeShader computeShader;

private ComputeBuffer outputBuffer;
private int _kernel;
private Material material;

void Start()
{
 RunShader();
}

void RunShader()
{
  _Kernal = computeShader.FindKernal("CSMain");

  vector3 Array = new vector3[200];
  outputBuffer = new ComputeBuffer(Array.Length, 12); //Output buffer  contains      vertices (float3 = Vector3 -> 12 bytes)
  outputbuffer.SetData(Array);

  computeShader.SetBuffer(_Kernal,"output",outputBuffer);

  computeShader.Dispatch(_Kernal,array.Length,1,1);

  vector3 data= new vector3[200];
  outputbuffer.GetData(data);

  buffer.Dispose();

  material.SetPass(0);
  material.SetBuffer("buf_Points", outputBuffer);
  Graphics.DrawProcedural(MeshTopology.Points, data.Length);
}