Up to date

This page is up to date for Godot 4.0. If you still find outdated information, please open an issue.

Using a Viewport as a texture


This tutorial will introduce you to using the Viewport as a texture that can be applied to 3D objects. In order to do so, it will walk you through the process of making a procedural planet like the one below:



This tutorial does not cover how to code a dynamic atmosphere like the one this planet has.

This tutorial assumes you are familiar with how to set up a basic scene including: a Camera3D, a light source, a MeshInstance3D with a Primitive Mesh, and applying a StandardMaterial3D to the mesh. The focus will be on using the Viewport to dynamically create textures that can be applied to the mesh.

In this tutorial, we'll cover the following topics:

  • How to use a Viewport as a render texture

  • Mapping a texture to a sphere with equirectangular mapping

  • Fragment shader techniques for procedural planets

  • Setting a Roughness map from a Viewport Texture

Setting up the Viewport

First, add a Viewport to the scene.

Next, set the size of the Viewport to (1024, 512). The Viewport can actually be any size so long as the width is double the height. The width needs to be double the height so that the image will accurately map onto the sphere, as we will be using equirectangular projection, but more on that later.


Next, disable HDR and disable 3D. We don't need HDR because our planet's surface will not be especially bright, so values between 0 and 1 will be fine. And we will be using a ColorRect to render the surface, so we don't need 3D either.

Select the Viewport and add a ColorRect as a child.

Set the anchors "Right" and "Bottom" to 1, then make sure all the margins are set to 0. This will ensure that the ColorRect takes up the entire Viewport.


Next, we add a Shader Material to the ColorRect (ColorRect > CanvasItem > Material > Material > New ShaderMaterial).


Basic familiarity with shading is recommended for this tutorial. However, even if you are new to shaders, all the code will be provided, so you should have no problem following along.

ColorRect > CanvasItem > Material > Material > click / Edit > ShaderMaterial > Shader > New Shader > click / Edit:

shader_type canvas_item;

void fragment() {
    COLOR = vec4(UV.x, UV.y, 0.5, 1.0