Opengl es OpenGL:多个顶点的单顶点属性?
我有一个接受以下属性的顶点着色器:Opengl es OpenGL:多个顶点的单顶点属性?,opengl-es,webgl,shader,vertex,Opengl Es,Webgl,Shader,Vertex,我有一个接受以下属性的顶点着色器: a_posCoord:顶点位置 a_texCoord:纹理坐标(传递到片段着色器) a_alpha:透明度因子(传递到片段着色器) 我正在渲染的对象都是“布告牌”(一对直角三角形组成一个矩形) 我使用对glDrawArrays的一个调用来渲染多个广告牌,每个广告牌可能有一个唯一的alpha值。单个广告牌有6个顶点。以下是一些伪代码,以说明如何为单个广告牌组织顶点属性缓冲区: vertexAttributes = [ px1,py1,pz1, // v
:顶点位置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中不受支持。如果某些顶点属性对于每个顶点都是常量,为什么不使用统一变量?如果它是常数,那么它是一致的!通过这种方式,您只需设置一次统一值,数据集就会减少。我通过实例渲染实现了这种效果<代码>glvertexattributedivisior(1)代码>使openGL每个实例读取一次顶点属性。如果你的牛仔板有不同的几何形状,你可以考虑将模型矩阵作为一个属性与alpha相同。
<强>顶点不是一个位置< /强>顶点是一个由多个属性组成的长向量。更改一个属性,最终将得到不同的顶点。因此,不能对多个顶点使用单个顶点属性,因为这在语义上没有意义
但是,新版本的OpenGL可以设置某个顶点属性的缓冲区偏移量的前进速率。实际上,这意味着在属性的缓冲区偏移量前进之前,给定顶点数组的数据将复制到n个顶点。设置此除数的函数为。在本例中,您为alpha数组设置了绑定除数6。但重要的是,这不会对多个顶点使用单个属性,但它会使OpenGL执行您为您执行的复制操作。有几个想法: 1.)咬紧牙关并更新顶点缓冲区,但仅当Alpha更改时 2.)将四边形列表分为多个批次,仅重建更改的批次 3.)控制广告牌的数量,并将alpha值数组绑定到统一的。。。 在顶点数据的alpha中,或在一些未使用的通道/附加通道中,存储 在您的统一阵列中,该广告牌的alpha索引。 至少这样你可能只上传n个alpha值 4.)组合2和3
我只是胡乱猜测。。。我想看看其他人是否有好的解决方案 我还没有详细研究过这一点,但我认为您也可以使用
gldrawerementsinstanced
。这样,您可以将alpha值放入一个大的统一数组中,实例索引将以某种方式传递给着色器。看看这个:
事实上,可能的复制非常接近复制,但我想将其保留几天,看看是否还有其他知识,因为我的问题更具体一些,可能有人有一种完全不同的方法,我不知道。我猜在WebGL利用ES3的几何体着色器支持之前,我必须坚持使用冗余数据。我注意到glVertexBindingDivisor不是WebGL 1.0或ES 2.0(我正在使用)的一部分(这不起作用,因为我只为整个缓冲区对象调用了一次
glDrawArrays
,该对象包含许多布告牌,每个布告牌都有自己的alpha值。我不清楚。事实上,我认为你运气不好!对不起。是的——在重读我的问题后,我意识到我没有强调重要的部分。尽管如此,谢谢!这是d。)WebGL似乎不支持oesn,但我会研究它。谢谢!我认为还需要注意的是,这种复制只在渲染过程中发生,因此使用绑定除数6存储的alpha值将使用更少的内存。(除非我严重误解了此功能!)OpenGL进行复制而不是对多个顶点使用单个属性的缺点是什么?这是否意味着GPU上的顶点缓冲区以某种方式被扩展,内存没有被保存?如果不是,那么可观察到的区别是什么?“实际上,这意味着在属性的缓冲区偏移量前进之前,给定顶点数组的数据将复制到n个顶点。“这不是真的,除数只作用于实例索引,而不作用于顶点索引。可以通过实例化每个广告牌来解决OP的特定问题,但答案中没有明确提到实例化,这是真的。