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

WebGL2用drawElements索引绘制在GPU着色器实现顶点插值的方案

适配WebGL2 POINTS模式的顶点插值实现方案

优先用下面两种更简单的方案,完全不需要做索引缓冲区复用:

  • 方案1:实例化绘制(性能最优,适配动态插值倍率场景)
    原始顶点缓冲仅存储原生流式顶点数据,不需要额外预处理:
    1. 绘制时调用gl.drawArraysInstanced(gl.POINTS, 0, 原始顶点总数, 插值倍率),最后一个参数直接传2或3即可
    2. 顶点着色器内用gl_VertexID取对应原始顶点的属性,用gl_InstanceID区分当前是原始点还是第几个插值点,直接做插值计算输出位置即可
  • 方案2:多倍顶点绘制(兼容性最好,无需依赖实例化接口)
    直接绘制原始顶点总数 * 插值倍率个点,顶点着色器内做序号拆分即可:
    #define INTERP_RATE 2 // 或3,也可以作为uniform变量动态传入
    in vec3 aPosition; // 原始顶点属性
    
    void main() {
      int originIdx = gl_VertexID / INTERP_RATE; // 对应原始顶点的索引
      int interpIdx = gl_VertexID % INTERP_RATE; // 当前插值点的序号,0为原始点
      // 此处按interpIdx做插值计算,输出最终位置
    }
    
    该方案不需要索引缓冲区,也不需要修改原始顶点数据结构,逻辑更直观。

gl_VertexID、gl_InstanceID的递增规则

  • gl_VertexID是当前顶点在本次绘制调用的顶点序列中的顺序号,每处理一个顶点就加1,和索引缓冲区存储的索引值没有直接关系。比如你用索引缓冲[0,0,1,1,2,2]调用gl.drawElements,gl_VertexID的取值是0到5连续递增,不是重复的0/1/2。
  • gl_InstanceID是当前实例的序号,同一个实例内所有顶点的gl_InstanceID相同,每切换一个实例就加1,完全匹配你区分原始点/插值点的需求。

当前问题根因

确实和索引复用逻辑有关:你误以为gl_VertexID会返回索引缓冲区的取值,实际取到的是连续递增的顶点序列序号,取模判断的逻辑完全错位,只有少数顶点的位置计算符合预期,最终只会显示3个点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:24:00