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

[3.5] possible performance regression with TileMap #64552

Closed
tehsquidge opened this issue Aug 18, 2022 · 7 comments
Closed

[3.5] possible performance regression with TileMap #64552

tehsquidge opened this issue Aug 18, 2022 · 7 comments

Comments

@tehsquidge
Copy link

tehsquidge commented Aug 18, 2022

Godot version

3.5.stable

System information

OpenGL ES 3.0 Renderer: AMD Radeon RX 6700 XT (navy_flounder, LLVM 14.0.6, DRM 3.46, 5.18.17-1-MANJARO)

Issue description

Hey,

So I believe there may be a performance regression involving the TileMap. I've noticed this this occurs when calling set_cell/set_cellv as well as update_bitmask_region. If either of these are called the performance issue is present.

The performance issues don't occur as long as I don't modify the TileMap. The bullet keeps hitting the tilemap and generating particles without any issues (although it doesn't mine through of course). I'm hoping this rules out issues with physics or rendering.

I've provided an example below. I'm unsure of what other information I can provide. Let me know and I'll try and add it.

Example

3.5
2022-08-18 00-32-22.webm

Hopefully you can see the frame drops here.

3.4.5
2022-08-18 00-34-26.webm

With 3.4.5 there is no frame drops.

Steps to reproduce

Any call to set_cell/set_cellv as well as update_bitmask_region should be significantly slower in 3.5 compared to 3.4.5.

Minimal reproduction project

#64552 (comment)

@Calinou
Copy link
Member

Calinou commented Aug 18, 2022

@tehsquidge Can you reproduce this in any of the 3.5 betas and RCs to determine when the regression started?

@tehsquidge
Copy link
Author

Hey,

I've worked through the RCs to see when started. Everything works as expected in RC3 and the problems appear in RC4.

I was looking to try and make a minimal reproduction project - but with it being so minimal I'm unable to demonstrate it well.

Cheers!

@tehsquidge
Copy link
Author

I took a look at the diff between those RCs and the big change I can see is in navigation.

I have it running as expected now. I had to make sure "Bake Navigation" was off. I also, in trying to track down the problem, removed other navigation elements which I no longer needed - so that could have helped too. So, my fix was make sure the tile map had no sort of navigation on it at all.

It looks like there is a larger cost now to recalculating the navigation on tile maps?

Thanks!

@smix8
Copy link
Contributor

smix8 commented Aug 18, 2022

A change in tiles / layers with baked navigation triggers not only navmesh updates but entire recalculations for the navmesh region connections on the NavigationServer. If too many navigation regions are involved a framedrop is expected.

Since it is a 2D game with TileMap I expect that it is using a small cellsize / pixelsize and also creating a navigationregion for each Tile by using baked navigationpolygons in the Tiles. Without a MRP project I can only guess but I am very certain that in the background it is creating 1000-10000+ navigation regions that are updating everytime a navigation Tile is changed which results in the lag.

Plans are to add some additional dirty_flags to SceneTree nodes to block repeated, redundant updates in the same frame that are triggered by navigation changes as they can flood the NavigationServer process_queue for no gain. The core of the problem here is how baked_navigation Tiles are handled / created / updated by the TileMap itself in both 3.5 and 4.0 which needs a full rework.

For now the solutions are that users are more mindful with their tileupdates, split their navigation maps into sectors instead of creating a giant navigation map with so many regions, or stop using baked navigation tiles and use a far more performant navigationpolygon to cover the same areas.

@tehsquidge
Copy link
Author

@smix8 What you're describing makes sense. If I do need use navigation maps I'll probably go with your suggestion of breaking them down into regions.

I've attached a MRP just in case you want to check.
TileMapRegTest.zip

@smix8
Copy link
Contributor

smix8 commented Aug 18, 2022

@tehsquidge The navigation region updates happen per navigation map so you need to create and switch to different maps with the NavigationServer API if you want to reduce the performance cost of each map update. I guess the best way for your 2D sidescroll project could be to use one large NavigationPolygonInstance and update the polygon every few frames when you make terrain changes. Since it is only a single large polygon that gets changed on the NavigationServer the update will be always instant. The way TileMap baked navigation work it will give you a lot of performance issues in your gametype with changeable terrain.

@tehsquidge
Copy link
Author

@smix8 Thanks for this. It's really informative :)

It's sounds like even prior to 3.5 I wasn't doing it in a particularly performant way and changes to 3.5 just made the problem more obvious. You've given me a lot to work with in terms of a better solution so I'll close this issue.

Cheers!

@Calinou Calinou removed this from the 3.x milestone Aug 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants