I believe the performance of Godot can benefit from minimizing drawcalls via static and dynamic batching support.
Here's what I found out from the 5000 sprites benchmark :
Unity 5: 50001 drawcalls, 173 fps
Godot: 50001 drawcalls, 175 fps
By turning off dynamic batching feature, Unity 5 and Godot has almost identical fps.
Unity 5: 2 drawcalls, 278 fps
Godot: n/a
Urho3D; ? drawcalls: 785 fps
WIth Dynamic batching, the drawcalls could be dramatically reduced hence the improvement of fps on Unity 5.
Reference:
Dynamic and Static Batching in Unity
OpenGL Batch Rendering
Sprite Batching in OpenGL ES 2.0
SpriteBatch in libgdx
CCSpriteBatchNode in cocos2d-x
Batch in Urho3D
The drawing code in Godot has been rewritten recently to allow
optimizations such as this. Dynamic batching could be added now, but I
think there are other, more interestig, optimizations that can be attempted
first. This is why having benchmarks is vital :P
On Thu, Mar 19, 2015 at 2:10 PM, marynate [email protected] wrote:
I believe the performance of Godot can benefit from minimizing drawcalls
via static and dynamic batching support.Here's what I found out from the 5000 sprites benchmark
https://github.com/marynate/godot.benchmark :
- Testing 5000 sprites on screen without dynamic batching:
Unity 5: 50001 drawcalls, 173 fps
Godot: 50001 drawcalls, 175 fpsBy turning off dynamic batching feature, Unity 5 and Godot has almost
identical fps.
- Testing 5000 sprites on screen with dynamic batching:
Unity 5: 2 drawcalls, 278 fps
Godot: n/aWIth Dynamic batching, the drawcalls could be dramatically reduced hence
the improvement of fps on Unity 5._Reference_:
Dynamic and Static Batching in Unity
http://docs.unity3d.com/Manual/DrawCallBatching.html
OpenGL Batch Rendering
http://www.gamedev.net/page/reference/index.html/_/technical/opengl/opengl-batch-rendering-r3900
Sprite Batching in OpenGL ES 2.0
http://antonholmquist.com/blog/sprite-batching-opengl-es-2-0/
SpriteBatch in libgdx
https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/SpriteBatch.java
CCSpriteBatchNode in cocos2d-x
https://github.com/cocos2d/cocos2d-x/blob/8716164a5d95480b7d61d114c215b4c4cb762077/cocos/2d/CCSpriteBatchNode.cpp
Batch in Urho3D
https://github.com/urho3d/Urho3D/blob/90833996fa797d6ecbac27ed78123b85fb974b42/Source/Urho3D/Graphics/Batch.cpp—
Reply to this email directly or view it on GitHub
https://github.com/okamstudio/godot/issues/1527.
@reduz have you started working on your optimization magic? :)
Nope, 1.1 comes first.. Are there enough benchmarks for doing optimization?
On Apr 6, 2015 1:28 PM, "marynate" [email protected] wrote:
@reduz https://github.com/reduz have you started working on your
optimization magic? :)—
Reply to this email directly or view it on GitHub
https://github.com/okamstudio/godot/issues/1527#issuecomment-90133222.
any progress with this request?
The only thing that stops me from developing with Godot is this.
Looking for benchmarks (something most people do when looking for a new engine) I've found that Godot lacks of sprite batching (try the bunnymarks numbers for comparing engines: https://www.youtube.com/watch?v=bmk9bmBfjX0
https://github.com/colludium/bunnymark-tests ).
I hope that sprite batching could be implemented within the 3.0 version
Edited: wrong link, to many open tabs
That benchmark only shows that GDScript is slow, it doesn't have much to do with rendering bottlenecks.
The lack of sprite batching is quite limiting if you are looking to create low end mobile games.
Even an alternative, such as the multi-mesh node, would be useful. Built in dynamic batching would be best though for new godot developers.
not only low end mobile games but low end pcs too i need this feature too my game cant handle a 200x200 tile map wihout dropping the fps from 60 to 30 when zoom out (all displayed at once on screen)
+1 for batching - fingers crossed
As @eons suggested on discord i am attaching the project files with the Map Generator to help devs to see the issue and maybe point to a solution or the implementation of the batching (v.3.0 beta1)
Map Generator fps.zip
I have tried the map generator and replacing the sprites with simple Node2D I get the same performance issues, trying to discard a debugger issue tested with Node too but these do not affect performance, only CanvasItems (with and without textures) seems to be the problem here.
Well, tested with release builds (release and debug) and both run at 60fps with 40k sprites (double than editor run), something is being added by the editor and not just the number of nodes is what affects it.
I have done some windows builds and running off the editor in my tests the fps are the same from editor or from the exported run both are decreasing the fps as camera zoom out (many sprites on screen)
Maybe godot engine can add Sprite-Batch based drawing API for 2D, like what it can do in MonoGame or DirectX2D:
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(textureBall, new Vector2(0, 0), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
Code example are from http://www.monogame.net/documentation/?page=adding_content
It's also easy to add custom blending factors.
When you have to dynamic draw tilemaps (e.g. create a game like LegendOfMir), it seems much easier to draw 2D the Sprite-Batch way than the node-based way.
For the above case, there's the Tilemap node.
But I would still like to know the status of dynamic batching?
Default tilemap node is not capable, since the map is not manually created in tilemap editor, it’s defined in custom map data, and so are the cell textures, the only to do is to create your own tilemap node with Godot custom module.
The key point:
In node-based 2d drawing, blending or shader relys on canvas item nodes or canvas item created with VisualServer.
But in the LengendOfMir game, blending or shader must be able to changed on every few texture draw-calls, just the feature the common SpriteBatch API provided.
And with GodotEngine, there’s no full blend control.
So node-based drawing has great convenience on creating games in Game Editor, but it also lose convenience SpriteBatch-based provided.
It’s really hard to create a game like LegendOfMir with GodotEngone.
Such an old issue... I will be working on this for Godot 4.0 by the way for the GLES2 renderer. Vulkan will probably not need it given how it's going to be implemented.
@ryancheung if you change the shader, the blending function or the texture batching won't work because you need to modify the opengl state and you'll need to start a new batch per change.
Batching is used because it creates 1 draw-call which will draw as many objects as you give it with one set of parameters. If you start modifying those parameters for every object you lose any benefit batching will give you.
@mrcdk It's OK to end previous batch and start new batch, since we don't need put all draw calls in one batch. Given I have 100 draw calls, it may be split to two batch, one 30, another 70 draw-calls.
I put some wrong words in previous post, it should be blending or shader must be able to changed every few draw-calls.
So, when this will be implemented for both GLES 3 and GLES 2? Even the 3D platformer demo (which is really simple) runs bad. This is probably the only thing preventing me from using Godot full time.
@yusdacra For 3D it will never be implemented, if you have bad performance in the 3D platformer demo it's probably related to something else.
Godot 4.0 will come with more advanced tools to measure better where your performance is being taken.
For some background:
My opinion is that batching aka mesh merging should be done at content creation time or as a editor plugin, but not at runtime.
The merging operation takes multiple minutes for a large 3d scene and that's not feasible to do at runtime.
Probably covered by: #37349
@red1939 That pull request only implements batching in 2D and when using the GLES2 renderer.
reduz has plans to further implement automatic instancing in the Vulkan renderer in both 2D and 3D so larger amounts of instances can be drawn.
Good to know! Will it be considerably different than sort & group by state
(texture, model, material, blending) + uber_shader.draw()?
On Tue, 12 May 2020 at 09:31, Hugo Locurcio notifications@github.com
wrote:
@red1939 https://github.com/red1939 That pull request only implements
batching in 2D and when using the GLES2 renderer.reduz has plans to further implement automatic instancing in the Vulkan
renderer in both 2D and 3D so larger amounts of instances can be drawn.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/godotengine/godot/issues/1527#issuecomment-627166542,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ADNME2BYTU4KYLKMXDI6EYTRRD3NHANCNFSM4A6F5BXA
.
Fixed by #37349. This will be ported to GLES3 too, and should be included in Godot 4.0 as well.
Most helpful comment
The lack of sprite batching is quite limiting if you are looking to create low end mobile games.
Even an alternative, such as the multi-mesh node, would be useful. Built in dynamic batching would be best though for new godot developers.