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

时间:2013-01-05 06:16:25

标签: opengl-es webgl shader 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 ...
];

注意相同的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 ...
];

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


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

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

5 个答案:

答案 0 :(得分:7)

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

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

答案 1 :(得分:0)

如果某个顶点属性对于每个顶点都是常量,为什么不使用统一变量?如果它是恒定的,它是均匀的!通过这种方式,您只需设置一次统一值,并减少数据集。

答案 2 :(得分:0)

我通过实例渲染实现了这种效果。 glVertexAttribDivisor(1);为每个实例生成一次openGL读取顶点属性。如果您的bullboards具有不同的几何图形,您可以考虑将模型矩阵作为属性传递给alpha。

答案 3 :(得分:0)

一些想法:

1。)咬住子弹并更新顶点缓冲区,但仅在alpha更改时才会更新。

2。)将四边形列表分成批次,只重建更改的批次..

3。)控制广告牌的数量并将一组alpha值绑定到一个统一的... 在顶点数据的alpha中,或在某些未使用的通道/附加通道中,存储 统一数组中该广告牌的alpha索引。 至少那样你可能只上传n个alpha值。

4。)结合2和3 ...

我只是疯狂地猜测......我想看看是否有其他人有好的解决方案!

答案 4 :(得分:0)

我没有详细研究过这个,但我认为你也可以使用glDrawElementsInstanced。有了这个,你可以将你的alpha值放入一个大的统一数组中,实例索引会以某种方式传递给着色器。看看这个:

http://sol.gfxile.net/instancing.html