I have a vertex shader that accepts the following attributes:
a_posCoord
: vertex positiona_texCoord
: texture coordinate (passed to the fragment shader)a_alpha
: transparency factor (passed to the fragment shader)The objects I'm rendering are all "billboards" (a pair of right triangles to make a rectangle).
I'm using a single call to glDrawArrays
to render many billboards, each which may have a unique alpha value. A single billboard has 6 vertices. Here's some pseudocode to illustrate how I organize the vertex attribute buffer for a single billboard:
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 ...
];
Notice how the same alpha
value is repeated 6 times, once for each vertex.
Is there a way I can specify an attribute for all 6 vertices without repeating it for each individual vertex?
Here's what I want my vertex attribute buffer to look like, in the interest of reducing the size of the buffer:
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 ...
];
For what it's worth, my current solution works just fine, but makes me feel dirty. I've only just begun to get a handle on using glVertexAttribPointer
and was wondering if it somehow supported something like this, or if there's a different method or technique I could use to achieve something less brute-force.
This is more specifically a WebGL question, but I'm curious about OpenGL in the general sense.
I'm aware that a geometry shader is really what I need for this particular example, but it's out of the question since they are currently unsupported in WebGL.
A vertex is not a position A vertex is a long vector consisting of multiplie attributes. Change one single attribute and you end up with a different vertex. So no, you can not use a single vertex attribute for multiple vertices, because that makes no sense semantically.
However what is possible with newer versions of OpenGL is setting the rate at which a certain vertex attribute's buffer offset advances. Effectively this means that the data for a given vertex array is virtually "replicated" into n vertex invocations before the buffer offset for a attribute advances. The function to set this divisor is glVertexAttribDivisor. In your case you'd set a Binding Divisor of 6 for the alpha array. But it's important that this does not use a single attribute for multiple vertices, but it makes OpenGL do that duplication you were doing for you.