Instanced drawing with different Texture Coordinates


#1

Hey there,

i am trying to display a texture from a video on many (lets say 20000) boxes. The boxes are arranged in way so that you usually wouldnt see its being drawn on 20000 boxes and it looks like one big surface. Something like this.

I did achieve exactly that by making 20000 boxes and correctly adjusting the texture coordinates of each box.

Now i want to optimize this (im around 15fps) and draw the boxes instanced. I found some forum posts and i checked the examples. I know how i can give each instanced box a different position via the shader and that works.

Whats unclear to me is how i can tell the shader the different texture coordinates of each vertex.
The position attribute is given per instance and the texture coordinate attribute should be given per vertex, right? So do i need to create a buffer on the GPU with all texture coordinates of each vertex? If yes, how can i tell the shader which one of them to pick?

Any help/hints are appreaciated!


#2

Hi Vpr,

I believe that you can store the texture coordinates in the mesh straight, no need for an external buffer, so you don’t get lost in indices…

I think you can do something like this to add textures coordinates for each box :

in ofApp.cpp::setup():

// assuming your box is a vboMesh and doesn't have textures coordinates : 
for( int i = 0; i < box.NumVertices(); i++){
    ofVec3f v = box.getVertex(i);
    float xPos = v.x;
    float yPos = v.y;
    float uTex = ofMap(xPos, 0, sizeCanvas, 0, maxTextureSize);
    float vTex = ofMap(yPos, 0, sizeCanvas, 0, maxTextureSize);
    box.addTexCoord({uTex, vTex});
}

For the xPos, and yPos, depending on how you want your texture to be mapped, you can project the 3D coordinates on a 2D plane, by projecting your z axis on (x,y).

So (X, Y, Z) would become (X,Y). In your case i think you want it perpendicular so the xPos and yPos remain the same and Z gets removed.

in the shader:

//this is how you access the coordinates of the texture in the shader
in vec2 texcoord;

Hope this helps,

++

P


#3

Hi Pierre,

thanks for your answer.
I cant test it right now but i believe with your solution every drawn instance of the VboMesh would have the same texCoords, right?

What i need is to draw x amount of boxes instanced from one VboMesh object with each drawn instance having its own texCoords.


#4

Ah, I thought you wanted to have an array of boxes, therefore an array of ofVboMesh.
So each one of them would have the corresponding space coordinates.
You would call the shader as many times as there is instances of boxes.

I don’t know if it’s the most efficient way of doing it tbh, but if the shader is not computation too intensive, i’ll try it.

Otherwise, having several boxes into one ofVboMesh would work too i guess, it will just have 6 * 6 vertices grouped into boxes. ( 6 faces * 6 vertices) for each box, etc…

Hope it works in the end.

Best,

P


#5

Hi, you can pass to the shader a vector with the texcoords as an attribute.
take a look at examples/gl/textureBufferInstancedExample
It is passing transformation matrices but you can use the same idea to pass the texcoords to each instance drawn.