How To Create a Icon Texture from a Scene

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Supatier

I need to create an icon for a button from a scene, is there anyway of creating it in godot without using screenshots?

Thank you

Can only think of Screenshot related solutions so will reserve an answer provided you don’t get a better one

Wakatta | 2023-02-21 02:49

Is it a 3D scene?
Then you can use Orthagonal or Perspective shot?
Or 2D scene?

I’m guessing you’re wanting to “render” a scene to a single image because of resolution limits of a screenshot? e.g. you want a 4K vs a 1440p image?

3D: If you’re on Godot 4, you could export the scene as a GTLF scene and import into Blender and do it that way.

If you’re trying to use a scene as an icon for a button inside another godot scene then you can use Camera and Viewport to achieve this. This may impact performance so it’s better to export to an image first if the image doesn’t need to be live regenerated.

TheNormandyProject | 2023-02-21 11:58

@ TheNormandyProject had the exact same thinking to use a Viewport container so if there exists a camera in the scene any type 2D or 3D can be linked.

Got the idea from an internal plugin called MeshEditor. Problem is though, just as you’ve said the image is better exported (saved) because ViewportTextures do really wierd things even when duplicated

Wakatta | 2023-02-21 14:23

:bust_in_silhouette: Reply From: Supatier

Okay, here’s what i did
First setup your scene like this, apple being the mesh i want to get a screenshot of. Make sure the parent is of type SubViewport.
this

If you have multiple meshes it would look like this. Just be sure the meshes don’t stack over each other.
enter image description here

Then attach this script to the root of the node. Then run the scene.

extends Node

func _ready() -> void:
	_generate_icon()

func _generate_icon():
	for child in get_children():
    	await RenderingServer.frame_post_draw
		var img = child.get_texture().get_image()
		img.save_png("res://icons/" + child.name +".png")
:bust_in_silhouette: Reply From: PolyBytes

Supatier’s answer is almost perfect but I felt the need to add this so others who come across this topic aren’t pulling their hair out like I have been because their icons are generating blank or just a black texture.

The one nugget of information that was left out here is that in each of your SubViewport nodes you must set the Render Target > Update Mode to something OTHER than the default When Visible.

I tried Always, When Parent Visible, and Once and all of those worked like a charm in my case.

Thank you for the otherwise really helpful solution!

v4.0.3.stable.mono.official [5222a99f5]