Jump to content
  • Advertisement
Sign in to follow this  
Norman Barrows

dx9 instancing with multiple textures

This topic is 606 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm still working on drawing my grass plants in Caveman 3.0.

Shader test 5 is drawing 1 million instances of the same mesh and texture, with animation based on wind.

I've just finished getting some decent plant meshes and textures going, as well as the code to generate the plants for.a temperate savanna terrain chunk, with nice scale, jitter, etc.  I tested 12 different plant meshes vs 25 different plant textures

So now its time to combine the two.

there are 90,000 plants in a 300 foot wide terrain chunk.

i'd like to allocate the chunk instance VB's just one time at program start, and simply size them "big enough".   

i was originally planning on just 4 mesh and texture combos per chunk for all terrain types - IE 4 instance VB's per chunk at 25-30,000 instances each.
 
But i have 22 combos of plant meshes and textures, using 4 meshes and about a dozen textures.  
 

so do i make 22 instance VBs of 5000 plants each? one for each mesh and texture combo, then make 22 draw calls?

or do  i just make 4 instance VB's - one for each mesh, and add some var to the instance data that says which texture to use - and make 4 draw calls?

i suspect dx9 is limited to 8 textures...

and different types of terrain might  have a different number of mesh and texture combos that look good....    ugh!

it would probably be a good idea to keep the number of mesh and texture combos for all chunks the same, regardless of terrain type. that way you don't have unused instance VBs in some chunks. OTOH...  the chunks for terrain types that that don't have instanced plants will have unused VB's all the time, so....   maybe its not a big deal.

I'm pretty sure all terrain types that will use instancing will draw the same number of instances (90,000 - one every foot on average).  so if i keep the number of mesh types the same for all chunks, i should get fairly decent memory usage. needless to say, chunks that don't use instancing will still have unused instance VBs - se la vie.  But i've already  added them to chunks, just to make sure there's enough memory.  I added 4 VBs of 25,000 instances each to a terrain chunk.

maybe just kick that up to 10 VBs at 10-15,000 instances each or something?

figure out the least number of mesh types a terrain type has, then use that as how many VBs all chunks have, and pick the best meshes for each terrain type?

or figure out the terrain type with the most types of meshes, and make that how many VB's a chunk has?  but size them for the terrain with the least number of mesh types, and thus the most number of instances? so say 12 mesh types max, so 12 VB's,   but there may be only 4 mesh types in some terrain, so make them at least 25-30,000 instances each, not just 90,000/12+some extra = 8000-9000 instances each.

Edited by Norman Barrows

Share this post


Link to post
Share on other sites
Advertisement

I'd make the 22 draw calls.

 

In terms of performance, the overhead of 22 draw calls vs 4 is going to be down in the noise.

Share this post


Link to post
Share on other sites

It looks like temperate savanna, tropical savanna, and prairie (shortgrass) will be the only terrain types that require instancing - IE stuff with short grass. Tall grass is tall, so it can be wide as well, so instancing is not required to cover the area.

So i guess the next step is see how many tropical and prairie plants i end up with, then decide on the number of mesh-texture combos per chunk.

creating instance VBs for mesh-texture combos as opposed to creating them for mesh types means a simpler shader - always a good thing.

and i'm burning about 600 meg of vidram on instance VBs no matter what, whether i have 4 big ones, or 22 smaller ones. keeping the instance VBs per chunk a constant for all chunks will waste no more memory than necessary.

And as you say, 22 vs 4 dip calls is nothing.  I'm routinely making 10K-15K non-instanced draw calls per frame.

Share this post


Link to post
Share on other sites

so do i make 22 instance VBs of 5000 plants each? one for each mesh and texture combo, then make 22 draw calls? or do  i just make 4 instance VB's - one for each mesh, and add some var to the instance data that says which texture to use - and make 4 draw calls?

If you are willing to use a texture atlas then you can go the "4" route, otherwise go the "22" route.

Share this post


Link to post
Share on other sites

a texture atlas

 

good idea. yet another way to get all the textures to the shader.  but altas creation and UV fixups would be a non-trival amount of work. unless i could automate it somehow....

right now i have one shared texture pool for everything in the game, and only character meshes use atlases, and that's only because i found assets that were already UV mapped and came with an atlas.  all meshes are also in one shared pool, so its grab any mesh, grab any texture, scale, rotate, translate,  etc, and draw. plant atlases would be made from the single plant textures, and would be new textures added to the game.

Right now i'm experimenting with low ground cover meshes that adjust to the heightmap. If they work out, they may greatly reduce the instances required for prairie grass. I may not even need instanced drawing - similar to tall grass.

So i'm still figuring out just how many types of plants i'll end up with for the three terrain types. for temperate savanna i have up to 22 to choose from.

But I'm really thinking, based on reference photos, that temperate and tropical savanna should all be just grass plants - a say 4 or 6 types. and the only different might be that tropical might use textures with  a bit browner and more de-saturated grass.  savanna, prairie, and tall grass are all basically just wild grass, at different sizes, in dryer or wetter climates, and prairies have lots of wildflowers. might be able to do it all with one mesh, 4 grass plant textures, 4 prairie flower textures, and one ground texture.

Share this post


Link to post
Share on other sites

With instancing in dx9,10, and 11 you can't change texture states between instances.  So if you want multiple textures within one instanced draw call you have to use a texture atlas.  IIRC with dx12 dynamic indexing is available for you to change textures per instance.

Share this post


Link to post
Share on other sites
you can't change texture states between instances

but i can pass a float in the instance data, and do a switch on it and sample one of multiple textures i pass to the shader.  you can pass more than one texture variable to a shader, can't you? sure you can, for blending. right?  but i don't know how many i can pass. 8 i would imagine, as the fixed function supports 8 stages. so the underlying pixel shader stage - fixed function or programmed - must also support at lest 8 i would think.

it would be nice if i could embed texID into the instance data, then just do a sample based on texID.

But at this point i'm still figuring out how many different meshes and textures i'll be dealing with for each terrain type. and thus how many texture+mesh combos per chunk. that will tell me if i should worry about binding all the textures at once, then drawing all the instances of a given mesh, or whether i should just  make one instanced draw call per mesh+texture combo.  How many meshes and textures per terrain type is also a consideration, as they will all share the same VBs and such, sot he VBs will have to be sized "big enough" for the worst cases scenario.

My latest experiments with low ground plant meshes that cover wider areas have not gone well. The best that can be achieved is a low plateau (ankle high) with nice lily type leaves. sort of like a rock in skyrim barely sticking out of the ground, with some alpaha tested leaves on it. but the plateau is noticeable enough you can tell its a "rock".  less steep sides leads to  Z-fighting when you turn the camera, as does drawing them lower in the ground. The alpha texted texture effect is just fine, but the nearly horizontal quads of the model cause issues were they meet the ground. I found no happy middle ground between mesh height, how far below the ground it is, and how good it looks. and when raised to float above the ground, some float too high, as ground qauds are on 10 foot centers, and plants are on 3 foot centers. a triple lerp over the triangle would be required to get the precise height of the ground qaud triangle where the plant is.  

I'm thinking more conventional quad based plant meshes might be easier. make them splay out low and wide,then fill the middle with short stuff. lots of overlap, lots of see-thru in the texture. Now that i've figured out how to make good low ploy quad based plants, i want to see if i can make low wide ones as a way to draw lots of low ground cover quickly. drawing just one low wide plant beats drawing a dozen little ones.

Edited by Norman Barrows

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!