13

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

  • 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 中不受支持。

4

5 回答 5

7

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

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

于 2013-01-05T12:25:51.490 回答
0

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

于 2013-01-05T07:06:05.387 回答
0

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

于 2013-01-05T08:35:13.227 回答
0

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

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

于 2013-12-03T18:02:15.680 回答
0

几个想法:

1.)咬紧牙关并更新顶点缓冲区,但仅在 alpha 更改时。

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

3.) 控制广告牌的数量并将一个 alpha 值数组绑定到一个统一...均匀阵列。至少这样你可能只上传 n alpha 值。

4.) 结合 2 和 3...

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

于 2013-02-25T18:24:58.160 回答