godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Add a random start property to AnimatedTexture (or improve TileSet animation performance) #8329

Open LeeWannacott opened 1 year ago

LeeWannacott commented 1 year ago

Describe the project you are working on

High Resolution Top down 2d game...

Basically, I want to animate water tiles with random start times at acceptable performance levels.

Using animated tileset/spritesheet gives ~120fps; However this option allows me to randomly start each tile which looks much nicer in my opinion.

Using animatedTexture gives ~1200fps, but all tiles play at the same time.

Note for animated tileset: options such as speed or Mode (default vs random start) doesn't seem to have a material effect); so, I assume its not the randomizing of tiles that is causing relatively bad performance.

Animated texture ~1200fps (but can't randomly start individual tiles)

https://github.com/godotengine/godot-proposals/assets/49783296/531cf254-cca7-4c40-9d5c-58ab3086a3db

Animating from tileset (animated from a spritesheet) ~120fps; can randomize individual tiles start time :

https://github.com/godotengine/godot-proposals/assets/49783296/8571bcb6-1488-42d5-ba6c-f5f819c54ce5

I tried out two approaches to my problem:

Animating tileset (animated from a spritesheet): image

AnimatedTexture: image

Tested on: 5900x and 6800xt

Describe the problem or limitation you are having in your project

I want to have ocean tiles that start their animation at random times (as it looks nicer) and also have acceptable performance, not just on my machine, but also on PC's less powerful...

Describe the feature / enhancement and how it helps to overcome the problem or limitation

I propose either improving the performance of animated tiles from a tileset, or adding the option to randomize each individual tile with animated texture.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

For example: Add a similiar mode in texture dropdown as tileset animation has for random start. image

If this enhancement will not be used often, can it be worked around with a few lines of script?

Possibly?, I welcome suggestions on how to implement this. Animated texture only gives you the current frame and randomizing current frame does it for all tiles, not individual tiles.

Is there a reason why this should be core and not an add-on in the asset library?

Above my pay grade :shrug: . I don't think it would make sense as an add-on...

Calinou commented 1 year ago

cc @rakkarage

The issue with AnimatedTexture is that it's a resource that is shared across all drawn tiles, so randomizing its start offset wouldn't help in your particular case unless you create a few variants (4-8) and place them randomly in your TileMap as different tiles.

LeeWannacott commented 1 year ago

The issue with AnimatedTexture is that it's a resource that is shared across all drawn tiles, so randomizing its start offset wouldn't help in your particular case unless you create a few variants (4-8) and place them randomly in your TileMap as different tiles.

I did think of trying this it sounds doable, However, not really ideal when you want to have maybe 4 variants for oceans which would each need 4+ varied rate AnimatedTexture; I think it could quickly get out of hand... and I'm not sure how it would look. I could try it out though... :thinking:

The issue with AnimatedTexture is that it's a resource

Maybe a potential solution could be chunking the main resource up into multiple sub resources (that are animatedTextures) at runtime with various starting frames and each having their own allocation of tiles (from the main resource) to draw. Just an idea :thought_balloon: ; might be dumb in practice...

dalexeev commented 1 year ago

Also note that AnimatedTexture is marked as deprecated.

LeeWannacott commented 1 year ago

Warning: The current implementation is not efficient for the modern renderers.

Also note that AnimatedTexture is marked as deprecated.

Do you know what they are planning to replace it with?, or any efficient alternatives?

If it's TileSet animation that is planned, then it might be good to have the one shot feature of the animatedTexture, for example weather effects; lets say you have an animation for snow falling that turns each corner of the tile into snow until it becomes a snow tile etc. You could also achieve this by having sub tiles within a tile, but Id imagine it would be complicated to implement...

Also the user experience for TileSet animation isn't great when you have many tiles (in my opinion) . Having to manually add 64 frames isn't the best experience. I don't see why after specifying columns you couldn't have a frames parameter that adds those frames on and you can still modify each frames time.

unless you create a few variants (4-8) and place them randomly in your TileMap as different tiles.

I tried this out doesn't get great performance, or look that nice... and yeah you can't use the exact same tiles for each variant you have to use different images; get around 500fps... I thought VRAM compressing the images might help, but nope : /

Calinou commented 1 year ago

I thought VRAM compressing the images might help, but nope : /

The bottleneck isn't memory bandwidth, it's having to constantly upload new textures to the GPU continuously (which implies frequent CPU-GPU roundtrips). It's strongly suggested to do animation using shaders that modify UV over time instead.

LeeWannacott commented 1 year ago

The bottleneck isn't memory bandwidth, it's having to constantly upload new textures to the GPU continuously (which implies frequent CPU-GPU roundtrips).

Yeah, I thought VRAM compression would mean your images are in VRAM so the GPU can access them directly without hitting ram and CPU. Clearly, my understanding is wrong...

It's strongly suggested to do animation using shaders that modify UV over time instead.

I was trying to avoid writing a shader, it might be simple for cycling through some images though :shrug;, or do you mean having dynamic water using math? I tried to get animated water working from various shaders on godot shaders, I couldn't get many working and the ones that I could either didn't look appropriate, or/and crippled performance especially those designed for 3d ones.

slightly off topic: I feel like I'm hitting so many issues I have to work around... would you say that godot is appropriate for an ambitous 2D game in the vein of say dwarf fortress, factorio, rimworld, songs of syx, or is it meant for smaller games, or just needs more dev time?

Calinou commented 1 year ago

I was trying to avoid writing a shader, it might be simple for cycling through some images though :shrug;, or do you mean having dynamic water using math?

Both approaches are viable, though it seems you want to go for premade images if you want more artistic control.

slightly off topic: I feel like I'm hitting so many issues I have to work around... would you say that godot is appropriate for an ambitous 2D game in the vein of say dwarf fortress, factorio, rimworld, songs of syx, or is it meant for smaller games, or just needs more dev time?

Every complex game has engine issues to work around, no matter which engine you use. Gamedev is a game of workarounds :slightly_smiling_face: