【发布时间】:2019-05-26 23:14:08
【问题描述】:
我想使用计算着色器来修改我的顶点,然后再将它们传递给顶点着色器。我找不到任何例子或解释,除了似乎在这里提到:Metal emulate geometry shaders using compute shaders。这对我没有帮助,因为它没有解释它的 CPU 部分。
我已经看到了许多在计算着色器中读取和写入纹理缓冲区的示例,但我需要读取和修改顶点缓冲区,其中包含具有法线的自定义顶点结构,并由 MDLMesh 创建。我将永远感谢一些示例代码!
背景
我真正想要实现的是能够在 GPU 上修改顶点法线。另一种选择是如果我可以从顶点着色器访问整个三角形,就像在链接的答案中一样。出于某种原因,我只能使用 stage_in 属性访问单个顶点。在这种特殊情况下,使用整个缓冲区对我不起作用,这可能与使用模型 I/O 和 MDLMesh 提供的网格有关。当我手动创建顶点时,我可以访问顶点缓冲区数组。话虽如此,使用该解决方案我将不得不为每个三角形计算三次新的顶点法线向量,这似乎很浪费,并且无论如何我希望能够将计算着色器应用于顶点缓冲区!
【问题讨论】:
-
在某个时候,您已经设置了 Metal 渲染管线的
vertexDescriptor,对吧?您还设置了与该顶点描述符的布局相对应的缓冲区。您将不得不使用它们直接访问顶点数据。我认为没有任何简单的方法可以做你想做的事。您可以将vertexDescriptor转换为stageInputDescriptor用于计算管道,但您仍然一次只能看到一个顶点。 -
感谢您的回答。当然,我已经发现如果我不使用 metalkit 网格制作的顶点描述符,那么我可以放弃 stage_in 并访问 Metal 中的整个缓冲区,这样该解决方案现在就可以工作了,但这很浪费,因为我需要这样做我的计算每个顶点 3 或 4 次,而且不是很灵活。我真正想做的是读取计算内核中的顶点缓冲区,修改它们并写入第二个缓冲区或类似的缓冲区,然后在顶点着色器中读取调整后的顶点缓冲区,但我发现的所有示例都修改了一个 texture2d在计算着色器中。
-
在计算着色器中修改缓冲区没有问题。让它接受一个像
device VertexIn *buffer [[buffer(0)]]这样的参数。然后,在函数中,只需读取和/或写入buffer[vertexIndex].field。您通常会根据网格位置计算顶点索引(对于一维计算“网格”,可能就像一对一一样简单)。 -
好的,我认为不可能在“第 1 层”设备上写入顶点缓冲区。此外,在他们写入内核函数中的纹理的情况下,他们似乎通过 access::read 传入引用并通过 access::write 写入另一个引用,顶点缓冲区不需要吗?我还担心金属会确保特定顶点在进入计算着色器之前不会发送到顶点着色器。理想情况下,我想以 4 个为一组修改顶点,因为四边形中的每个顶点都应该具有相同的调整法线!你有任何示例代码吗?
-
您似乎混淆了缓冲区和纹理。内核和顶点函数始终能够读取和写入缓冲区。写入缓冲区的片段函数存在限制。此外,在图形函数中写入 textures 也有局限性。关于顶点缓冲区,Metal 并没有什么特别之处。它们只是像其他缓冲区一样的缓冲区。不用担心计算着色器和渲染命令在 GPU 上的竞争。没有示例代码。对不起。
标签: swift shader metal compute-shader metalkit