Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polygon2D is extremely slow compared to Sprite rendering #19943

Open
bluepandion opened this issue Jul 3, 2018 · 10 comments

Comments

Projects
None yet
@bluepandion
Copy link

commented Jul 3, 2018

Godot version:
3.04

OS/device including version:
Windows 10 / Surface Pro 4

Issue description:
Polygon2D seems alarmingly slow when compared to Sprite or draw_rect().

Here are some results from a small test scene I made:
godot3_poly2d_performance

I've had the same results in a game project where I've attempted to create levels from Polygon2D objects. Usually optimized meshes would be very useful for optimizing fillrate, but this performance seems to make it impossible to utilize. I feel like this is going to hurt many graphically demanding 2D-projects.

Steps to reproduce:
Comparing between Sprite / Polygon2D and draw_rect() / draw_polygon() seems to give similiar results.

Minimal reproduction project:
polygon2d_performance.zip

@Zylann

This comment has been minimized.

Copy link
Contributor

commented Jul 3, 2018

Note: draw_polygon might require to recompute triangulation everytime, unless the polygon is retained and doesn't change (while sprites are trivial and dont require generic triangulation)

@bluepandion

This comment has been minimized.

Copy link
Author

commented Jul 3, 2018

Note: draw_polygon might require to recompute triangulation everytime, unless the polygon is retained and doesn't change (while sprites are trivial and dont require generic triangulation)

Every time update() is called or every frame?
Still, that shouldn't concern the attached reproduction project since it generates individual nodes instead of using draw_polygon().

@CptPotato

This comment has been minimized.

Copy link
Contributor

commented Jul 4, 2018

I also think for a few 2D sprites this is kind of slow in general. Though, I don't know the specs of OP's device.

@dragmz

This comment has been minimized.

Copy link
Contributor

commented Jul 4, 2018

It's not caused by triangulation in this case. A quick profiling shows that the multiple glBufferSubData and glDrawElements calls (from RasterizerCanvasGLES3::_draw_polygon) cause the FPS drop here.

@dragmz

This comment has been minimized.

Copy link
Contributor

commented Jul 6, 2018

I'm working on a PR that reduces the number of glBufferSubData calls by splitting canvas_render_items implementation into the following parts:

  1. Compute polygon data
  2. Send the polygon data to GPU (with a single glBufferSubData call per buffer)
  3. Execute render commands but use the already filled in buffers for rendering polygons.

Currently there is a per-polygon glBufferSubData call made and that hurts performance.

Some preliminary tests for the new approach seem to be promising (with ~4x FPS increase -> 240 vs 60 FPS).

@dragmz dragmz referenced this issue Jul 9, 2018

Closed

Fix GLES2 rendering performance #20077

4 of 4 tasks complete

@Chaosus Chaosus added this to the 3.1 milestone Aug 29, 2018

@reduz

This comment has been minimized.

Copy link
Member

commented Sep 7, 2018

did batching PR get merged in the end?

@akien-mga

This comment has been minimized.

Copy link
Member

commented Sep 10, 2018

No, #20965 was merged but was then reverted in #21204.

@akien-mga akien-mga removed their assignment Sep 10, 2018

@chanon

This comment has been minimized.

Copy link
Contributor

commented Oct 9, 2018

I am having a big problem with this now.

What I need to do is to be able to submit triangles as vertices with uvs using canvas_item_add_triangle_array many times per frame. (I will have many nodes that each will draw themselves by using canvas_item_add_triangle_array.)

However doing so with less than 100 calls on iOS results in less than 20 fps. (It goes down to less than 10 fps when I do it in my game, compared to 60fps with out those calls.)

It is disappointing to see that Godot 3 does not do any automatic batching.

I would actually want to try and fix this .. or maybe at least write a new add_triangle_array call that would batch them, or maybe use something else that doesn't get impacted by the multiple glBufferSubData calls.

However, I would like to ask first ... why is iOS using only GLES3?

I would like to implement this in only GLES2 which I thought was the recommended mobile renderer, however iOS is hardcoded to use GLES3?

@chanon

This comment has been minimized.

Copy link
Contributor

commented Oct 9, 2018

Just looking at #20077 speedup results:

Core i7-4790K, Intel 4600:

480 polygons: 325 vs 60 = 5,42
1920 polygons: 185 vs 19 = 9,74
7680 polygons: 77 vs 5 = 15,4
sprites: no change

Core i3-2310M, Intel 3000:

480 polygons: 60 vs 10 = 6
1920 polygons: 24 vs 3 = 8
7680 polygons: 7 vs 1 = 7
font rendering (using text_rendering.zip project attached below): 140 vs 10 = 14
sprites: no change

Android (Moto C):

font rendering: 57 vs 4 = 14,25

That is the difference between 2D polygons being actually useful or not.
I really wish that was merged, since 'full batching' hasn't been implemented and no one seems to even be working on it (?).

EDIT And looking at the code, it was a very well architected solution which would have been a great framework to later add batching. This and the other batching pull request, if combined into one would be perfect. (Then could optimize to reduce the number of flush calls to allow batching across canvas items.)

I don't know why there is such an all or nothing mindset though. reduz wants full batching so doesn't allow this PR even though it would be a good stepping stone. Then the batching PR gets completely reverted because of 9 patch rendering on Android instead of maybe just going back to old rendering for 9 patches?

@blurymind

This comment has been minimized.

Copy link

commented Mar 25, 2019

is the dragonbones runtime outperforming godot's polygon2d node?
sanja-sa/gddragonbones#5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.