Jump to content

Batching calls


fenomas
 Share

Recommended Posts

Hi,

 

Does BJS do any kind of batching when it draws?

 

For example, if a scene has 1000 meshes that all use material/texture A, and another 1000 meshes that use material/texture B, does it attempt to batch together meshes with a common material? Or just render them in arbitrary order, rebinding textures for every mesh?

 

Also: does scene composition affect this? (e.g. would it depend on whether the meshes had a common parent, or whether they are in the same part of the octree, etc.)

Link to comment
Share on other sites

Okay, from doing a simple test it looks like meshes get rendered in the order they were added, regardless of material, parent, etc.

 

So if I understand correctly:

 

 * Binding the material is skipped if consecutive meshes happen to share a material

 * Nothing happens if consecutive meshes use the same texture, it gets re-bound if the material changes

 * This info isn't useful for optimization unless perhaps you manually reorder 'scene.meshes'

 

If that doesn't sound right please let me know

 

Basically I was looking into whether it would be beneficial to pack small textures into an atlas, but it looks like it's not - that would just mean re-binding a large texture every call, rather than a small one.

Link to comment
Share on other sites

Wonder if you can effect the order meshes are drawn from outside the frame work by parenting meshes?  If so, an application could parent meshes of similar material.  Not every app could do this.

 

At the frame work level, perhaps there might be an optimization you could call to "sort" meshes by material.  This could be called occasionally by an application thinking they might benefit, but not put any more cpu pressure on, since not attempting to do this in order in the render process.

 

Maybe put in a enhancement request, http://babylonjs.uservoice.com/forums/267546-general, or do it yourself & PR.

Link to comment
Share on other sites

Wonder if you can effect the order meshes are drawn from outside the frame work by parenting meshes? 

 

Nope, like I said they appear to be drawn in the order they appear in scenes.meshes. I didn't test things like submeshes, but parenting doesn't affect this.

 

Either way, unless I'm missing something draw order doesn't affect the case I was hoping to improve (texture atlases).

Link to comment
Share on other sites

If 100 meshes has the same material you could think about merging them

 

I'm asking about the case where the meshes can't be joined, of course.

 

The idea was, if I have 100 meshes with 100 small textures, could I gain performance by stitching the textures into an atlas (thus having 100 meshes that all use the same texture).

 

And it appears the answer is no - this can only hurt performance. If I'm missing anything please let me know...

Link to comment
Share on other sites

Nothing is batched because there is no good optimization as materials are note the same in your case

 

Wait, so does that mean that avoiding texture bind calls isn't worthwhile?

 

That is, suppose I have a scene with 1000 meshes and two texture atlases. So every mesh has a different material, but they all use one of the two textures. My assumption was that (due to the caching you described) it would be worthwhile for me to sort "scene.meshes" so as to batch the atlases together. I know it's still 1000 draw calls either way, but batching would allow texture bind calls to be skipped (1000 binds in the worst case, 2 in the best case).

 

Is that not correct? Or are texture bind calls so inexpensive (compared to draws) that it doesn't matter?

Link to comment
Share on other sites

Sorry I wasn't clear :) I meant batching materials is not a good optimization if all meshes have differents materials. If they are sharing materials and textures, the cache will do the batching for you by not setting up things that are already set up

 

You are right about the sort.And this is easy to do by just changing objects order in the scene.meshes array :)

Link to comment
Share on other sites

..batching materials is not a good optimization if all meshes have differents materials. If they are sharing materials and textures, the cache will do the batching for you..

 

Err, could be read both ways. :unsure:  I'm asking about the case for meshes which do not share materials but do share a single texture. Batching should also be beneficial in this case, right?

Link to comment
Share on other sites

Hey,

 

I'm working on a class that will handle automatic batching of separate meshes into one big mesh with a multimaterial. If batched meshes are removed/added, the buffers of the big mesh will be recomputed (meshes will be sorted by material). Something like this:

// BATCHED MESH USAGEthis.batched_mesh = new BatchedMesh( 'ground_static_mesh' );var mesh = meshes_from_file[index];mesh.position.copyFrom(this.position);mesh.position.y += 1.0;this.batched_mesh.injectMesh(mesh);this.batched_mesh.injectMesh(meshes_from_file[index2]);

The main use will be to merge meshes that will not move every frame, but will still be changed from time to time. It's mainly a helper to avoid merging meshes manually when needed.

 

Do you guys think this may be useful on this topic?

 

Link to comment
Share on other sites

 

The main use will be to merge meshes that will not move every frame, but will still be changed from time to time. It's mainly a helper to avoid merging meshes manually when needed.

 

What is the benefit of merging separate meshes into a large mesh with a multimaterial?

Link to comment
Share on other sites

In the case where all meshes have different materials I'm not sure there's a real benefit, at least according to this thread.

 

I'm doing it mainly because most of my meshes have the same material. At first I was using instances, but it was still running very slow due to the fact that I had a very large mesh list. I also had thousands of draw calls.

 

But since it's not very complicated, I made it so the BatchedMesh class produces one mesh with a multimaterial and submeshes, instead of several meshes with a unique material. I'm thinking it might be interesting to do a simple benchmarking test (case 1: one mesh & multimaterial, case 2: several meshes & single material) , and see what's the best solution...

Link to comment
Share on other sites

Okay, yeah. I've been doing a lot of testing with that over the past week or two. I'm working on a minecraft-style scene full of terrain split up into chunks. For N discrete chunks, each of which has M different parts that require different materials, I've tried three setups:

 

1. Naive way: N*M separate chunks and M materials

2. Submeshes way: N meshes, each with M submeshes, the whole scene shares 1 multimaterial (with M submaterials)

3. Octree way: Like the naive way, but adding in a selection Octree with N octree blocks

 

Unfortunately I wasted about a week working on this because there was a bug in synchronization that greatly affected performance. Now that that's fixed, my profiling results are that 2&3 perform equally, and 1 is significantly slower, mainly due to Scene._evaluateActiveMeshes().

 

Stuff I've learned:

1. Unless you merge meshes that use the same material, the number of draw calls stays the same no matter what - it doesn't matter whether you use submeshes or multimaterials.

2. AFAIK the only benefit to using submeshes and multimaterials is that the merged mesh's bounding information is used when determining which objects are visible, very similarly to octrees. This is apparently why my methods 2 & 3 perform the same.

3. Basically don't trust the debug layer statistics; they're pretty misleading unless you dig into the source and check how each one is calculated. For example, "Total meshes" and "Total vertices" are not in general related. Total/Active vertices are counting different things as well. It's really confusing.

 

 

With all that said, my suspicion based on this thread is that overall performance could be sped up by using N*M meshes and manipulating the mesh list to group similar materials together. The number of draw calls won't change but material/texture bind could be skipped, as DK described. My other suspicion is that using submeshes will kill this benefit - because submeshes that use the same material will in general never be rendered consecutively. I haven't tested these suspicions yet, and probably won't until I do more with texture atlases.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...