Setting SubViewport size to always match root Viewport size

Godot Version

4.2.2 Windows 11

Question

Hi, I’m working on a Project where the 3D World is in a seperate Viewport Container.
My goal is for the 3D Render resolution to match the window size when playing in windowed mode. To this end I set the project stretch mode to canvas_items and the aspect to expand.

My problem is that when changing the window size, the root viewport’s resolution gets updated, but the subviewport keeps its approximate size, even though the SubViewportContainer is set to stretch=true.


This is my general setup. You can see that the SubViewport and the RootControl node’s sizes don’t match the root viewport.

How could I achieve my goal? I tried setting the size explicitly:
$SubViewportContainer/SubViewport.size = get_tree().root.size
This requires the container to be stretch=false and leads to the Viewport not taking up the whole window:


Now, the root viewport matches the 3D subviewport, which is great!
Though in this case the RootControl node’s size stays fixed to the initial viewport size. This confuses me as well; as it’s anchors are set to 1, I would expect it to grow with the window.

Here’s my code:

func _process(_delta: float) -> void:
	$Label.text = "Root Viewport Size: " + str(get_tree().root.size) +\
	 "\n3D Viewport Size: " + str($SubViewportContainer/SubViewport.size) +\
	"\nRoot Control Size: " + str(size)
	# setting the size only works when stretch = false,
    # in which case the viewport doesn't fill up the screen anymore
	#$SubViewportContainer/SubViewport.size = get_tree().root.size
	#self.size = get_tree().root.size

Here’s a link to my test project. Thank you for any pointers :slight_smile:

I found a workaround. By setting the main Window’s content_scale_size to 0, 0 the node sizes always match the window size.

I added this to _ready():

if get_window().mode == Window.MODE_WINDOWED:
    get_window().content_scale_size = Vector2(0, 0)

Though take note that this messes up the scaling of CanvasItems outside the 3D Viewport, so this solution was not suitable for me.

What I ended up doing was ditching the whole SubViewportContainer and working with a TextureRect and a ViewportTexture instead. This is a little more work but allows for more control over the Subviewport.

Hope this helps someone else! :slight_smile:

1 Like

I still haven’t completely solved my problem, but just want to add this relevant Github discussion for anyone stumbling upon this thread:
https://github.com/godotengine/godot/issues/77149