Ow, 142 draw calls, thatâs a bit too many Iâd say. Iâm sure there are ways to reduce the number of draw calls to less than 20 in your game. Please read up on how the engine batches draw calls and what you can do to help the engine to reduce draw calls:
Draw calls and Defold
I already know how to disable etc. Just needed to know if its possible with collections.
Thanks!
Collections have no impact on a game object at all. They are a means of organizing game objects. They do not exist as a concept in runtime.
First step (maybe interesting for beginners like me)âŚ
ON top there is a statistic window. Used 3 atlasses in the past (units, structures, ingameGUI).
Iâve made a new atlas with all used graphics.
Changed the statistic graphics and set up just ONE atlas and changed the linked graphics of cause.
DrawCalls past: 42
DrawCalls now: 40
Sure, small result, but anyway, shows me how things take effect.
Will now change all Sprites to the new atlas.
Second try:
Removed unused graphics in GUI with boxes, sprites etc.
The âunit-menuâ dropped from 124 to 107 frames. Logic⌠there was the âoldâ menu etc outof the view and other crap. Removed it to drop down the drawcalls. Have to continue the cleanup.
(btw, just posting this for beginners to prevent questions).
Maybe there should be another optimisation-thread?
@stephenkalisch I suggest you have a look at this great writeup on draw calls in defold by @Mattias_Hedberg to get you started
My experience of optimisations.
This post awesome!
The main things that helped me:
- use 1x1 alpha sprite in gui instead of empty nodes;
- node layers;
- replace tinting sprites with pre tined textures.
Thanks @AGulev.
Iâve seen your post already. Not sure how it works.
1x1 alpha sprite? Iâve added a 1x1 colored pixel, f.e. orange and added the texture for the box-node. but it âfades outâ. Like you can see here (first button START)
Ah now⌠you mean for empty nodes. Dont have any yet. Tying your example I realized: textured boxes reduces the drawcalls by 1 instead of just colored boxes o.O
added a simple layer and added all nodes to it. no effect.
last point âtinting spritesâ not sure what you meanâŚ
btw: Very nice game you are on! Really like the graphics
step by step:
-
1x1
Sometimes you need empty node for right position of children.
Bad a node without texture (break a batch) open full image by click:
Good (alpha texture should be in the same atlas as other gui items):
2 . Node layers
Different types of nodes break batch.
Bad when all nodes has the same layer or has no layer. All nodes draw one by one like in yours âOutline windowâ and if some text (for example) into box node, it will break batch.
Good all different types of node has own layer (draw order). For example all box nodes has an âimgâ layer, and all text node has âtxtâ layer. Sometimes you need to draw text under the box node, then you need one more layer for it.
3 . Tinting sprites.
If you change tint using sprite.set_constant, and it will be static (it is not an animation, just change tint once) You can change tint in photoshop and use this texture in game. It will help to reduce drawcalls count.
Ok. got the layers (always 2: one for boxes called âimgâ and one for the text-nodes called âtxtâ). changed on (hopefully) every gui.
Reduces the drawcalls by half! In the main menu there was 38 calls, now 23. In game (no building menus open), at 23 drawcalls, was 42.
Have to continue optimizing. Opening a unit-menu for building punshes the drawcalls from 23 to 90.
The reason is the dynamicly generated âpop-up-build-menuâ.
HereâŚa question to @britzl and the other Proâs⌠If I clone a node-tree, does the cloned one also clones the layer-config from the template? Or do I have to set it for the clones?
hmâŚ
I dont know why the unit and structure menu takes about 70 drawcalls for 90 nodes.
both menues are now based on 2 layers.
Are you changing the color of the nodes? That would break the batches. Does all of the box nodes have an image assigned from the same texture?
hmâŚ
I use box-nodes with different colors. I thought this would be the most âhardware-friendlyâ way (and I like simple looks).
All the dynamic (cloned) buttons have a coloured box as background. its about 15 buttons containing a background box-node, a box-node with a sprite and 2 text-nodes with 2 different fonts (sizes).
The content of the âingameGUIâ which will be activated after clicking on a unit or structure which takes about these 70 are in the last screenshot. The button left top is a template. it will be cloned depending on a table content which is actually 8 entries.
there is also a nearly same GUI (for structures)- dont have these small buttons in the middle - rest the same. also 7 dynamic buttons.
These 2 GUIs activated (happens if you click on unit OR structure) takes all the performance.
I could give you screens, source or access if you like.
Iâve saw this kind of solving and handling in some examples and thought it would be a good way.
Maybe I should handle it all in one GUI (unit and structure).
I have a couple of GUIs actually.
I was wrong. Box nodes with different colors does not break the batch. Sorry about that.
Youâre welcome to invite me (bjorn.ritzl@king.com) to the project and Iâll take a look.
Uploaded and added you to the dev-team Thanks so far.
Some things Iâve noticed when looking at the unit.gui:
- Youâre using two layers;
img
andtxt
. The thing is that youâre using both the system font and your own font and you assign all text nodes to the layertxt
regardless of font. This will break batching every time the font changes. Solution: Use one font or use more layers (one per font). - The node
structure_underconstruction
is assigned to theimg
layer but it is set as semi transparent (alpha = 0.3). I believe this will break a batch. - The node
move_selector
doesnât have a texture but it is assigned to theimg
layer (and itâs semi transparent). This will break the batch. Create an image, add it to the atlas and use the image instead. - The node
buildmenu/button_buildstructure_base
doesnât have a texture assigned either.
I believe the above couple of issues are causing all of the additional draw calls in that gui scene.
Thanks so far @britzl.
hm⌠that means every box-node needs to have a texture?
if there is any transparency there has to be a separate layer?
for each font a layer?
OMG. Nearly everything designed is a âbatch-breakerâ.
There should be a separate thread which explains the batches
Like Iâve said, Iâve coded this game in another language which is no engine. There, I have to code a couple of procedures (was a basic language). One for unit-tracks, one for kind of particles, one for units, one for ⌠etc. There I had to take priority who many such procedures will become called and what content. I needed 1 month for optimizations. So I compare your batches like classes our routines which handels specific stuff. one for box-nodes, one for textured-box-nodes, one for text-nodes etc. If you mix up too much some classes/routines has to be called twice - thats what its meant to âbreak a batchâ, right? layers seems a way to handle that if I understand the docs and you right.
Is there any âbatchâ list, priority or anything to read for a deeper understanding or understanding at what âsituationâ a batch breaks?
What we are talking about really is the work of the GPU and OpenGL. Two things are involved here:
- Giving OpenGL instructions to set up the render state. Which shader should be used? Which texture? Which blend mode? And so on.
- Instructions sent to the GPU to draw a mesh. These are the draw calls.
The initial setup of the render state is expensive. Telling the GPU to draw a mesh isnât.
Defold will try to batch draw calls that have the same render state (ie the same texture, shader, blend mode etc).
When I write âbreak a batchâ what I really mean is that if we have a long list of things in the game (for instance sprites) that have the same properties they will all be drawn in a single draw call. This is good. BUT if I have one sprite with another material or with another blend mode and stick that into the middle of my long list of otherwise identical sprites then Iâm breaking the batch of draw calls. What would otherwise have resulted in 1 draw call now results in 3 draw calls. This is bad.
The documented that has already been linked previously covers this: Draw calls and Defold
To clarify:
Rendering of sprites, spine models, particle fx etc
- Rendering is based on z-order, back to front.
- Components on different depths will be batched unless one of the following is different from the previous component:
- Component type (sprite, spine, particle, label, model)
- Texture
- Material
- Blend mode, tint etc
- Collection proxies
- Note: Each particle emitter will result in a draw call
Rendering of gui scenes
- Rendering is based on the order of the nodes in the outline, depth first
- Nodes will be batched unless one of the following is different from the previous node:
- Node type (box, text, pie)
- Texture
- Blend mode
- Font
- Stencil settings
Layers are used to group different nodes to reduce the number of draw calls. Some images:
Big thanks @britzl!
Very detailed answer. Its principially what I thought and what I meant with my posting. Without an engine (only some sprite commands) you have to write your own âBatchesâ etc.
But now it is a clear thing what it is about.
As I asked for a âlist of breaking batchesâ its exactly that: âsprite with different textureâ etc.
Does your posting includes all states of breaking/changing a batch? Or are there much more âmistakesâ to make ?