Unity:在 GPU 上重新计算网格
Unity: Recalculate mesh on GPU
我在网上搜索了一段时间,但找不到适合我当前问题的答案:统一可见对象由网格组成。在 OpenGL 术语中,网格是一个 VertexBuffer,理想情况下,它传输一次到 GPU,然后送入顶点着色器。
现在,在某个给定点,我想在 GPU 上重新计算给定的网格。例如,如果我的 VertexBuffer 有 space for 200 Vector3<float>
它们是立方体的一部分,我想调用一个 ComputeShader(?) 更新每个 Vector3<float>
以便网格现在是一个球体。
我知道我可以使用 CPU 重新分配网格,但在我的场景中那太慢了。
所以问题是,如何将 VertexBuffer 或 Mesh 统一传递给 ComputeShader?我想直接修改 VertexBuffer。
感谢您提供想法、资源和提示!
计算着色器易于设置。
像这样写一个计算着色器
#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);
}
我在网上搜索了一段时间,但找不到适合我当前问题的答案:统一可见对象由网格组成。在 OpenGL 术语中,网格是一个 VertexBuffer,理想情况下,它传输一次到 GPU,然后送入顶点着色器。
现在,在某个给定点,我想在 GPU 上重新计算给定的网格。例如,如果我的 VertexBuffer 有 space for 200 Vector3<float>
它们是立方体的一部分,我想调用一个 ComputeShader(?) 更新每个 Vector3<float>
以便网格现在是一个球体。
我知道我可以使用 CPU 重新分配网格,但在我的场景中那太慢了。
所以问题是,如何将 VertexBuffer 或 Mesh 统一传递给 ComputeShader?我想直接修改 VertexBuffer。
感谢您提供想法、资源和提示!
计算着色器易于设置。
像这样写一个计算着色器
#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);
}