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

Unity optimization

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

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

When we are playing games, we should know which performance factors affect the game in order to prescribe the right medicine. For a game, there are mainly two kinds of computing resources: CPU and GPU. The two will work together to make the game work at the expected frame rate and resolution. CPU is responsible for the frame rate, and GPU is mainly responsible for something related to resolution.

To sum up, there are mainly the following performance bottlenecks:

CPU: too many Draw Calls; complex scripts or physical simulations.

Vertex processing: too many vertices; too much calculation per vertex.

Fragment processing (GPU): too much fragment,overdraws;, too much pixel-by-pixel calculation.

Wideband: large and uncompressed texture; framebuffer with high resolution.

For CPU, it is mainly the Draw Calls in the game that limits it. So what is Draw Call? In OpenGL, before each drawing, we need to prepare vertex data (position, normal, color, texture coordinates, etc.), and then call a series of API to put them in a specified location that GPU can access. Finally, we need to call the _ glDraw command to tell GPU to render, and when we call the _ glDraw command, it is a Draw Call. Why is Draw Call a performance bottleneck (and a bottleneck for CPU)? When we want to draw an image, we must call Draw Call. For example, if there are water and trees in a scene, we use a material and a shader to render the water, but we need a completely different material and shader to render the tree, so CPU needs to reprepare the vertex data and reset the shader, which is actually very time-consuming. If each object in the scene uses a different material and different texture, then too much Draw Call will be generated, which will affect the frame rate and the game performance will be degraded.

How to reduce DrawCalls?

Mainly introduce batch processing (Batching)

The most common is through batch (Batching). In terms of name, it means to deal with multiple objects together. So what kind of objects can be dealt with together? The answer is an object that uses the same material. This is why, for objects that use the same material, the difference between them is only the difference in vertex data, even if the mesh is different. We can merge these vertex data together and send them to GPU together to complete a batch processing.

There are two batch processing methods in Unity: dynamic batch processing and static batch processing. For dynamic batch processing, the good news is that everything is automatic, we don't need to do anything ourselves, and objects can move, but the bad news is that there are so many limitations that we may accidentally break this mechanism, resulting in Unity unable to batch some objects that use the same material. The good news for static batching is that it has a high degree of freedom and few restrictions, while the bad news is that it may take up more memory, and all objects after static batch processing can no longer be moved.

Let's start with dynamic batch processing. The condition for Unity to batch dynamically is that objects use the same material and meet certain conditions. Unity always does dynamic batch processing for us before we know it. For example, the following scene: this scene contains a total of four objects, two of which use the same material. As you can see, its Draw Calls is now 3, and shows that Save by batching is 1, that is, Unity saves us 1 Draw Call with Batching. Next, let's randomly change the size of one of the boxes to see what happens: you can see that the number of Draw Calls becomes 4 and the number of save by batching becomes 0. Why is that? They still use only one material. The reason is the other conditions mentioned earlier that need to be met. Although dynamic batch processing is touching, it requires a lot from the model: the maximum limit for vertex properties is 900, and it is likely to change in the future. Don't rely on this data.

In general, all objects must use the same scale (it can be (1, 1, 1), (1, 2, 3), (1.5, 1.4, 1.3), and so on, but they must all be the same. However, if it is non-uniform scaling (that is, the scale of each dimension is different, for example, (1, 2, 1)), it can also be batch if all objects use different non-uniform scaling. This requirement is weird, so why does batch processing have anything to do with scaling? This has something to do with the technology behind Unity.

Objects that use lightmap will not be batch processed. Multi-passes shader interrupts batch processing. Objects that receive real-time shadows will not be batch processed.

In addition to the most common cases of batch destruction due to scaling, there are also restrictions on vertex properties. For example, in the above scenario we added a previously unoptimized box model: you can see that Draw Calls suddenly becomes 5. This is because the newly added box model contains 474 vertices, and it uses vertex attributes such as location, UV coordinates, normals, and so on.

There are so many conditions for dynamic batch processing that it doesn't work out accidentally, so Unity provides another method, static batch processing. Following the above example, we keep the modified zoom, but check the "Static Flag" of the four objects:

Click on the triangle drop-down box behind Static, and we will see that this step actually sets a lot of things, and all we want here is "Batching static". At this time, let's take a look at Draw Calls. Well, there is still no change. But don't worry, we click run, and there is a change:

Draw Calls goes back to 3 and shows that Save by batching is 1. This is the benefit of static batch processing. Moreover, if we look at the model's grid at run time, we will find that they all become something called Combined Mesh (roo: scene). This grid is the result of Unity merging all the objects identified as "Static", in our case, four objects:

You can ask, why can these four objects be merged into one when they do not all use the same material? If you look closely at the image above, you will find that it is marked with "4 submeshes", that is, the merged grid actually contains four subgrids, that is, our four objects. For the merged mesh, Unity determines the submeshes that use the same material, and then batch them.

However, if we are more careful, we can see that our boxes actually use the same grid, but after the merger, they become two. Moreover, we observe the "VBO total" in the Stats window before and after running. Its size has changed from 241.6KB to 286.2KB, and it has become bigger!

This shows the disadvantage of static batch processing. If some objects share the same grid before static batch processing (for example, the two boxes here), then each object will have a copy of the grid, that is, a grid will become multiple grids and be sent to GPU. In the above example, the size of the VBO has increased significantly. If there are a lot of objects that use the same mesh, then this is a problem, and at this point we may need to avoid using static batches, which means sacrificing some rendering performance. For example, if you use static batch processing in a forest that uses 1000 repeating tree models, the result is 1000 times more memory, which has a serious memory impact. In this case, either we can put up with this method of sacrificing memory for performance, or instead of static batch processing, use dynamic batch processing (provided that everyone uses the same scaling size. Or everyone uses different non-uniform scaling sizes), or write batches themselves. Of course, I think it's best to use dynamic batch processing to solve the problem.

There are some tips to use:

Choose static batches whenever possible, but always be careful about memory consumption.

If static batching is not possible and you want to use dynamic batching, be careful of the various considerations mentioned above. For example:

Make such objects as few as possible and contain as few vertex attributes as possible.

Do not use uniform scaling, or both use different non-uniform scaling.

For props in the game, such as gold coins that can be picked up, dynamic batch processing can be used.

For such objects that contain animation, we cannot all use static batches, but if there is an immovable part of it, we can identify it as "Static".

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

Servers

Wechat

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

12
Report