2017-10-07 2 views
1

私はいくつかの基本的な金属のレンダリングを学習してきた、と私はいくつかの基本的な概念で立ち往生しています:メタルで呼び出される頂点シェーダーの回数は何回ですか?

私たちが使用してシェーダに頂点データを送信することができます知っている:

renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0) 

をそして、我々はそれを取得することができますシェーダに:私はそれを理解したよう

vertex float4 basic_vertex(const device VertexIn* vertexIn [[ buffer(0) ]], unsigned int vid [[ vertex_id ]]) 

、頂点関数は、一度、各頂点ごとに呼び出され、vertex_idは、頂点インデックスを含むように呼び出しごとに更新します。

質問はどこから来ましたか?

私はシェーダに異なるサイズでより多くのデータを送ることができ

:vertexBufferは3つの要素を持っている、とvertexBuffer2は10個の要素を持っている場合

renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0) 
renderEncoder.setVertexBuffer(vertexBuffer2, offset: 0, index: 1) 

を...頂点関数が何度も呼ばれていますか? 10?

ありがとうございます!

答えて

3

これは、レンダリングコマンドエンコーダでの描画呼び出しによって決まります。最も簡単な描画方法を取る:

drawPrimitives(type:vertexStart:vertexCount:) 

vertexCountは、あなたの頂点関数が呼び出された回数を決定します。頂点関数に渡される頂点IDは、vertexStartからvertexStart + vertexCount - 1の範囲のものです。

あなたは別のdrawメソッドを検討している場合:

drawPrimitives(type:vertexStart:vertexCount:instanceCount:) 

頂点IDの同じ範囲に渡って行きます。しかし、それはあなたの頂点関数vertexCount * instanceCount回を呼び出します。 instanceCountコールがあり、頂点IDはvertexStartです。これらの呼び出しでは、インスタンスIDの範囲は0〜instanceCount - 1です。同様に、instanceCountのコールでは、頂点IDがvertexStart + 1vertexCount >= 2と仮定します)であり、1つは各インスタンスIDが[0..instanceCount-1]です。その他

その他の描画方法にはさまざまなオプションがありますが、ほとんどの場合、頂点関数が呼び出される回数には影響しません。たとえば、baseInstanceはインスタンスIDの範囲をシフトしますが、そのサイズはシフトしません。

さまざまなdrawIndexedPrimitives()メソッドは、範囲内のすべての頂点IDを列挙する代わりに、バッファから特定の頂点IDを取得します。そのバッファは、複数の場所に所与の頂点IDを含むことができる。その場合、頂点関数が同じ頂点IDとインスタンスIDに対して複数回呼び出されるかどうかは定義されていないと思います。メタルは恐らく重複を避けるようにしようとしますが、複数のインデックスが同じ頂点IDになっても、インデックスバッファ内のすべてのインデックスの頂点関数を呼び出すだけで実際には高速になることがあります。

頂点処理ステージに渡すバッファ内の頂点とデータの関係は、あなた次第です。あなたはバッファを一切渡す必要はありません。例えば、頂点関数は、頂点IDおよびインスタンスIDから完全に計算的に頂点情報を生成することができる。

もちろん、少なくともいくつかのバッファには、頂点IDを使用してインデックス付けされた頂点ごとのデータの配列が含まれています。他のバッファは、すべての頂点で同じ均一データ(つまり、頂点IDを使用してそのバッファにインデックスを作成しない)である可能性があります。しかし、金属自体はこれを知らない。

関連する問題