我有一个顶点着色器,它接受以下属性:
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中不受支持。
答案 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值放入一个大的统一数组中,实例索引会以某种方式传递给着色器。看看这个: