godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.67k stars 20.11k forks source link

Render and export PNGs from AnimationPlayer #12240

Closed dodgyville closed 6 years ago

dodgyville commented 6 years ago

I'd love to export an animation to a series of PNGs for creating animated gifs and videos.

Alternatively, is there a way in gdscript to force a frame perfect function call that ignores speed so as to avoid frame skips? ie a non-realtime render.

This is what I'm using but it's unreliable.

extends Spatial

var images = []

func _ready():
    set_process(true)

func _process(delta):
    var image = get_viewport().get_texture().get_data()
    images.append(image)

func _on_AnimationPlayer_animation_finished( name ):
   var frame = 0
    for image in images:
        frame += 1
        image.save_png("res://images/output%04d.png"%frame)
~                                

~

Zylann commented 6 years ago

You could slow down the animation (or FPS) to increase the reliability of saving each frame ;)

dodgyville commented 6 years ago

Thanks for the suggestion Zylann. I will give it a go.

eon-s commented 6 years ago

AnimationPlayer can run on fixed mode while you get pictures on idle (process), I don't know if that will be fast enough, though.

fire commented 6 years ago

Some other software also renders to a size bigger than the screen and then stitch the pieces together.

For example your screen is 1080p and you want to render at 4k or 8k.

Zylann commented 6 years ago

If you want bigger than screen you can also render offscreen with a viewport I guess, no need to stitch

fire commented 6 years ago

Some other software also does panoramas, but that's a different goal. That in particular requires stitching and out of scope of this issue. Well, animated 3d gifs anyone :)

vnen commented 6 years ago

I fail to see the point of this request. What would you gain with such feature, in respect of game development?

dodgyville commented 6 years ago

Game development encompasses a lot of tasks.

Being able to have full size, frame perfect, uncompressed renders of a particular scene and animation sequence is important for commercial game makers and also experimental artists as the quality can not be faked.

For example, I would use it for HD trailers and animated gifs on social media.

Hope that helps, Luke

vnen commented 6 years ago

Game development encompasses a lot of tasks.

Yes, sure it does. But Godot never promised to do all of those tasks. You can't compose your game soundtrack in it, nor make your 3D models and textures, even though they are game development tasks. Well, you might even be able to make tools for that with Godot, but it's not available out-of-the-box.

I'm not saying this request should be dismissed because of that, I'm just saying that the argument is too vague.


Ideally this could be done only with GDScript in a plugin and distributed in the AssetLib. If there's something missing in GDScript to allow you to do that, then we can add something to it. For instance, if you run the animation manually, advancing step by step and capturing each frame, this could be reliably achieved, but I'm not sure if AnimationPlayer allows that. If it doesn't, it's something reasonable to add.

dodgyville commented 6 years ago

I meant it's not just about the playable game itself. There's sharing development, promotion/marketing, archiving and experimentation. IMO having a render and export feature for AnimationPlayer would be an extremely useful tool for the engine.

It's not quite like asking for a soundtrack composer, since godot is where the rendering and framerate of a project are controlled.

eon-s commented 6 years ago

Can be useful for small video captures that now are common, but maybe need something else and not animation player dependant, an external process perhaps...

dodgyville commented 6 years ago

Would love to be able to run the animation manually step by step in gdscript. That would give me control over the snapshot of get_viewport().get_texture().get_data()

NathanWarden commented 6 years ago

I definitely see a need for this type of functionality, but it seems much more suited for a plugin.

mhilbrunner commented 6 years ago

Closing this for now, as it seems conensus is overwhelmingly that this should be in a plugin, not core functionality.