What is a Draw Call?
Draw calls are essentially the game engine sending up groups of triangles to be handled by the rendering engine. The sending of the data is handled by the CPU (processor) and the actual rendering is handled by the GPU (graphics card).Where do they come from?
Draw calls are "generated" a little differently per game engine. I will use Unreal Engine 3 as an example. Each material/shader adds to the amount of draw calls (as well as lights and such but ignore that for now). Therefore a single model with 3 materials applied to different faces is indeed 3 draw calls.For characters this isn't so bad since they are usually limited, but for static meshes this could become a problem. Thankfully most engines have a system for "batching" similar objects/materials together. If a bunch of static objects with the same materials exist then they will be combined into a single draw call since they all get rendered the same way.
Why so expensive?
There are a couple of really technical reasons for draw call expense, but we won't cover everything nor do i know it.There is a certain amount of overhead to every draw call regardless of the number of triangles or complexity of shaders. So lots of tiny draw calls end up slowing things down due to this overhead.
Rough Example:
Picture you are moving a bunch of books off of an assembly line to a library. The only boxes you have are made of steel. Each box is so heavy that filling it with books only slightly affects the weight, therefore most of the weight of each box is the box itself. Filling each box only half way is a waste of a trip since filling it to full would be little different weight-wise.The weight of the box represents the initial cost of a draw call in general. Always present despite the content.
The people shipping the boxes are the CPU, having to pick up the content and send it out for rendering.
The people unloading at the library are the GPU, getting these Draw Calls and rendering them and making them presentable.
The people packing the boxes of books are YOU. Based on how well you create your models is a determining factor of draw call amount.
Unloading the boxes is pretty simple, especially if they are only half full. The loaders(CPU) are doing a ton of work moving these half empty boxes while the unloaders(GPU) are barely doing anything, just sitting around waiting for the next boxes to come in.
Conversely if the boxes are packed too full, the loaders(CPU) would have many fewer boxes to carry but the unloaders(GPU) would be running around crazy trying to unload them fast enough since they have so much content in them.
Typically in my experience, the GPU is pretty darn fast. No box carries enough books to really be worried about. Therefore the process usually becomes CPU bound as too many small Draw Calls are sent.
The loss of frames per second is associated in this case with one of these systems being bottle necked and waiting on the other.
Why not just combine everything together?
To solve draw calls all together we could (and people have) do some combining of assets.Let's say I have a series of meshes that make up a computer: a mouse, keyboard, monitor, and tower. I originally made them each separately on separate textures to be placed by Level Design.
I know they will always be set up the same way every time though so to reduce draw calls i can combine them all into a single mesh with a single material. The textures are a bit tricky but they can fixed up by taking each texture and laying it out next to the others in new larger square texture and then offset the UVs of my new combined model to fit up with the new texture locations. This is called "Atlasing" your textures.
An Atlas of 4 ground textures combined into a single image:
Nothing wrong with that example other than a loss of control for placing the assets separately, but that can be decided based on the needs of a project.
Combining can be detrimental if done improperly. It may seem silly but just because some polygons are off screen or hidden behind something does not mean that the game is not handling them. There is a system in place calling "Culling" to try and emulate this.
Culling will essentially test objects to see if the engine should even render them and there are many many methods for accomplishing this. Exempt from the exact way that objects get tested for Culling, they usually follow certain rules such as:
"If any part of the object would not be culled, none of it may be culled".
So essentially if your entire subterranean level is a single big cave mesh, that entire mesh will be considered for rendering no matter how much of it you can see. This can cause considerable overhead for rendering as well as streaming levels and many other game systems that need to determine where an object is located.
So try to avoid combining things that are far apart or take up a lot of screen space.
Final Thoughts:
As a rule try to avoid separate materials on models, some examples of when a new material would be wanted:- You need very large textures
- head and body of characters are often separate
- You need different rendering modes or lighting types on your meshes
- Translucent vs Opaque, Phong vs An-isotropic
- Like a truck with opaque body but separate window material so it can be translucent
- You have small amounts of available memory and are using repeating texture maps instead of textures that match UV layouts
Some assets are considered hero pieces and thus will stand alone and not be used too often, these are often forgiven their misconduct and allowed whatever it takes to look amazing.
-
No comments:
Post a Comment