Vulkan渲染2D四边形时gl_VertexIndex取值问题及优化方案咨询
问题判断
你的判断完全正确。在索引绘制流程中,gl_VertexIndex返回的是从索引缓冲区读取到的顶点索引值,而非当前绘制调用内的顶点调用序号。你为每个四边形填充了6个相同的索引值,因此对应6次顶点着色器调用拿到的gl_VertexIndex完全一致,gl_VertexIndex % 6的结果永远固定,自然无法生成四边形需要的6个不同顶点位置。
解决方案
推荐使用实例化非索引绘制方案,该方案比你原本的设计传输开销更低,实现也更简单:
- 原本的方案需要为每个四边形传输1组顶点属性 + 6个索引值,本方案仅需要传输1组顶点属性,完全不需要索引缓冲区
- 具体实现步骤:
- 修改顶点输入绑定配置:将存储
inTopleft和inExtent的顶点绑定的输入速率设置为VK_VERTEX_INPUT_RATE_INSTANCE,表示每1个实例(对应1个四边形)读取1组属性,而非每1个顶点读取1组 - 顶点着色器调整为如下逻辑:
- 修改顶点输入绑定配置:将存储
#version 450 layout(location = 0) in vec2 inTopleft; layout(location = 1) in vec2 inExtent; vec2 positions[6] = vec2[ vec2(0, 0), vec2(0, 1), vec2(1, 0), vec2(0, 1), vec2(1, 1), vec2(1, 0) ]; void main() { // 非索引绘制下gl_VertexIndex为0~5的循环,直接取对应偏移即可 vec2 position = positions[gl_VertexIndex]; gl_Position = vec4(inTopleft + position * inExtent, 0, 1); }
- 绘制时调用
vkCmdDraw,参数设置为:顶点数6,实例数为你要渲染的四边形总数,其余参数填0即可,不需要创建索引缓冲区,也不需要调用索引绘制接口。
如果有特殊需求必须使用索引绘制,也可以将索引缓冲区改为[0,1,2,3,4,5, 6,7,8,9,10,11, ...],同时顶点缓冲区中每个四边形的属性重复存储6次,但该方案的顶点缓冲区体积为原设计的6倍,没有特殊需求不推荐使用。
内容的提问来源于stack exchange,提问作者Andrew Tomazos
相关产品推荐
相关产品推荐

