To texture atlas or to TextureAtlas

hi guys…

My game has 8 different kinds of units (more to come). who used to have separate materials and textures.
With the goal of improving performance i remapped these 8 units in blender to use a single texture file. (separate section for each unit type). I then selected the same material to use for all 8 units using the jme3 IDE
so i now have
8 models → 1 material → 1 texture

so
Is there a need for me to use?

Material mat = new Material(mgr, "Common/MatDefs/Light/Lighting.j3md");
mat.setTexture("DiffuseMap", atlas.getAtlasTexture("DiffuseMap"));
//change one geometry to use atlas, apply texture coordinates and replace material.
Geometry geom = scene.getChild("MyGeometry");
atlas.applyCoords(geom);
geom.setMaterial(mat);

Or is this simply doing programmatically what i have done manually?

the reason i ask is that I didn’t really notice a big performance improvement ? (which was disappointing)
would this this be more useful if i was on computer with a dedicated graphics card?

No, you don’t need the TextureAtlas class if you already created an atlas yourself. The main point of an atlas is that you want the same materials on objects, including textures. That allows batching of multiple objects and also allows the GPU to render multiple objects with that same material without state changes.

2 Likes

Which means you could also use the geometrybatchfactory in Addition now to improve Performance.

Other than that you dont gain much if you dont lack gpu memory or something.

Is there a reason for those optimizations? If so, show/measure where your bottleneck currently is.

1 Like

Thanks for you response…

I cant use geometrybatchfactory because i need to animate the characters… the units do different things… running shooting dying etc…

im not following this statement here … are you saying the process of combing the textures into an atlas wont gain much if i don’t have gpu memory?
or that if i had enough gpu memory for all the separate textures to begin with then combining them would not improve things much?

i guessed it was the characters that was slowing things, because it seemed like the the FPS was slower when there was a lot of characters around.
Im finding measuring this very difficult… I have tried using the net beans profiler… but it shows me what the CPU is doing its not showing me anything about why the frame rate is low.
It shows me stuff to do with BetterCharacterControl and that doesnt seem to change regardless of whether the FSP is good or bad
If you could point me in the right direction with regards to measuring this, it would be awesome…

First: On master there is a new profiler app state to debug frame issues, but that is probably not needed for the first steps.

If you have textures they are stored in you RAM and are then upon rendering transferred to the GPU Memory. If the GPU Memory is large enough, those will stay in there and are use. If the GPU memory would not be enough, the game would always re upload textures from the RAM to the GPU Memory, which is slow.

But now I realize that this answer was not perfect, because a texture atlas won’t reduce the memory usage much (only in cases where the same texture would be used for multiple models). On the other hand there are things like “texture fetches”, where the gpu has to read the texture from the memory, but I guess this is also only relevant if you had multiple texture layers for the same material.

So: Atlasses only make sense when batching.

Then you can take TaskManager and MSI Afterburner. If the cpu usage is 100/Number of Cores then your game is CPU capped. If not then it is GPU capped (Afterburner GPU Usage is big).

How much FPS do you actually get on what computer? Probably your rig is just bad for multiple cpus.
Also try to set the Bullet Threading Type to Parallel and see if that helps.

2 Likes

Atlases do two major things for you:

  1. let you combine multiple geometries into one. Fewer objects = better, in general. Though if you only have 2-3 textures it doesn’t save too much unless you are instantiating this set of objects many times.
  2. if you do instantiate this multiple times then having a single material will let you take better advantage of batching and/or instancing. You could have done these even with the separate materials but you don’t get as much benefit.

So, if you only have one object with three different textures and you only place it in your scene once… probably not a big deal.

If you place this object in your scene 100 times then a texture atlas will give you 200 less objects for JME to manage.

If you batch it without a texture atlas then JME is dealing with only 3 objects.

If you batch it AND use a texture atlas then JME is only dealing with 1 object.

each geometry = 1 draw call… fewer draw calls = better.

2 Likes

firstly thanks thanks for all your replies… ITs been a tremendous help…

Im on a Mac book pro quad core i7 which i guess isnt the most ideal machine for games… But hey…

i was getting about 60 fps… but when a new model enters my view port for the first time (not added to the root node but shows up on the view port) it drops to 15 and then recovers… And that sounds like the texture being loaded to the GPU you guys were talking about…
– is there a way to pre load load these…? without having to show all my models to the user in a loading screen?

I have been reluctant to batch things because of animations… My characters have animations as they do stuff… Even my building have animations like opening closing doors/widows… Even my trees have animations as they get runover… jme says i have about 500 objects on average and that doesn’t deviate by more than 50
– The characters ill try to use batch node… but can they still be animated independently?
– the structures i will try to batch these… and then maybe replace them with un-batched versions when animations are required…

Activity monitor says im using 50% CPU… Im running few other things on the computer as well like a nosql db and a custom server… Which i will obivously move out when the game is released. I seem to have 1gb of mt 8 gb still available

I also added

bulletAppState.setThreadingType(BulletAppState.ThreadingType.PARALLEL);

which changed FPS from 60 to 100 at the resting stage…

thanks again for all you help

Your Macbook might even have a dedicated Graphics Card, so it’s not that bad.
So what you see is actually uploading stuff to the GPU Memory. The Texture Atlas could fix this, but only when you don’t clone the models. If you do everything (including the mesh) is reuploaded again and again.

You could have your loading screen simply overdraw the scene in the background, so actually you would show all models but they aren’t seen. Otherwise this issue might get more complicated and possibly it won’t work without modifications to the engine itself.

In the earlier days there were recommendations for 100 objects. It is simple: The Driver, the lwjgl library and all take some time. And they take that 500 times per frame which actually sums up.

BTW: It is only hardware skinning which requires multiple materials. You could use software skinning and have an object number of 10. This would on the one hand put some load from the GPU to the CPU but on the other hand the batching effects might be huge.

BTW: We need the per-process Usage, or possibly the profiler also helps with it’s percentage views.
The Bullet Change hints to some cpu cap. However now it could be the gpu which is limiting.

The 100 object suggestion is true for Android but not really true for desktop. We’ve made a lot of optimizations that should help with numbers of objects… I’d say 1000 is a closer ‘max’ but a lot depends on your system.

If you want to test if it’s the textures then just try not setting the texture and see if you still get the slow down. In my experience, large meshes can cause the same kinds of stalls.

I am abusing the crap out of jME with a deep and fine grained scene graph with 100s and sometimes 1000s of separate geometries, (some are just cubes but still could be causing a draw call each i assume). Even on a fairly mid to low range laptop (K2000M GPU or something) i get 100s of FPS.

I have finally noticed some slow down on a 400NZD on board intel gpu thing. But it is still acceptable. I will of course eventually optimize all that. IF it ever gets too slow AND profiling shows its the draw call overhead (which is a little higher from java than C++/C).

But right now on desktops i just don’t see a need.

The render queues seem to do a good job of grouping objects such that state changes are not to frequent.

1 Like