📜 ⬆️ ⬇️

Ad Visualization 1.1 - Decisions and Conclusion

Ad visualization 1.1:
Now the fun part! Here I will present you some solutions that I found during my research. I hope they give you a general idea of ​​how to optimize game resources in terms of the visualization process.

1. Sort


To begin with, you can arrange all your commands (for example, by the Render State) before filling the command buffer. This operation will reduce the number of necessary changes to the Render State to a minimum, since you can process all the polygonal meshes of the same type.



But there are still significant overhead due to the display of all polygonal meshes one by one. To cut them, there is a useful technique called Batching .
')

2. Batching


When you sort polygonal meshes, you sort of group them together in groups. The next step is to ask the GPU to visualize each pile at a time. This is the essence of Batching:
Batching is a grouping of several polygonal meshes before calling API methods to visualize them. This is done due to the fact that it takes less time to render one large polygonal mesh than for many small ones. [ a36 ]
So, instead of calling one Draw Call to the polygonal mesh (which has the same Render State) ...



... you merge polygonal grids (with the same Render State) and display them for one Draw Call. This is a really interesting topic, because you can visualize different grids (stone, chair or sword) at the same time , while they use the same Render State (in essence, this means that they use the same material settings).



It is important to remember that the integration of polygonal grids occurs in the RAM (RAM) and only then the new large mesh is transferred to the memory of the graphics card (VRAM). It takes time! Therefore, Batching is well suited for static objects (stones, houses ...), which are combined once and stored in memory for a long time. Of course, you can combine dynamic objects, such as laser shots in a space game, for example. But since they are constantly moving, you will have to create a “cloud of shots” grid every frame and transfer it to the GPU memory!

Another point why you should be careful ( thanks to koyima for the reminder ): if the object is not in the field of view of the camera, it can just be dropped (ignored when displayed). But if you group several objects together, during rendering you will have to take into account the large polygonal mesh as a whole (even if only a small part of it is really visible). In some cases, this may be the cause of performance degradation.

A more suitable solution for handling dynamic objects is instantiation .

3. Instantiation


Instantiating means sending only one polygonal mesh (for example, a laser shot) instead of several, and letting the GPU duplicate it several times. Drawing the same object in the same position with the same rotation or animation is pretty boring. Therefore, you can transfer a stream of additional data, such as a transformation matrix, to visualize duplicates in different positions (and different poses).
Typical attributes for a copy are the transformation matrix of the “model to the world”, the color of the copy, and the animation player along with the bones. [ a37 ]
Do not hit me hard, but as I understand it, this data stream is just a list in RAM, to which the GPU has access.

In total, only one Draw Call per polygonal mesh type is required! Compared to Batching, the difference is that all instances look the same (because the same mesh is copied), while the combined mesh can consist of several different ones, provided that they use the same Render State settings.



Then everything will be a little more unusual. I think the following tricks are cool, even if they are only suitable for special occasions:

4. Shader for multi-materials


A shader can have access to several textures and therefore you can use not only one diffuse / normal / reflective texture, but two, for example. Naturally, this means that you can combine the two materials in one shader. The materials are mixed with each other, and the degree of mixing is determined by the controlling texture. Of course, this requires additional expenses from the GPU, since mixing is an expensive operation, but it reduces the number of Draw Calls, due to the fact that you no longer have to “tear” the polygonal mesh into parts (see “4. Polygonal meshes and multimaterials” ).

Read more about it here.
Documentation says that more Draw Calls are still better than this expensive technique. Nevertheless, it seemed to me very interesting and, if you need good numbers for statistics, you can argue that “puff” materials reduce the number of Draw Calls (let it not say anything about performance ... but shhhhh!).

5. "Skin" polygonal mesh


Remember the above talked about laser shot grid? I said that this polygonal mesh should be updated every frame, since the shots are constantly moving. Combining them together and sending the result every frame is quite expensive. An interesting approach to solving this problem is to automatically add bones to each shot and transfer information as “skin”. Thus, you can use one large polygonal mesh that can remain in memory, and you will only update bone information with each frame. Of course, if a new shot object is made or the old one is destroyed, you will have to recreate the polygonal mesh. But it sounds like a really interesting idea, I think.

Read more about it here.
Feel free to send me more links about unusual solutions to reduce draw calls!
Almost all! Now you have a certain understanding of what can be done to visualize game resources a little faster. Do not worry, the next book will be short.

the end

Ad visualization 1.1:
Here I will summarize what we have already learned:

Avoid small polygonal meshes.


Check the need for small grids or there is an opportunity to combine several small ones into one large one. Talk to a graphic programmer to get information about the "golden mean" in the number of polygons (the maximum of triangles, the rendering of which does not result in a loss of performance). You may want to add a few triangles to smooth out the corners. You should also follow the multi-materials. If you have collected one large polygonal mesh, but with 5 designated materials, then the large mesh will be broken for visualization, which means that you have 5 small grids left. Maybe the texture atlas will help you?

Avoid too much material.


Speaking of materials, think about managing them. Sharing materials between game resources may be possible if you plan this before creating a resource. Large texture atlases can help you.

Debugging tools


Discuss with programmers whether it is possible to get in-game statistics to understand how problematic this or that game resource can be. Sometimes it's hard to get a general idea of ​​the complex game resources. But if the tool can warn you that some resource has potential performance problems, then you will be able to solve the problem before it is fixed as final.

Ask coder


As you can see, this topic is very technical and strongly depends on the context (hardware, engine, driver, game prospects ...). Therefore, of course, it is a good idea to talk to a programmer about how to configure game resources. Or just wait, if the loss of performance is due to your resources, then programmers will find you and will poke until you optimize everything you did. :)
Do you know any tips I should add here? Let me know!
Wow, did you read up to here? You are crazy! Thank you very much! Tell us what you think about it. I hope you learned something new. :)

the end


[a36] Technical Breakdown - Assassins Creed II
[a37] NVidia GPU Gems 2

Source: https://habr.com/ru/post/246133/


All Articles