Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
This question was closed Jan 27, 2015 at 02:26 AM by meat5000 for the following reason:

The question is answered, right answer was accepted

avatar image
4
Question by Zergling103 · Dec 21, 2011 at 05:27 AM · renderingperformancebatchingmeshesinstantiating

Dynamic Batching and Instantiating

I am creating a project where meshes are placed procedurally using a script. However, the draw calls are hurting performance. When instantiated with a script they will not dynamically batch at all.

  • I notice that when I place the meshes manually, they batch just fine. So the mesh must be within the vertex count limit of 300.

  • All of the meshes share the same materials and textures.

  • All the instantiated meshes seem to reference the same material and not separate instances, since when the materials are modified in the editor the changes apply everywhere.

  • I am not accessing MeshRenderer.material or .materials[] anywhere in my script.

Static batching is not a desirable option in that these meshes are constantly being instantiated in game, and each StaticBatchingUtility.Combine() call is very costly especially since there will be very many meshes.

Combining meshes isn't an ideal solution either for similar reasons. Combining them using a hierarchy is also very complex and could impose limitations on the project in the future (for example, LOD levels).

Static batching causes some meshes to disappear and move to (0,0,0); some of these objects are scaled (mirrored along one axis specifically) although not necessarily all of them.

On a side note, if anyone has any ideas of how to improve rendering performance when instantiating objects (especially on a large scale) then please feel free to mention them.

Thank you.

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image syclamoth · Dec 21, 2011 at 07:21 AM 1
Share

I remember reading something about this in the documentation. Let me look it up...

EDIT: Nope, must have been imagining it...

avatar image Rod-Green · Dec 21, 2011 at 08:23 AM 0
Share

You might have to post an example project so we can test locally. Or at least some steps so we could repro this with cubes or something?

avatar image Zergling103 · Dec 21, 2011 at 08:43 AM 0
Share

I figured out the issue with that particular example - I had a point light present in the scene, so nothing was being batched. Otherwise, it worked as it was supposed to.

Also, I was switching scenes to test if manually placing objects would let them batch - and that new scene had no point light. :)

2 Replies

  • Sort: 
avatar image
5
Best Answer

Answer by Oliver Eberlei · Dec 15, 2013 at 10:03 AM

I know this is a very old post, but I found this question through google and I came up with a solution that works for me, which I want to share. I'm using this to dynamically batch 2d level sprites, so I'm not sure how this applies to you.

After dynamically creating all the sprites with this code

 SpriteRenderer CreateSprite( Sprite sprite, float x, float y, float rotation )
 {
     GameObject newObject = new GameObject( sprite.name );
     newObject.transform.parent = transform;
     newObject.transform.localPosition = new Vector3( x, y, 0 );
     newObject.transform.localRotation = Quaternion.Euler( 0, 0, rotation );

     SpriteRenderer renderer = newObject.AddComponent<SpriteRenderer>();
 
     renderer.sprite = sprite;
     renderer.sortingLayerName = "LevelRoom";
 
     return renderer;
 }

I simply call this function on the parent gameObject. Since the sprites are all parented to the same GO, this will disable and enable all newly created sprites.

 void BatchSprites()
 {
     gameObject.SetActive( false );
     gameObject.SetActive( true );
 }

This reduces the drawcalls from 143 to 28. I'm afraid I havn't done any more tests with this method, it seems to work for my specific case. Hopefully it points you in a direction to get your own situations working.

Cheers

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image OhNoDinos · Mar 26, 2014 at 04:00 AM 0
Share

You sir are a genius. After looking all over the place and seeing nothing but vague solutions, or undocumented reasons why it was impossible, this solution just plain works. I'm creating a detail-object placing tool, and you just saved my literally thousands of draw calls just by parenting them all to one object and quickly de / re-activating it as the game starts. it costs nothing once the game is running, and it solves the problem absolutely.

Hope more people stumble across this answer!

avatar image DrKucho · Jan 27, 2015 at 02:24 AM 0
Share

i did stumbled! :D i noticed that manually placed in editor got batched, but not so the instantiated/created by script, this trick saved me to go trough a lot of crap!!

