Is there scenarios where this is actually good practice? Or does it slow down performance?


//Vertex format is:
//X, Y, U, V
var myXYs:Vector.<Number> = new <Number>[
  -1, -1,
  1, -1,
  1, 1,
  -1, 1

var myUVs:Vector.<Number> = new <Number>[
  0, 0,
  1, 0,
  1, 1,
  0, 1

//Create actual VertexBuffers....
// ...yaddiyaddiyadda...

//Set context3d's vertex-attributes:
//Assign 'va0':
context3D.setVertexBufferAt(0, bufferXY, 0, Context3DVertexBufferFormat.FLOAT_2);
//Assign 'va1':
context3D.setVertexBufferAt(1, bufferUV, 0, Context3DVertexBufferFormat.FLOAT_2);

Would the GPU have to constantly internally 'swap' between bufferXY and bufferUV to process the vertex-data? Or does it handle it just as good as a single vertex-buffer?

NOTE: My goal is to figure out a way to minimize uploading data from CPU to GPU for a large number of objects (more than the 128 limit with vertex-constants in Stage3D) by manipulating a list of vertices only responsible for the position of objects rather than the entire geometry + color and/or UV coordinates.


1 Answer 1


If you're fetching all the vertex attributes in the shader, then in general attributes in multiple streams may be slower than all attributes in one stream, due to the loss of cache locality. However, using multiple streams can still be a good idea in some cases, such as:

  1. Some passes only need to read a few of the attributes. For example, drawing the object into the shadow map usually only needs positions and is vertex bound, so it can be a win to have the positions set aside in their own stream.
  2. Some attributes are static and some are dynamic. This sounds like your proposed solution. You may be able to save bandwidth overall by keeping the static attributes and the dynamic ones in separate vertex buffers so you only need to update the dynamic ones.
  3. Instancing, where the inner and outer attributes must be in separate streams. This is probably what you should be doing if you're rendering many copies of an object, since it lets you have an outer vertex buffer with one entry per object and an inner vertex buffer with the the vertices for one copy of the object.

In any of these cases the slowdown due to fetching from multiple streams (which may be slight) can be offset by the reduced use of bandwidth overall. As always, the golden rule is to profile it. YMMV, as these things are very dependent on hardware and on details of your shaders and scenes. Measure the performance and see what's fastest for your case.

  • \$\begingroup\$ Thanks, that gives me a good perspective on how to use multiple buffers. I haven't quite understood the 3rd case (inner and outer attributes). Do you have more information (or know a site or two) on the subject? \$\endgroup\$ Jan 24, 2012 at 13:38
  • 2
    \$\begingroup\$ Yeah, here's an introduction to geometry instancing. It's written for Direct3D 9 but the same ideas should hopefully be translatable to whatever API you're using. \$\endgroup\$ Jan 24, 2012 at 17:29
  • 1
    \$\begingroup\$ +1 and I'll add that having your positions in a separate stream can be good for cases where you're forced to use software T&L as it's a friendlier layout for SIMD instructions (you may want to pad position to 4 floats). I've also effectively used multiple streams for keyframe animation on the GPU - one stream gets positions for current keyframe, second stream gets positions for previous keyframe, third stream gets texcoords, put the blend factor in a constant register, and interpolate between the frames in your vertex shader. \$\endgroup\$ Jan 24, 2012 at 19:11
  • \$\begingroup\$ @bigp, if you found this answer helpful, don't forget to click the "accept" button to mark it as accepted for other users. :) \$\endgroup\$ Jan 25, 2012 at 18:21

You must log in to answer this question.

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