[英]How many times is the vertex shader called with metal?
我一直在學習一些基本的金屬渲染,我堅持一些基本的概念:
我知道我們可以使用以下命令將頂點數據發送到着色器:
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
然后我們可以在着色器中檢索它:
vertex float4 basic_vertex(const device VertexIn* vertexIn [[ buffer(0) ]], unsigned int vid [[ vertex_id ]])
據我了解,每個頂點都會調用一次頂點函數,每次調用時頂點函數都會更新以包含頂點索引。
問題是,從哪里來的vertex_id?
我可以向着色器發送更多不同大小的數據:
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderEncoder.setVertexBuffer(vertexBuffer2, offset: 0, index: 1)
如果vertexBuffer有3個元素,而vertexBuffer2有10個元素......頂點函數被調用了多少次? 10?
謝謝!
這是由您在渲染命令編碼器上進行的繪制調用確定的。 采用最簡單的繪制方法:
drawPrimitives(type:vertexStart:vertexCount:)
vertexCount
確定調用頂點函數的次數。 傳遞給頂點函數的頂點ID是從vertexStart
到vertexStart + vertexCount - 1
的范圍內的頂點ID。
如果你考慮另一種繪制方法:
drawPrimitives(type:vertexStart:vertexCount:instanceCount:)
這涉及相同范圍的頂點ID。 但是,它會調用頂點函數vertexCount * instanceCount
次。 將存在具有頂點ID為vertexStart
instanceCount
調用。 對於這些調用,實例ID的范圍從0到instanceCount - 1
。 同樣,將有一個instanceCount
調用,其頂點ID為vertexStart + 1
(假設vertexCount >= 2
),其中一個實例ID在[0..instanceCount-1]
。 等等。
其他繪制方法有各種其他選項,但它們通常不會影響頂點函數的調用次數。 例如, baseInstance
會baseInstance
實例ID的范圍,但不會baseInstance
其大小。
各種drawIndexedPrimitives()
方法從緩沖區獲取特定的頂點ID,而不是枚舉范圍中的所有頂點ID。 該緩沖區可以在多個位置包含給定的頂點ID。 對於這種情況,我認為沒有定義是否可以針對相同的頂點ID和實例ID多次調用頂點函數。 Metal可能會試圖避免重復工作,但實際上最好只是為索引緩沖區中的每個索引調用頂點函數更快,即使多個這樣的索引最終是相同的頂點ID。
傳遞給頂點處理階段的緩沖區中的頂點和數據之間的關系完全取決於您。 您根本不必傳遞任何緩沖區。 例如,頂點函數可以僅從頂點ID和實例ID完全計算地生成頂點信息。
當然,對於至少一些緩沖區來說,包含使用頂點ID索引的每頂點數據的數組是很常見的。 其他緩沖區可能是對所有頂點都相同的統一數據(也就是說,您不使用頂點ID索引到該緩沖區)。 但金屬本身並不知道這一點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.