Using Viewports
Introduction
Think of aViewport as a screen onto which the game is projected. In orderto see the game, we need to have a surface on which to draw it. That surface isthe Root Viewport.

SubViewports are a kind of Viewport that can be added to the scene so that thereare multiple surfaces to draw on. When we are drawing to a SubViewport, we call it a render target. We can access the contentsof a render target by accessing its correspondingtexture.By using a SubViewport as render target, we can either render multiple scenes simultaneously or we can render toaViewportTexture which is applied to an object in the scene, for example a dynamicskybox.
SubViewports have a variety of use cases, including:
Rendering 3D objects within a 2D game
Rendering 2D elements in a 3D game
Rendering dynamic textures
Generating procedural textures at runtime
Rendering multiple cameras in the same scene
What all these use cases have in common is that you are given the ability todraw objects to a texture as if it were another screen and can then choosewhat to do with the resulting texture.
Another kind of Viewports in Godot areWindows. They allow their content to be projected onto a window. While the Root Viewport is a Window, they are lessflexible. If you want to use the texture of a Viewport, you'll be working withSubViewports most of the time.
Input
Viewports are also responsible for delivering properly adjusted andscaled input events to their children nodes. By defaultSubViewports don'tautomatically receive input, unless they receive it from their directSubViewportContainer parent node. In this case, input can bedisabled with theDisable Input property.

For more information on how Godot handles input, please read theInput Event Tutorial.
Listener
Godot supports 3D sound (in both 2D and 3D nodes). More on this can befound in theAudio Streams Tutorial. For this type of sound to beaudible, theViewport needs to be enabled as a listener (for 2D or 3D).If you are using aSubViewport to display yourWorld3D orWorld2D, don't forget to enable this!
Cameras (2D & 3D)
When using aCamera3D orCamera2D, it will always display on theclosest parentViewport (going towards the root). For example, in thefollowing hierarchy:

CameraA
will display on the RootViewport and it will drawMeshA
.CameraB
will be captured by theSubViewport along withMeshB
. Even thoughMeshB
is in the scenehierarchy, it will still not be drawn to the Root Viewport. Similarly,MeshA
will notbe visible from the SubViewport because SubViewports onlycapture nodes below them in the hierarchy.
There can only be one active camera perViewport, so if there is morethan one, make sure that the desired one has thecurrent property set,or make it the current camera by calling:
camera.make_current()
camera.MakeCurrent();
By default, cameras will render all objects in their world. In 3D, cameras can use theircull_mask property combined with theVisualInstance3D'slayerproperty to restrict which objects are rendered.
Scale & stretching
SubViewports have asize property, which represents the size of the SubViewportin pixels. For SubViewports which are children ofSubViewportContainers,these values are overridden, but for all others, this sets their resolution.
It is also possible to scale the 2D content and make theSubViewport resolutiondifferent from the one specified in size, by calling:
sub_viewport.set_size_2d_override(Vector2i(width,height))# Custom size for 2D.sub_viewport.set_size_2d_override_stretch(true)# Enable stretch for custom size.
subViewport.Size2DOverride=newVector2I(width,height);// Custom size for 2D.subViewport.Size2DOverrideStretch=true;// Enable stretch for custom size.
For information on scaling and stretching with the Root Viewport visit theMultiple Resolutions Tutorial
Worlds
For 3D, aViewport will contain aWorld3D. Thisis basically the universe that links physics and rendering together.Node3D-based nodes will register using the World3D of the closest Viewport.By default, newly created Viewports do not contain a World3D butuse the same as their parent Viewport. The Root Viewport always contains aWorld3D, which is the one objects are rendered to by default.
AWorld3D canbe set in aViewport using theWorld 3D property, that will separateall children nodes of thisViewport and will prevent them from interacting with the parentViewport's World3D. This is especially useful in scenarios where, forexample, you might want to show a separate character in 3D imposed overthe game (like in StarCraft).
As a helper for situations where you want to createViewports thatdisplay single objects and don't want to create aWorld3D, Viewport hasthe option to use itsOwn World3D. This is useful when you want toinstance 3D characters or objects inWorld2D.
For 2D, eachViewport always contains its ownWorld2D.This suffices in most cases, but in case sharing them may be desired, itis possible to do so by settingworld_2d on the Viewport through code.
For an example of how this works, see the demo projects3D in 2D and2D in 3D respectively.
Capture
It is possible to query a capture of theViewport contents. For the RootViewport, this is effectively a screen capture. This is done with thefollowing code:
# Retrieve the captured Image using get_image().varimg=get_viewport().get_texture().get_image()# Convert Image to ImageTexture.vartex=ImageTexture.create_from_image(img)# Set sprite texture.sprite.texture=tex
// Retrieve the captured Image using get_image().varimg=GetViewport().GetTexture().GetImage();// Convert Image to ImageTexture.vartex=ImageTexture.CreateFromImage(img);// Set sprite texture.sprite.Texture=tex;
But if you use this in_ready()
or from the first frame of theViewport's initialization,you will get an empty texture because there is nothing to get as texture. You can deal withit using (for example):
# Wait until the frame has finished before getting the texture.awaitRenderingServer.frame_post_draw# You can get the image after this.
// Wait until the frame has finished before getting the texture.awaitRenderingServer.Singleton.ToSignal(RenderingServer.SignalName.FramePostDraw);// You can get the image after this.
Viewport Container
If theSubViewport is a child of aSubViewportContainer, it will become active and display anything it has inside. The layout looks like this:

