Best way to render multiple instances with unique license plate

Started by
8 comments, last by L. Spiro 9 years ago

I'm currently trying to get the most performance based on the following constraints.

Each instance/object is only 22 triangles and it's the same mest for every instance.

You can think of it as a cube with 4 quads on the top, where each quad contains a 4 digits (the licenseplate). The licenseplate is created by mapping into the numbertexture with different uv coordiantes.

Right now, I have only created a ProofOfConcept where I render 50000 instances, but the licenseplate is the same.

Now I want to make the licenseplate unique and my bet would be to bind the unique texture coordinate into a VBO, but it would be quite large (22(tricount) x 3(3 vertexes/tri) x numInstances), around 13MB just for texture coordinates.

Does anyone have a better idea ?

Advertisement

Pass a unique instance ID for every instance, and use that ID to generate the UV coordinates for the digit quads. For example, you could use the instance ID as a random number seed, and from that seed generate a sequence of 4 (or however many digits a plate has) numbers in the range of 0..9, then calculate the UV offsets from the digits.

Pass a unique instance ID for every instance, and use that ID to generate the UV coordinates for the digit quads. For example, you could use the instance ID as a random number seed, and from that seed generate a sequence of 4 (or however many digits a plate has) numbers in the range of 0..9, then calculate the UV offsets from the digits.

Was thinking of doing that, but wouldn't I have to branch in the vertex shader in order to do this, thought they where expensive.

Pass a unique instance ID for every instance, and use that ID to generate the UV coordinates for the digit quads. For example, you could use the instance ID as a random number seed, and from that seed generate a sequence of 4 (or however many digits a plate has) numbers in the range of 0..9, then calculate the UV offsets from the digits.

Was thinking of doing that, but wouldn't I have to branch in the vertex shader in order to do this, thought they where expensive.

First, while branches are expensive - assuming the compiler doesn't replace them with equivalent branchless code - but that doesn't mean you should avoid them like the plague, especially in vertex and geometry shaders. Branches are expensive on the CPU as well, but you would never dream of writting purely branchless code for that, right?

Second, there's absolutely no need for branches to do this - it's doable entirely by performing mathematical operations on the ID number that you feed into the shader.

Pass a unique instance ID for every instance, and use that ID to generate the UV coordinates for the digit quads. For example, you could use the instance ID as a random number seed, and from that seed generate a sequence of 4 (or however many digits a plate has) numbers in the range of 0..9, then calculate the UV offsets from the digits.

Was thinking of doing that, but wouldn't I have to branch in the vertex shader in order to do this, thought they where expensive.

First, while branches are expensive - assuming the compiler doesn't replace them with equivalent branchless code - but that doesn't mean you should avoid them like the plague, especially in vertex and geometry shaders. Branches are expensive on the CPU as well, but you would never dream of writting purely branchless code for that, right?

Second, there's absolutely no need for branches to do this - it's doable entirely by performing mathematical operations on the ID number that you feed into the shader.

Don't want to sound like an idiot, but I can't get my head around how to do that.

The InstanceId would be the same for all vertexes in the cube, so how would I know only to change the uv coordinates for the vertexes that are part of the license plate, or am I thinking about this the wrong way ?

Tag your vertices anyhow, e.g. with a bool or with texcoords > 1. Alternatively use a second instanced call with only the license plate and using a different shader, since "car" and plate are in effect different materials.

Tag your vertices anyhow, e.g. with a bool or with texcoords > 1. Alternatively use a second instanced call with only the license plate and using a different shader, since "car" and plate are in effect different materials.

Of course!! :), that's the solution or at least part of it, i'll try both and see what performs the best

Don't want to sound like an idiot, but I can't get my head around how to do that.

The InstanceId would be the same for all vertexes in the cube, so how would I know only to change the uv coordinates for the vertexes that are part of the license plate, or am I thinking about this the wrong way ?

If you're on DX10+ or GL3+, you can use texture arrays and pass the instance ID as the array index.
Otherwise you can use texture atlases, e.g. pack 8 license plates together in the same texture among the U axis and use (u + instanceId) / 8.
Or pack 4 license platex as a grid, and calculate u' = (u + instanceId) / 2 and v' = (v / 8 + mod( instanceId, 1 ) / 2)

Don't want to sound like an idiot, but I can't get my head around how to do that.

The InstanceId would be the same for all vertexes in the cube, so how would I know only to change the uv coordinates for the vertexes that are part of the license plate, or am I thinking about this the wrong way ?

If you're on DX10+ or GL3+, you can use texture arrays and pass the instance ID as the array index.
Otherwise you can use texture atlases, e.g. pack 8 license plates together in the same texture among the U axis and use (u + instanceId) / 8.

With 25000 instances, wouldn't the array get awfully big or am I missing something ?

With 25000 instances, wouldn't the array get awfully big or am I missing something ?

If you have 25,000 unique license plates then it doesn’t really matter, does it?
It’s big somewhere either way.

If cars can share license plates then you clearly don’t need an array of 25,000 textures (regardless of how you implement things).

If they can’t, you would simply generate the license plate via a single texture with digits from 0 to 9. Take the instance ID and use it to generate each number of the license plate. It’s no different from writing a 2D number printer using a single texture atlas.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement