I am trying to write my particle system for OpenGL ES 2.0. Each particle is made up of 4 vertexes, forming the little square where a transparent texture is drawn.
The problem is: each particle has its own properties (color, position, size), that are constant across the 4 vertexes of that particle. The only variation for each vertex is what corner of the square it is.
If I am to send the properties of the particle via uniform variables, I must do:
for(each particle) { // do maaaany times
glUniform*(...);
glDrawArray(...); // only draw 4 vertexes
};
this is clearly inefficient, since I will only draw 4 vertexes per glDrawArray call.
If I send this properties via attribute variables, I must fill the same information 4 times for each fragment in the attribute buffer:
struct particle buf[n];
for(each particle) {
struct particle p;
p = ...; // Update particle
buf[i+0] = buf[i+1] = buf[i+2] = buf[i+3] = p;
};
glBufferData(..., buf, ...);
// then draw everithing once afterwards...
what is memory inefficient and seems very ugly to me. So what is the solution to this problem? What is the right way to pass parameters that change for each few vertexes to the shader?
Use point sprites. The introduction is very explicit about how to solve your problem.
You can also combine the use of point sprites with another extension, point_size_array.
…
As Christian Rau has commented, the point_size_array is no more usefull using programmable pipeline: set the maximum point size as usual, then discard fragments basing on their distance from the point center, derived from texture coordinates generated by OpenGL. The particle size shall be sent via additional attribute.