1

我在 Vulkan 中渲染一个基元,它具有重复的顶点,顶点着色器根据顶点缓冲区中的索引对这些顶点进行不同的处理。所有重复的顶点都是连续的,所以如果 a、b、c 是顶点,缓冲区可能看起来像[a,a,a,b,b,b,c,c,c],我需要能够在我的顶点着色器中判断这是第一次、第二次还是第三次看到相同的顶点。

如果我只是将同一个顶点多次提交到顶点缓冲区,我可以使用gl_VertexIndex(或gl_VertexID在 OpenGL 中)确定它是同一顶点的重复次数,然后根据需要以不同的方式处理每个重复。

但是,我想使用索引缓冲区来避免重复内存中的顶点。当使用索引缓冲区gl_VertexIndex时,每次出现相同的索引时都是相同的值,因为它是顶点缓冲区的索引,每个顶点只有一个副本,因此索引缓冲区是值得的。这意味着在顶点着色器中,我无法区分顶点的第一次、第二次或第三次重复。

gl_VertexIndex是否有一个像我可以使用的内置变量,例如gl_IndexBufferIndex它告诉我这个顶点来自索引缓冲区中的哪个索引?或者,这个顶点在索引缓冲区中已经遇到了多少次?如果没有,是否有一种有效的方法可以在每个顶点的基础上将此信息发送到顶点着色器?

根据 Vulkan 规范 1.2.146 §8.7.1,顶点着色必须为相同的索引重复,除非它保证相同的结果,所以这应该是可能的:

如果在绘制命令中多次指定相同的顶点(例如,通过在索引缓冲区中多次包含相同的索引值),如果它可以静态确定顶点着色器调用将产生相同的结果,则实现可以重用顶点着色的结果.

4

1 回答 1

2

我需要能够在我的顶点着色器中判断这是第一次、第二次还是第三次看到相同的顶点。

你不能。Vulkan(和所有其他渲染 API)定义“相同顶点”的方式是通过顶点索引(或者更具体地说,通过顶点/实例索引对,但这与这个问题无关)。如果系统在绘制调用中获得相同的顶点索引,则允许假设顶点着色器将从该顶点产生相同的输出值,因此由于 post-T&L 缓存,VS 调用可能会被跳过。

这就是你引用的那篇文章所说的。

如果您真的需要做您所说的事情,那么您将不得不自己进行顶点获取。也就是说,您将“真实”顶点索引数组设为属性,在 VS 中,您使用该索引从 SSBO 读取实际属性数据。这允许您获取相同的数据,尽管顶点索引不同。

于 2020-07-06T05:35:06.797 回答