HoloLite

Scene optimizations: how do you handle high draw calls and high textures collisions ?

Recommended Posts

I am hitting into this weird problem on a scene which I imported from a 3ds max project into .Babylon format.
The scene is quite static, it just has lots of static meshes. Nothing moving at all. No animations.

I am viewing the scene in vr mode, and looking at the stats panel, a few stat info looks rather abnormal:

- meshes count: 235      (this is ok, given there is lot of static meshes in the scene)
- draw calls: 332             (this seems too high)
- texture collisions: 130 (this also seems too high)

(Note: the draw calls and texture collisions rates double up as soon as I enter vr mode, this itself is normal I guess)

What caused the high draw calls ?
What is texture collision ? why is it so high ?
As I mentioned the scene has no moving/animations stuff. It looks very static.

If you have tips on how to improve this, please let me know. Thanks

Share this post


Link to post
Share on other sites

It depends on many parameters, starting by the computer which supposed to runs the app. Maybe you can share some materials? Maybe your textures size can be reduce? Maybe you make a try for each tips here? Have you too many dynamic lights, plus dynamic shadows? If yes, why not baking shadows to lightmaps instead?

Every scenes are different and can be optimised in different ways.

Share this post


Link to post
Share on other sites

You have more details about the texture collision counter here:

http://doc.babylonjs.com/how_to/optimizing_your_scene#sceneinstrumentation

"Number of time a texture has to be removed to free a texture slot. Generally, there are 16 texture slots on most recent hardwares. Babylon.js will try to use all of them as the process of binding a texture is expensive. It is a good idea to try to keep this number as low as possible."

You can reduce this number by sharing materials between meshes.

You have a high number of drawcalls (higher than the number of meshes) probably because some meshes may have submeshes

 

I love optimizing scenes so here are some ideas:

- Run a profiler to see if evaluateActiveMeshes is a top function. If yes then call scene.freezeActiveMeshes()

- If not please report here which functions are the more extensive

A good read about optimizations: http://doc.babylonjs.com/how_to/optimizing_your_scene

Share this post


Link to post
Share on other sites

Thanks @V!nc3r and @Deltakosh for the replies!

Those are really good suggestions which I will look into.

A few questions I have:

  • The scene was actually built by the max exporter, I had little control over it.
    You are actually right that many similar textures are being used in the scene, they can be shared actually, but the exporter is not doing this optimization.
    I guess I need to manually optimize the loaded meshes/textures in the scene and save them back into .Babylon format ?
    Do we have some kind of scene editor that can be used for this type of purpose ?

     
  • Which profiler are you referring here ? I've never done web profiling before, any suggestions on the tools ?

Share this post


Link to post
Share on other sites

Could not the # of texture collisions be reduced also by doing a one time sort of meshes by material, after all created?  Even for meshes with multi-materials, slots re-use would also be helped, if they were ordered together.

This assumes you are sharing materials across meshes already.  You should probably check the source code of your exporter, or do a google search like '3ds max share materials'.

Share this post


Link to post
Share on other sites

I was thinking about the F12 profiler in your browser.

Also regarding the exporter, it is not something that can be done at exportation time as we cannot decide for you if materials must be shared or not (because you may NEED to have separate materials for your own logic)

Share this post


Link to post
Share on other sites

@Deltakosh what I was thinking was that the exporter actually keeps track the hash of each texture file content.

Thus it knows whether the a texture is a dup or not, based on the hash. It then can simply ignore the dup texture and share the one it already has in its catalog. 

The user does not need to worry if he is applying dup textures all of the place, the exporter eliminates the dup for you. Isn't this possible ?

Share this post


Link to post
Share on other sites

For texture this is the case: babylon.js will share all texture data

I thought you were mentioning materials and materials require multiple simultaneous textures forcing the system to remove unused one as there are only 16 slots hence the collisions

Share this post


Link to post
Share on other sites

@Deltakosh

There are lots of dup materials in the scene which share the same textures.
I did optimize the number of dup material and texture objects in the scene by around 100 each, and got no improvement in the draw calls and fps. (This is exactly as you said).

The scene does have lots of materials. Some people recommend combining the materials/textures into a single file, a technique called Texture Atlas. This is supposed to reduce the # of draw calls.
Texture atlas has an xml/index file which tells you where each texture is located in the master texture file. That said, would babylonjs be able to work with texture atlas file ? Will the max exporter be able to export it?

 

Share this post


Link to post
Share on other sites

A few updates on the perf issue:

- I optimized the texture such that texture collision is down to 0. But much to my surprise, the draw call# does not change, thus the fps stays the same too.
This looks unexpected to me as I thought texture collision would lead to draw calls, right ?? But it is what it is, at least in my app. :) 

- After profiling the perf, it turned out the calls to intersectsTriangle spent most of the time.
First suspect was the teleport, and disabling it actually improved the fps by almost twice! (what a surprise)
Whew! did not know teleport can take that much processing. The scene does have lots of vertices though (over 1.2 millions).
Now I have to think about how to enable teleport only when the user intends to and disable it automatically after every use. Not sure if this is possible but will investigate.

Share this post


Link to post
Share on other sites

- texture collisions are not linked to draw call as one single draw call can drive up to 8 different textures. Reducing texture collisions helps at driver / GPU level but if you are not GPU bound it won't change a lot

- You can reduce it by playing with the predicate that detects which objects can be a ground. I also highly encourage having a simple (and not visible) object to use a ground. Like here: https://github.com/BabylonJS/Website/blob/master/Demos/HillValleyVR/demo.js#L11

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


  • Recently Browsing   0 members

    No registered users viewing this page.