Different Textures in Instanced rendering

You can not change rendering state in the middle of a single draw call. So if your non-instanced pattern was [BindTexture; Draw; BindTexture; Draw], you won’t be able to directly replace that with a single Draw*Instanced call.

Depending on how much texture data you have, you can arrange things to work within a single draw call, via a few different methods:

  • combine multiple textures into a texture atlas. Per-instance data must include offsets into the atlas. (good for 2D sprites; but be aware of atlasing complications with texel filtering.)
  • combine multiple 2D textures into a 2D array texture. Per-instance data includes the slice into the array. (avoids filtering issues; but note that popular platforms like ES2 on iOS don’t support array textures.)
  • bind multiple textures (up to i.e. MAX_TEXTURE_IMAGE_UNITS.) Per-instance data includes the index into the array of samplers. (note that dynamically indexing into an array of samplers may or may not be allowed, depending on your GLSL version.)

Keep in mind that all of these solutions increase the texture footprint that has to be simultaneously accessible to the GPU during the single instanced draw call. If you have a truly huge amount of texels (i.e. exceeding the amount of VRAM on a discrete desktop GPU), the old [BindTexture; Draw; BindTexture; Draw] pattern is potentially better.