-
-
Notifications
You must be signed in to change notification settings - Fork 21.5k
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
Massive performance issue in 2D viewport when zooming out on huge TileMap #85871
Comments
What do you mean by "horrible performance"? Can you provide a bit more info about what you are using to measure performance and what numbers you are getting? |
There is no tool used, when I move the map with middle mouse button it's laggy. |
I can confirm the issue, which is caused by a pathological case of a humongous tilemap with 1873319 16x16 tiles. The more tiles are in view, the lower the FPS when moving the viewport. With GL Compatibility, I get around 7 FPS when panning the view on a Radeon RX Vega M on Linux (Mesa 23.1). When I click the TileMap node and the "grid" gizmo is shown on a portion of the map, the FPS drops further to 1-2 FPS. With Forward+, I get 1-2 FPS (or likely less) in both scenarios. Increasing the rendering quadrant size from 16 to 128 doesn't seem to help. |
Well, at some point there's kind of no way for to ensure good performance with an infinite amount of tile. Displaying 2 millions tiles at once should already be taxing on any hardware. I am not sure what should be the limit here, we can't chase performance improvement forever. Here, I suspect the most taxing part is probably the grid drawing. We could probably disable it after a given zoom level or something, but users might complain their grid does not draw anymore. |
The grid should definitely be greatly simplified when zooming out, it makes no sense to have such a performance heavy fine mesh as far away zoom levels. It can be replaced by a simple rect probably to still show where the mouse focus is, if that's useful. And transitioned back to a grid when reaching a zoom level where it makes sense. But even without grid I have 7 FPS. I wonder if some batching or picking low res mipmaps might help. Alternatively, I was joking about it on chat, but at such zoom levels, it could make sense to replace the dynamically rendered tilemap by a single static texture... If it's going to take 1/7th of a frame to render it again, we can as well render it once to a ViewportTexture and apply it as a plain background texture. Of course this wouldn't allow editing the tilemap, but I don't think this should be supported at such zoom level. Zooming out is useful to navigate / get an overview of the whole map, it shouldn't be a problem if it's read-only. |
That is an interesting solution, but I fear that people might be annoyed if they cannot, like, copy-paste huge parts of the map. TBH, I feel like the editor is already a complex enough beast. If we can avoid additional checks about being at a given zoom level, that's better IMO. So I think disabling the grid, or simply replace it by a localized grid around the cursor should probably be good enough for now. Then for further optimizations, I'd prefer we figure out a way to optimize the underlying layers (likely the rendering servers parts), rather than making more complex the Tilemap node and/or the TileMap editor. But in general, I think we kind of have to set ourselves what we consider an "acceptable" level of performance anyway. Because with that kind of test projects, it's kind of easy to find a point where things would break (you simply have to add tiles until performance becomes bad 🤷 ). You can't really expect to have hundreds of millions of tiles and still expect things to work, whatever the game engine I mean. Eventually, I'd like us to have some sort of a chunk system, for dynamic loading of big maps, but for now, users should replace that by splitting their TileMaps into smaller ones. |
I think this is two different issues for me, I tried to check and get more info on this using Mangohud to check fps, but it does not work with "Forward+". |
Well this doesn't seem to be a bug. The Compatibility renderer is more lightweight, so it's faster. Advanced features found in the Forward+ renderer come at a performance cost. |
For what it's worth I poked around a bit and though I don't expect 2 million tiles to render very quickly, the performance is also very bad when even when zoomed in if the tilemap was selected. The grid in this case is not heavy at all (tested by disabling the grid in the editor settings) but this block of code is extremely slow. Building a version of godot with it commented out makes zoomed in performance even with this large tilemap acceptable. Assuming the MRP above doesn't have invalid IDs I'm not even sure this block of code actually does anything apart from cause slowdown. godot/editor/plugins/tiles/tile_map_editor.cpp Lines 4041 to 4092 in a311a4b
|
That's quite interesting. The problem may be the I can have a look. |
I investigated the issue a bit, and I know what is happening. What makes panning/zooming slow is the fact the TileMapEditor drawing has to fetch data from the TileSet when drawing things. Basically, it will have to check for invalid tiles every time you move the view, which is a bit time consuming as in needs to access the TileSet data, which is stored into an HashMap. There are two issues:
I think that, to solve this issue, we should probably cache the data about the tile being valid or not somewhere. This is however hard to do without modifying the TileMap itself, which I'd rather avoid instrumenting for the editor uses only. I think the best solution for now might be to find a way to simply cache whether or not invalid tiles exists in the TileMap, as a boolean. That could be done at the TileMap level without being too invasive I believe. |
Edit: this is a separate issue #84591, thank you @akien-mga I would like to add a quick data point. In 4.2 I am getting 1-2fps but in 4.1.3 I have >60fps. Hardware: Macbook Air M1 |
I have found a temporary solution to this problem it may not solve all the possible problems but it solves mine: |
The new ARG separates out the workloads to make it easier to visualise where the performance issues are. As I suspected, a massive amount of overhead is draw calls: Note On my MacBook Pro M1 Max, when zoomed out, I get about 4-5 FPS with Metal, and with MoltenVK I get < 1 FPS, which is a really great indicator of the lower overhead we will gain accessing Metal directly. This makes me want to explore batching in 2D 😊 |
Can you try this when the next dev build lands given #92797 has landed |
Tested versions
Tested on 4.2 stable mono
Also tested with custom build #84963 (compiled my self)
System information
Godot v4.2.stable.mono - Ubuntu 23.10 23.10 - Wayland - Vulkan (Forward+) - dedicated Intel(R) Arc(tm) A770 Graphics (DG2) () - AMD Ryzen 7 2700X Eight-Core Processor (16 Threads)
Issue description
I am getting horrible performance on "Forward+" compared to "Compatibility" with large tilemap,
at first, I thought this was a driver issue so I tried intel mesa drivers and the latest Ubuntu repa mesa drivers but none of these solved the problem then i tried with Custom Build(#84963 ) but that didn't solve the problem.
That being said it is slow with Compatibility but not horrible(on forward it can escalate into a crash..). The most noticeable slowness appears with Zooming out when zoomed in the slowness disappears.
Selecting the Tilemap node will create the same lag.
Steps to reproduce
Create a large tilemap and zoom out this will create the issue.
Minimal reproduction project (MRP)
TestTileMapLag.zip
The text was updated successfully, but these errors were encountered: