Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What should I do if Dynamic Batching doesn't work?

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

Dynamic Batching does not take effect what to do, I believe that many inexperienced people do not know what to do, so this article summarizes the causes of the problem and solutions, through this article I hope you can solve this problem.

Recently, in the process of project development, I inadvertently found that the rendering of the game scene takes up a lot of Batches, almost a model display takes up a Batch, and the number of Saved by batching is almost zero, that is, there is no batch rendering optimization. This is obviously far from expected, because although there are as many as hundreds of models in the scene that need to be drawn, most of them are identical card models, referencing the same shader, and most of them can be automatically dynamic batching by Unity for merge batch processing. Where? what went wrong?

So take a look at Unity Manual and check the rules of Dynamic Batching, which can be summarized as follows:

In general, Unity only supports Dynamic Batching for objects with Meshes less than 900vertices, if vertex positions, normals, and UV values are used in Shader, then only objects below 300vertices are supported; if vertex positions, normals, UV0,UV1 and Tangent vectors are used, only objects below 180vertices are supported.

If the scale of two objects happens to be mirrored, such as scale of (- 1) or (1), they will not be Dynamic Batching.

Objects that reference different material instances will not be Dynamic Batching, even if the materials of the two objects are essentially no different. There is a bit of a twist in the understanding of this sentence, for example, if two copies of the same material are instantiated and referenced by An and B respectively, then An and B will not be Dynamic Batching because they refer to two different instances.

Objects that use lightmaps will not be Dynamic Batching unless they point to the same part of the lightmap.

Shader objects with multiple Pass channels will not be Dynamic batching.

According to the simple investigation, the model meets the Unity's requirements of 1pm, 2pm, 4pm and 5pm. So I began to suspect that different material instance references caused the problem.

Looking at Inspector, you can see that the Material referenced by Mesh Renderer is indeed the desired shader, but the word Instance is added after that. Click the red box in the image, and the Project window does not jump to all the locations of the shader file, indicating that the material is instantiated at run time, not the shader reference pointed to by Prafab preset. From this we can speculate that each model instantiates its own instance of material, resulting in not being Dynamic Batching. Know the cause of the problem, but also know what the problem is. Check the script bound on the object and look at the code related to material. You can see that there are two places:

Private Texture _ mainPlaneTex; private Texture _ flashPlaneTex; public MeshRenderer massively rendererPlane; private Material _ cachedPlaneMaterial = null; private Material cachedPlaneMat {get {if (_ cachedPlaneMaterial = = null & & m_rendererPlane! = null) {_ cachedPlaneMaterial = massively rendererPlane.planet;} return _ cachedPlaneMaterial } private void SetGray (bool bGray) {if (bGray) {cachedPlaneMat.SetTexture ("_ MainTex", _ flashPlaneTex);} else {cachedPlaneMat.SetTexture ("_ MainTex", _ mainPlaneTex);}}

This model needs to be grayed out by getting the material of the object and setting the MainTexture to normal / grayed map as appropriate. Nine times out of ten, the problem is in this piece of code. Looking at the interface of MeshRenderer, it turns out that Unity provides two method interfaces to obtain Material, namely material and sharedMaterial.

Understanding the difference between these two interfaces and figuring out what Unity has done at the bottom is probably not far from the truth.

Renderer.material

Returns the first instantiated Material assigned to the renderer.

Modifying material will change the material for this object only.

If the material is used by any other renderers, this will clone the shared material and start using it from now on.

Unit officials say that when you use Renderer.material to get a Material reference, the first preset Material in the Materials list in Render will be instantiated and an instance will be returned. In this way, when we modify the Material of this object, we will only modify the instance, not the original shader. For example, when we drag and drop more than N shaders of the same model into the scene, when we modify the shader of one of the model A, such as replacing the map, the other models will not be affected, because An only modifies the shader instantiated by itself.

Renderer.sharedMaterial

The shared material of this object.

Modifying sharedMaterial will change the appearance of all objects using this material, and change material settings that are stored in the project too.

It is not recommended to modify materials returned by sharedMaterial. If you want to modify the material of a renderer use material instead.

If you call the Renderer.sharedMaterial API, Unity will not instantiate it for us and return the instance, directly returning the original shader. Again in the above example, when we replace the shader of the A model, we will find that all the models of the scene have been replaced.

After seeing the differences between the two interfaces, I finally understand the root cause of the problem. In order to achieve the requirement of graying the model, Renderer.material is used in the code to get material instances, but each object holds a different material instance, which makes it impossible for Unity to render these identical objects in batches. When the number of objects displayed on the same screen is as many as 100, it means hundreds more unnecessary Drawcall and more unnecessary wear and tear.

And this problem can not simply change Renderer.material to call Renderer.sharedMaterial to solve, after all, a model can not be grayed out, all models should be grayed out, right? The correct solution is to preset normal / gray shaders and replace materials according to different situations.

Finally, compare the Drawcall of the scene before and after optimization:

Before optimization

After optimization

As you can see, in the case of more models on the same screen, the number of Batch has plummeted from nearly 100 to 2, which is basically processed by Unity dynamic batch processing.

After reading the above, have you mastered the method of what to do if Dynamic Batching does not take effect? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report