12
\$\begingroup\$

I am planning to do geometry instancing in OpenGL ES 2.0 Basically I plan to render the same geometry(a chair) maybe 1000 times in my scene.

What is the best way to do this in OpenGL ES 2.0?

I am considering passing model view mat4 as an attribute. Since attributes are per vertex data do I need to pass this same mat4, three times for each vertex of the same triangle(since modelview remains constant across vertices of the triangle).

That would amount to a lot of extra data sent to the GPU( 2 extra vertices*16 floats*(Number of triangles) amount of extra data).

Or should I be sending the mat4 only once per triangle?But how is that possible using attributes since attributes are defined as "per vertex" data?

What is the best and efficient way to do instancing in OpenGL ES 2.0?

\$\endgroup\$
1
  • 3
    \$\begingroup\$ I really miss glVertexAttribDivisor :( \$\endgroup\$
    – Will
    Commented Jul 3, 2012 at 13:16

4 Answers 4

8
\$\begingroup\$

ES2 has neither glVertexAttribDivisor nor floating point textures so your options are quite limited.

Definitely put your chair model into a VBO if you're not doing so already. From there you're more or less restricted to individual draw calls - one per chair - so it's a question of getting the transformation matrix for each chair to the GPU as efficiently as possible.

You could do this with regular glUniform calls, or you could abuse some extra vertex attrib slots and make some glVertexAttrib (note: not glVertexAttribPointer) calls before drawing each chair, specifying the matrix using 4 such slots, and these values will "stick" for each subsequent vertex in the chair. That can be a fast enough path on some hardware but slower on other so you're going to have to experiment.

If your chairs don't rotate one other thing you can do is just send position to your shader and construct a new transformation matrix on the fly there. That sounds horrible but it's actually incredibly fast (it's just setting 3 floats) and might do the job.

On the whole though, and assuming that you're aiming for a typical mobile platform, I'm thinking that whatever you do, draw calls are going to kill you.

\$\endgroup\$
7
\$\begingroup\$

Your best bet is to use an instancing approach pretty similar to skinned models. Create a VBO that will hold many copies of your chair, all of them identical. Now, every vertex must have a byte attribute that will hold the index to the transform matrix that it will be applied to it. Send an array of matrices to your shader and use them as the world transform of each of your chairs. This way, you can draw in each call as many chairs as the maximum size of the array parameter, without having to rewrite any data in the VBO.

\$\endgroup\$
3
\$\begingroup\$

Wolfire Games has an excellent blog post about fast object instancing. What they do is render the model a bunch of times, but send a different matrix for each object to a uniform slot.

This is a pretty efficient way to instance a whole bunch of objects, because you only have to send the data once (the biggest bottleneck when rendering a batch of objects will always be bandwidth) and then transform the model in a shader.

\$\endgroup\$
1
1
\$\begingroup\$

http://www.youtube.com/watch?v=rfQ8rKGTVlg

This is a Google Talk on WebGL, which is OpenGL ES for JavaScript, meaning there's no geometry instancing either. It may give you an idea, though it's hard to tell because i don't know whether your bottleneck is on the GPU or the CPU.

Though, you should learn about uniform variables, there's absolutely no need to send a mat4 in an attribute, all vertices of your chair will be transformed by the same matrix, you have to send it only once per model, not per triangle. Uniform variables let you do that, they're a special kind of a variables that you can set in the shader program itself.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .