2017-03-21 22 views
2

私はしばらくWebを検索していましたが、私の現在の問題のために良い答えが見つかりませんでした:単一の場合、可視オブジェクトはメッシュで構成されています。 OpenGLの用語では、メッシュはVertexBufferで、理想的には一度GPUに送信され、次に頂点シェーダに送られます。Unity:GPUでメッシュを再計算

そして、ある時点で、私はGPU上で与えられたメッシュを再計算したいと思っています。例えば、私のVertexBufferがキューブの一部である200 Vector3<float>のためのスペースを持っているならば、私はComputeShader(?)を呼び出して、Vector3<float>を更新してメッシュが球になるようにしたいと思っています。

私はCPUを使用してメッシュを再割り当てすることができますが、私のシナリオでは遅すぎます。

どうやら、VertexBufferまたはMeshをComputeShaderに一貫して渡すことはできますか? VertexBufferを直接修正したいと思います。

アイデア、リソース、ヒントありがとう!

答えて

2

計算シェーダはセットアップが簡単です。

この

#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); 
} 
+0

このステップは、「vector3 data = new vector3 [200]」ですか? outputbuffer.GetData(data); '必要なの?それは "データをCPUにコピーする"のように読み込まれます。しかし、 'outputbuffer'は私のOpenGL VertexBufferです。だから私はバッファの長さを知っている場合、私はそれをメッシュに直接CPUにコピーしないで渡すことができますか? – Christoph

+0

あなたのデータを取得するには、バッファーに結果データをCPU RAMの新しい場所にコピーさせる必要があります。これは、ディスパッチが呼び出された後にGetDataメソッドを使用して行われます。 – Nain

+0

さて、最後の質問です。 'SetBuffer()'の呼び出しで "buf_Points"がどこから来るか。 – Christoph

関連する問題