Sign in to follow this  
DKMr_Chaos

Best way to render multiple instances with unique license plate

Recommended Posts

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 ?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

 

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.

Share this post


Link to post
Share on other sites

 

 

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 ?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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) Edited by Matias Goldberg

Share this post


Link to post
Share on other sites

 

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 ?

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this