You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vulkan渲染2D四边形时gl_VertexIndex取值问题及优化方案咨询

问题判断

你的判断完全正确。在索引绘制流程中,gl_VertexIndex返回的是从索引缓冲区读取到的顶点索引值,而非当前绘制调用内的顶点调用序号。你为每个四边形填充了6个相同的索引值,因此对应6次顶点着色器调用拿到的gl_VertexIndex完全一致,gl_VertexIndex % 6的结果永远固定,自然无法生成四边形需要的6个不同顶点位置。

解决方案

推荐使用实例化非索引绘制方案,该方案比你原本的设计传输开销更低,实现也更简单:

  • 原本的方案需要为每个四边形传输1组顶点属性 + 6个索引值,本方案仅需要传输1组顶点属性,完全不需要索引缓冲区
  • 具体实现步骤:
    1. 修改顶点输入绑定配置:将存储inTopleft和inExtent的顶点绑定的输入速率设置为VK_VERTEX_INPUT_RATE_INSTANCE,表示每1个实例(对应1个四边形)读取1组属性,而非每1个顶点读取1组
    2. 顶点着色器调整为如下逻辑:
#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);
}
  1. 绘制时调用vkCmdDraw,参数设置为:顶点数6,实例数为你要渲染的四边形总数,其余参数填0即可,不需要创建索引缓冲区,也不需要调用索引绘制接口。

如果有特殊需求必须使用索引绘制,也可以将索引缓冲区改为[0,1,2,3,4,5, 6,7,8,9,10,11, ...],同时顶点缓冲区中每个四边形的属性重复存储6次,但该方案的顶点缓冲区体积为原设计的6倍,没有特殊需求不推荐使用。

内容的提问来源于stack exchange,提问作者Andrew Tomazos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 10:54:03