问题
I've been learning some basic metal rendering, and I am stuck with some basic concepts:
I know we can send vertex data to a shader using:
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
And then we can retrieve it in the shader with:
vertex float4 basic_vertex(const device VertexIn* vertexIn [[ buffer(0) ]], unsigned int vid [[ vertex_id ]])
As I understand it, the vertex function will be called once per each vertex, and vertex_id will update on each call to contain the vertex index.
The question is, from where comes that vertex_id?
I could send to the shader more data with different sizes:
renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
renderEncoder.setVertexBuffer(vertexBuffer2, offset: 0, index: 1)
If vertexBuffer has 3 elements , and vertexBuffer2 has 10 elements ...how many times are the vertex function called? 10?
Thanks!
回答1:
That's determined by the draw call you make on the render command encoder. Take the simplest draw method:
drawPrimitives(type:vertexStart:vertexCount:)
The vertexCount
determines how many times your vertex function is called. The vertex IDs passed to the vertex function are those in the range from vertexStart
to vertexStart + vertexCount - 1
.
If you consider another draw method:
drawPrimitives(type:vertexStart:vertexCount:instanceCount:)
That goes over the same range of vertex IDs. However, it calls your vertex function vertexCount * instanceCount
times. There will be instanceCount
calls with the vertex ID being vertexStart
. The instance ID will range from 0 to instanceCount - 1
for those calls. Likewise, there will be instanceCount
calls with the vertex ID being vertexStart + 1
(assuming vertexCount >= 2
), one with each instance ID in [0..instanceCount-1]
. Etc.
The other draw methods have various other options, but they mostly don't affect how many times the vertex function is called. For example, baseInstance
shifts the range of the instance IDs, but not its size.
The various drawIndexedPrimitives()
methods get the specific vertex IDs from a buffer instead of enumerating all vertex IDs in a range. That buffer may contain a given vertex ID in multiple locations. For that case, I don't think it's defined whether the vertex function might be called multiple times for the same vertex ID and instance ID. Metal will presumably try to avoid duplicating effort, but it might end up actually being faster to just call the vertex function for every index in the index buffer even if multiple such indexes end up being the same vertex ID.
The relationship between vertexes and data in buffers you pass to the vertex processing stage is entirely up to you. You don't have to pass any buffers, at all. For example, a vertex function could generate vertex information completely computationally just from the vertex ID and instance ID.
It is pretty common, of course, for at least some of the buffers to contain arrays of per-vertex data that are indexed into using the vertex ID. Other buffers might be uniform data that's the same for all vertexes (that is, you don't index into that buffer using the vertex ID). Metal itself doesn't know this, though.
来源:https://stackoverflow.com/questions/46622147/how-many-times-is-the-vertex-shader-called-with-metal