Logo 3.5Cats_AndHalfAFish


Quickly rendering inventory icons in Godot.

March 10, 2021 Shade, Godot : image rendering

Note : Godot 3.2.3, Blender 2.83, Gimp 2.10.18.

While making the first game area playable, I came across the issue of how I'm going to create inventory icons.
My first idea was to make these inside Blender, but it seems a bit of a hassle to set up a new scene and add all models one be one ... Especially since I'm still in the early stages of making this game. So, I turned to Godot : would it be possible to quickly create an image I whenever I add a new asset to the game ?

As it turns out : yes, you can create images in Godot ... and it's not even hard or time consuming !

Keep in mind that what I'm showing below is not for my final images. So, I have not spent much time on lighting or making things look as good as they can. I'm only interested in creating icon images, as painlessly as possible.

Godot : setup for creating inventory icons.
Godot : setup for creating inventory icons.

As you can see, the setup is very simple : a viewport, 2 lights, the item I want to create the icon for (as a child of the 'hook'), a camera, and a Timer (used in the script attached to the root node).

I'm using the viewport mostly to be able to set a custom camera size without having to change the size in the project settings. In this particular setup, I'm using 100x100 px.
I've also created a WorldEnvironment node for the camera. This is useful for defining background, lighting, etc.

If you switch from the 3D view to the 2D view (where I expected the camera view to be visible), you will see ... nothing. That is because a viewport node/ camera setup renders to a texture, and we're not actually doing anything with that texture.
So, there are 2 ways to visualize what the camera is seeing :

1) With a TextureRect node :

Godot : TextureRect node visualizing.
Godot : TextureRect node (2D view).

Just some simple setings to take care of :

Godot : setup with TextureRect node.
Godot : setup with TextureRect node (2D view).

2) Or with a ViewportContainer node :

Godot : setup with ViewportContainer node.
Godot : ViewportContainer node (2D view).

This setup is even simpler. Just make the viewport (and all nodes under it) a child of the viewport container.

You can use either of these 2 methods to set a good Fov for the camera (a close up of the item).
Note : checking the 'preview' checkbox for the camera doesn't seem to give a realistic view of the scene ... I expected this to work as well (but it doesn't).

This is the short script I'm using to write the textures to the hard disk as png files :

Godot : code for taking snapshots.
Godot code : taking snapshots.

Important : add the 'tool' line to the top of the script. This way, the script will run in the editor (you don't even have to press F6).
When the script doesn't seem to run (which sometimes happens), you can try one of these things (they usually fix the issue) : save all scenes, or, close the scene and reopen it, or, minimize and maximize Godot.

So. What does this simple script do ?
In the process function, we check if the escape key has been pressed (can be any key you like). If so, we execute the create_icon method where the viewport texture is saved to file.
The Timer node used in this script, is to make sure that only one image per second can be taken (see what happens if you don't).

One more thing to mention : the icon background.
If you want a colored background, you can use a background mesh with a material, or you can set a color in the WorldEnvironment of the camera ('mode') :

Godot : world environment setup.
Godot : world environment setup.

I have the background mode set to 'clear color' here. This color is defined in the project settings > general > rendering > environment > default clear color (a light grey). But you can also pick a random color ('custom color'), or use the 'sky' color.
You can also set the background to be transparent. This is done in the Viewport node settings :

Godot : Viewport node transparency.
Godot : Viewport node transparency.

You might be confused as to why the saved image looks different from what you see in the editor ... It certainly puzzled me. =)
But, after checking all settings I could think of, and after checking the web, the penny finally dropped : the background is black ! And 'black' is kind of like transparent, if you use it with 'add' instead of 'mix'.
The proof :

Godot : Viewport node transparency (2).
Godot : Viewport node transparency (2).

1) The item as seen in the editor (light grey background).
2) The file saved to hard disk (black background).
3) Adding the saved file to the Inventory as a TextureRect (gui Control node as scene root).
4/5) With the TextureRect selected, go to the CanvasItems section in the inspector. Add a new CanvasItem material and set its blend mode to 'add' (was 'mix').

Good. Now I can finally get back to what I was doing before. =)