avatar image
6

Answer by Zergling103 · Dec 21, 2011 at 08:39 AM

The best approach is a combination of Dynamic Batching, Static Batching and Mesh Combining since each has its own advantages and disadvantages.

Dynamic Batching

Advantages:*

  • Requires no code work.

  • Doesn't cause lag spikes when optimizing many objects.

  • Supports per-object culling.

  • Objects can move and rotate freely.

  • Objects can be created and destroyed.

Disadvantages:

  • Cannot cope with point lights or spot lights.

  • Items must be of uniform scale.

    Static Batching

    Advantages:*

  • Lowers draw calls dramatically when point and spot lights are not present.

  • Lowers draw calls significantly when point and spot lights are present.

  • Supports per-object culling.

  • Objects can be destroyed.

Disadvantages:

  • Requires significant code work in order to prevent lag spikes when optimizing many objects.

  • Does not cope with point lights and spot lights as well as Mesh Combining does.

  • Items must be of uniform scale.

  • Objects cannot move after being batched.

  • Newly created objects must be re-batched inorder to be optimized.

    Mesh Combining

    Advantages:*

  • Works well in all lighting conditions.

  • Works well with any scaling.

Disadvantages:

  • Requires significant code work in order to prevent lag spikes when optimizing many objects.

  • Does not support per-object culling, resulting in potentially a lot of wasted computing power processing offscreen polygons. (However, this risk is negligable if the resulting combined mesh's bounding box takes up very little screen area.)

  • Objects cannot move after being combined, unless recombined afterwards.

  • Objects cannot be created or destroyed after being combined, unless recombined afterwards.

  • Requires memory to store the resulting combined mesh.


Here's what I think would work best:

1) Use Mesh Combining to combine the objects into chunks. The chunks should be big enough to fit as many objects as possible without being too big, or else it will never be culled.

  • Try to use a delayed combine, in case objects are being created, changed, or destroyed often. Wait for everything to settle for a few seconds and then combine them, otherwise every change will cause this slow combine operation to happen.

  • Detect when changes are made to the objects you want to combine. When a change occurs, delete the combined mesh and enable the original mesh renderers. Then after a pause, recombine them again.

  • Don't do this in one big step with all the objects you want to optimize. Instead, try to perform the merging over multiple frames.

  • This resolves the issues Dynamic Batching and Static Batching have with using scaled objects.

  • This also resolves the issue Static Batching has with optimizing many objects. Since many small objects are combined into a few big ones in this step, Static Batching should work much faster.

  • This also saves a slight amount of time that'd normally be spent on culling calculations.

  • Lastly, when using Point Lights or Spot Lights, the combined meshes act as a reliable fallback when the other approaches fall short.

2) Combine the resulting larger objects together using StaticBatchingUtility.Combine();

  • Try to use a delayed combine here as well, for similar reasons.

  • Detect when changes are made to the objects you want to combine. When a change occurs, all you have to do is call StaticBatchingUtility.Combine() a second time.

  • If there are too many objects for the static batcher to combine, consider using mulitple batchers. Batch operations should also be spread out over multple frames as they can be slow.

3) Dynamic batching is applied automatically so no work needs to be done here. :)

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image djarcas · Jan 03, 2013 at 09:56 PM 0
Share

Have you managed to locate a solution to this yet?

I'm having an almost identical issue, but can't find any solutions as of yet.

(Whilst I appreciate the long answer above, that doesn't answer the question : "Why don't objects instantiated in a script batch dynamically?")

avatar image Henrik Poulsen · Feb 19, 2013 at 01:33 PM 0
Share

I don't really see how this answers the question. The actual problem as I see it relates to "When instantiated with a script they will not dynamically batch at all.".

Follow this Question

Answers Answers and Comments

11 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Is there any way I can statically batch procedurally generated objects? 0 Answers

Drawcalls or Batched, which is more important to performace? 1 Answer

,Drawing 100 000+ cubes 1 Answer

Force elements in same batch 1 Answer

Is there a way to use SkinnedMeshRenderer.BakeMesh() in multiple threads? (Mesh Instancing) 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges