我正在开发2D绘图应用程序。我想在线条扩大的地方产生效果,像这样:
这是一种动画,其中线条像气球一样展开和弹出。
这些线绘制为三角形带。我的想法是通过使顶点着色器中的每个三角形更大来使其扩展。每个顶点都应推离三角形中的其他顶点。
为此,我需要访问三角形中的其他顶点。在Metal中有可能吗?
vertex Vertex vertex_expand(device float2 *vertices [[buffer(0)]],
constant VertexUniforms *uniforms [[buffer(1)]],
uint vid [[vertex_id]]) {
// is vertices[vid - 1] and vertices[vid + 1] the previous and next vertices?
// is vid=0 the first vertex?
}
答案 0 :(得分:1)
是的,您可以根据绘制方式潜在地访问其他顶点。如果您对索引工程进行索引,则顶点ID和三角形之间的关系由索引缓冲区控制。但是问题是,您不知道用于顶点着色器的给定调用的索引(如果这些索引都引用同一顶点,则可能会为多个索引调用一次)。
因此,您将不得不避免索引工程图。
在这种情况下,是的,vertices[vid - 1]
和vertices[vid + 1]
是上一个和下一个顶点。
但是,请注意,对于三角形带,每个顶点都是多个三角形的成员。因此,对于远离顶点的每个顶点,没有一个唯一的三角形,您可以移动该顶点以扩展顶点。我希望您希望与条带边缘相同的两个顶点与要处理的顶点相同,并使用它们为包含当前顶点的线段计算法线,然后沿该顶点移动顶点。>
由于要进行动画制作并因此要重复进行此操作,因此您可能需要预先计算一次这些法线,并将其作为每个顶点数据传递。您可以将计算着色器用于此计算,尽管在CPU上执行它可能足够快。如果以这种方式预计算法线,则顶点着色器将不需要引用任何相邻的顶点。
答案 1 :(得分:1)
回答这个问题,因为我没有足够的声誉来发表评论Ken的答案。 在索引绘制期间,似乎也有一种访问相邻顶点数据的方法。将索引缓冲区作为参数传递给顶点着色器。
[encoder setVertexBuffer:vertices offset:0 atIndex:0 ];
[encoder setVertexBuffer:indices offset:0 atIndex:1];
[encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:indexCount];// this calls vertex shader with vid ranging from 0 to indexCount-1
vertex Vertex vertex_expand(device float2 *vertices [[buffer(0)]],
device uint *indices [[buffer(1)]],
uint vid [[vertex_id]]) {
// if vid % 3 == 0 then vertices[indices[vid]] is the current vertex and vertices[indices[vid + 1]] and vertices[indices[vid + 2]] are the other two vertices belonging to the same triangle.
}