OpenGL:多个顶点的单顶点属性?

nam*_*uol 13 shader opengl-es webgl vertex

我有一个顶点着色器,它接受以下属性:

  • a_posCoord:顶点位置
  • a_texCoord:纹理坐标(传递给片段着色器)
  • a_alpha:透明度因子(传递给片段着色器)

我正在渲染的对象都是"广告牌"(一对直角三角形来制作一个矩形).

我正在使用单个调用来glDrawArrays渲染许多广告牌,每个广告牌都可能具有唯一的alpha值.单个广告牌有6个顶点.这里有一些伪代码来说明我如何为单个广告牌组织顶点属性缓冲区:

vertexAttributes = [

  px1,py1,pz1, // vertex 1: a_posCoord
  tx1,ty1,     // vertex 1: a_texCoord
  alpha,       // vertex 1: a_alpha

  px2,py2,pz2, // vertex 2: a_posCoord
  tx2,ty2,     // vertex 2: a_texCoord
  alpha,       // vertex 2: a_alpha

  px3,py3,pz3, // vertex 3: a_posCoord
  tx3,ty3,     // vertex 3: a_texCoord
  alpha,       // vertex 3: a_alpha

  px4,py4,pz4, // vertex 4: a_posCoord
  tx4,ty4,     // vertex 4: a_texCoord
  alpha,       // vertex 4: a_alpha

  px5,py5,pz5, // vertex 5: a_posCoord
  tx5,ty5,     // vertex 5: a_texCoord
  alpha,       // vertex 5: a_alpha

  px6,py6,pz6, // vertex 6: a_posCoord
  tx6,ty6,     // vertex 6: a_texCoord
  alpha        // vertex 6: a_alpha

  // ... Many more billboards not shown ...
];
Run Code Online (Sandbox Code Playgroud)

注意相同的alpha值如何重复6次,每个顶点一次.

有没有办法可以为所有6个顶点指定一个属性而不为每个顶点重复它?

这是我希望我的顶点属性缓冲区看起来像是为了减少缓冲区的大小:

vertexAttributes = [
  px1,py1,pz1, // vertex 1: a_posCoord
  tx1,ty1,     // vertex 1: a_texCoord

  px2,py2,pz2, // vertex 2: a_posCoord
  tx2,ty2,     // vertex 2: a_texCoord

  px3,py3,pz3, // vertex 3: a_posCoord
  tx3,ty3,     // vertex 3: a_texCoord

  px4,py4,pz4, // vertex 4: a_posCoord
  tx4,ty4,     // vertex 4: a_texCoord

  px5,py5,pz5, // vertex 5: a_posCoord
  tx5,ty5,     // vertex 5: a_texCoord

  px6,py6,pz6, // vertex 6: a_posCoord
  tx6,ty6,     // vertex 6: a_texCoord

  alpha        // vertex 1-6: a_alpha

  // ... Many more billboards not shown ...
];
Run Code Online (Sandbox Code Playgroud)

对于它的价值,我目前的解决方案工作正常,但让我觉得很脏.我刚刚开始尝试使用glVertexAttribPointer,并想知道它是否以某种方式支持这样的东西,或者是否有一种不同的方法或技术可以用来实现更少的暴力.


这更具体地说是一个WebGL问题,但我对一般意义上的OpenGL很好奇.

我知道几何着色器确实是我对这个特定示例所需要的,但它不可能,因为它们目前在WebGL中不受支持.

dat*_*olf 7

顶点不是位置 顶点是由乘法属性组成的长向量.更改一个属性,最终得到一个不同的顶点.所以不,你不能对多个顶点使用单个顶点属性,因为这在语义上没有意义.

但是,对于较新版本的OpenGL,可能的是设置某个顶点属性的缓冲区偏移量前进的速率.实际上,这意味着在属性的缓冲区偏移量提前之前,给定顶点数组的数据会复制到n个顶点.设置此除数的函数是glVertexAttribDivisor.在你的情况下,你为alpha数组设置了一个6的Binding Divisor .但重要的是,这不会对多个顶点使用单个属性,但它会使OpenGL执行您为您执行的重复操作.

  • "实际上,这意味着在属性的缓冲区偏移量增加之前,给定顶点数组的数据会复制到n个顶点." 这不是真的,除数仅适用于实例索引,而不适用于顶点索引.人们可以通过实例化每个广告牌解决OP的特定问题,但没有明确提到答案中的实例化,这是[相当误导](/sf/ask/3545532021/). (3认同)