TheSubViewport will cover the area of its parentSubViewportContainer completelyifStretch is set totrue
in the SubViewportContainer.
Note
The size of theSubViewportContainer cannot be smaller than the size of theSubViewport.
Rendering
Due to the fact that theViewport is an entryway into another rendering surface, it exposes a fewrendering properties that can be different from the project settings. You canchoose to use a different level ofMSAA for each Viewport. The default behavior isDisabled
.
If you know that theViewport is only going to be used for 2D, you canDisable 3D. Godot will thenrestrict how the Viewport is drawn.Disabling 3D is slightly faster and uses less memory compared to enabled 3D. It's a good idea to disable 3D if your viewport doesn't render anything in 3D.
Note
If you need to render 3D shadows in the viewport, make sure to set the viewport'spositional_shadow_atlas_size property to a value higher than0
.Otherwise, shadows won't be rendered. By default, the equivalent project setting is set to4096
on desktop platforms and2048
on mobile platforms.
Godot also provides a way of customizing how everything is drawn insideViewports usingDebug Draw.Debug Draw allows you to specify a mode which determines how the Viewport will display things drawninside it. Debug Draw isDisabled
by default. Some other options areUnshaded
,Overdraw
, andWireframe
. For a full list, refer to theViewport Documentation.
Debug Draw = Disabled (default): The scene is drawn normally.
Debug Draw = Unshaded: Unshaded draws the scene without using lighting information so all the objects appear flatly colored in their albedo color.
Debug Draw = Overdraw: Overdraw draws the meshes semi-transparent with an additive blend so you can see how the meshes overlap.
Debug Draw = Wireframe: Wireframe draws the scene using only the edges of triangles in the meshes.
Note
Debug Draw modes are currentlynot supported when using theCompatibility rendering method. They will appear as regular draw modes.
Render target
When rendering to aSubViewport, whatever is inside will not bevisible in the scene editor. To display the contents, you have to draw the SubViewport'sViewportTexture somewhere.This can be requested via code using (for example):
# This gives us the ViewportTexture.vartex=viewport.get_texture()sprite.texture=tex
// This gives us the ViewportTexture.vartex=viewport.GetTexture();sprite.Texture=tex;
Or it can be assigned in the editor by selecting "New ViewportTexture"

and then selecting theViewport you want to use.

Every frame, theViewport's texture is cleared away with the default clear color (or a transparentcolor ifTransparent BG is set totrue
). This can be changed by settingClear Mode toNever
orNextFrame
.As the name implies, Never means the texture will never be cleared, while next frame willclear the texture on the next frame and then set itself to Never.
By default, re-rendering of theSubViewport happens whenitsViewportTexture has been drawn in a frame. If visible, it will berendered, otherwise, it will not. This behavior can be changed by settingUpdate Mode toNever
,Once
,Always
, orWhenParentVisible
.Never and Always will never or always re-render respectively. Once will re-render the next frame and change to Never afterwards. This can be used to manually update the Viewport.This flexibility allows users to render an image once and then use the texture without incurring the cost of rendering every frame.
Note
Make sure to check the Viewport demos. They are available in theviewport folder of the demos archive, or athttps://github.com/godotengine/godot-demo-projects/tree/master/viewport.