Praytic / youtd2

Classic community-driven session-based Tower Defense game with RPG elements.
https://youtd2.com/
MIT License
87 stars 15 forks source link

Reduce VRAM usage #274

Closed Kvel2D closed 9 months ago

Kvel2D commented 9 months ago

VRAM usage has went up a lot since version 0.7, because of new tilesets. It was 0.8GB in version 0.7 and now it's 1.4GB in version 0.8. Should work on reducing it where possible.

For example, high VRAM usage causes crashes for some players: #273

Texture compression

2023-11-14 06_51_49-(_) GameScene tscn - YouTD 2 - Godot Engine None of the compression options are of any help.

Online tools like TinyPNG is same thing as Lossy compression - only reduces size on disk, doesn't reduce VRAM usage.

Empty space in tilesheets

We currently have a lot of unused space in tilesheets. 2023-11-14 07_02_39-GraphicsGale ver 2 08 24

The first thing we should do is remove equal amounts of space above all tile, using a script. This way, the tilesizes will still be equal to each other and setting up tilesets will still be easy. Later we can look into packing tilesheets tightly - but that will make setting up tilesets more complicated.

Also some tilesheets have empty tiles - should remove them.

2023-11-14 07_11_20-GraphicsGale ver 2 08 24

Packing tilesheets

Decoration tilesheets can be packed like creep spritesheets: 2023-11-14 07_35_40-folder Use PackSpriteSheet.gd script for that. Note that you need to fix the tileset after doing this.

Tileset duplication

We have two tilemap nodes - "Map" and "Decorations". We need two separate tilemaps because "Map" has tile size set to 256x128 and "Decorations" has tile size set to 64x32. This is so that tiles can be placed on the grid in "Map" but you can also do more flexible positioning of decoration tiles in "Decorations" tilemap.

When two different tilesets reference the same png, the png will be stored in VRAM twice. For example, the "Floor.png" has two tilesets and it's memory usage is doubled. 2023-11-14 07_05_20-Map tscn - YouTD 2 - Godot Engine Should avoid situations like this where possible.

Kvel2D commented 9 months ago

Disabling texture padding reduced VRAM usage by 50%: ddea2fd3eb449ee57b14db2827a4986489664510 Before: 1.5GB After: 0.75GB

Godot documentation says:

Disabling this setting might lead a small performance improvement https://docs.godotengine.org/en/stable/classes/class_tilesetatlassource.html#class-tilesetatlassource-property-use-texture-padding But for some reason, in our case it leads to huge performance improvement.

Kvel2D commented 9 months ago

Tried out prerendering the background here: https://github.com/Praytic/youtd2/pull/276

This reduced VRAM usage: 0.75MB->0.4MB

Note that I had to restore foreground map which made VRAM usage go up to 650MB again. WIll need to dedicate more time to removing unused tiles from foreground tileset.

Breakdown of current VRAM usage (using prerendered background):

Also note that tower sprites are dynamically loaded while the game is played and will consume VRAM. For reference, a single tower family (Tiny Shrub tier 1 through 6 for example) will consume around 3 MB with Lossless compression of the atlas. With VRAM compressed it will consume 1MB. Should think about switching to VRAM compression for all tower atlases but need to confirm if they look ok in game that way.

Kvel2D commented 9 months ago

Enabled VRAM compression for creep atlases: 9199a8867debbbc8a0face2115d8146c9fe34b5c 234bc2692f83c03e61d0381e7c7d99c5a0bf07cf

This reduced VRAM usage by creep sprites from 145MB to 45MB. Almost 4 times reduction, as expected.

Kvel2D commented 9 months ago

Had to disable VRAM compression for creep atlases - there are problems on Web export. Tried to fix it but couldn't figure it out. With "High Quality" enabled, you get "failed to load resource" errors in console and sprites don't draw at all. With "High Quality" disabled, resources appear to load but creep sprites draw only one frame and then disappear. There are also other settings related to VRAM compression in project settings and export config and I tried them but couldn't find a solution.

I also looked into using "Basis Universal" type of compression. It causes console to print these messages (not errors):

Basis universal cannot unpack level 1.

There is some discussion online but nothing conclusive. Decided not to proceed with this compression type because I don't understand the issue.

Kvel2D commented 9 months ago

Closing this because the biggest sources of VRAM usage were fixed and the game is back to VRAM usage levels from 0.7. Can tackle specific VRAM usage sources separately later, as needed.

Kvel2D commented 2 months ago

I've looked into Basis Universal again and it seems usable.

There is one caveat.

When using Basis Universal for textures used in tilesets, you need to disable "Use Texture Padding" option. Otherwise, the texture will appear empty and you will get spammed with console errors. 2024-07-06 21_04_39-map tscn - YouTD 2 - Godot Engine

Turning on Basis Universal for tilesheets also causes these console errors:

Basis universal cannot unpack level 1. These errors appear to be harmless and can be ignored.