-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SubViewportContainer does not scale Viewport properly with CanvasItems project scale mode. #77149
Comments
Upon some investigation it appears that scaling that it can handle one axis of scaling but not both. Either vertical or horizonal scaling works properly but not combined. |
This doesn't happen automatically by design, as changing viewport size behind the user's back may break expectations (especially when using viewport for off-screen rendering, such as procedural textures). You need to resize the SubViewports by listening to the |
That commit removes any reference to SubViewportContainer from the example. Is this not the point of SubViewportContainer's stretch option? To keep the viewport at a 1:1 pixel ratio on screen. I think one of us is missing something here. If you look at the way the size of the container actually changes in the example, it isnt as simple as just multiplying it by the scaling factor. The containers laying it out etc for splitscreen actually keep one of the dimensions in a weird way. |
The Stretch option makes the SubViewportContainer stretch to cover the container's size. It does not resize the underlying Viewport. |
https://github.com/godotengine/godot/assets/20043270/048f0e2e-7152-4ca7-8671-78fe5913836f |
It does what it says on the tin to be fair, the problem is that when I think Perhaps the scaling mode should be set per-viewport instead of per-project? |
There was some talk about moving the content scale options from Window to Viewport, but this likely breaks compatibility. |
I saw that demo as answering the common question "How do I scale the 3D resolution for performance", which no longer requires a SubViewport in the forward renderer, as you can set the 3D scaling directly on the main viewport. I split out a separate compatibility demo to show the "legacy" way of scaling with a SubViewport (which should also apply to e.g. multiple SubViewports for split-screen), where I think I hit this issue: godotengine/godot-demo-projects#891 (comment) |
Just ran into this while trying to add 3D collectible counter icons to a UI. I use a base resolution of 1024x768. When I maximize the window on my 2560x1440 monitor, the icons look extra blocky, with 2-pixel slope steps. Ideally, the |
For anyone seeking a solution, my current workaround is to replace the SetupFor Also, I set the Scriptclass_name ViewportSizer
extends Node
@export var target_viewport: SubViewport
var _base_render_size: Vector2 = Vector2()
var _window: Window
func _ready():
_window = get_tree().root as Window
_window.size_changed.connect(update_size)
_base_render_size = target_viewport.size
## Calculates a scale for width and height, and applies the lower of the two.
##
## This assumes the following display settings:
## - display/window/stretch/mode: canvas_items
## - display/window/stretch/aspect: expand
func update_size():
# Cast from Vector2i (integer) to Vector2 (float) for smooth results
var current_viewport_size: Vector2 = _window.size
var reference_viewport_size: Vector2 = _window.content_scale_size
var viewport_scale: Vector2 = current_viewport_size / reference_viewport_size
var size_scale: float = minf(viewport_scale.x, viewport_scale.y)
# Round back to integer size to prevent truncation
var scaled_size: Vector2i = (_base_render_size * size_scale).round()
target_viewport.size = scaled_size |
@OhiraKyou this solution does not work for me. any steps you may have forgot to detail? also, does this solution break object picking for yo? |
Assuming you're referring to selecting objects by clicking on them from the viewport, I can still click on the |
Here's my version of @OhiraKyou's script, this time as a replacement subclass for SubViewportContainer # https://github.com/godotengine/godot/issues/77149
class_name SubViewportContainerBug77149
extends SubViewportContainer
@export var stretch_without_bug_77149 : bool
func _ready() -> void:
resized.connect(_on_resized)
_on_resized()
var _dont_recurse : bool
func _on_resized() -> void:
assert(not stretch)
if not stretch_without_bug_77149 or _dont_recurse:
return
var window := get_window()
var viewport_size := Vector2(window.size)
var reference_size := Vector2(window.content_scale_size)
var viewport_scale := viewport_size / reference_size
var size_scale := minf(viewport_scale.x, viewport_scale.y)
var scaled_size := Vector2i((size * scale * size_scale).round()) / stretch_shrink
if Vector2i(size.round()) == scaled_size:
return
_dont_recurse = true
# we need to set the container's size first or it'll get resized by the viewport resize (ugh)
scale = Vector2(1.0 / size_scale, 1.0 / size_scale)
size = scaled_size
for subviewport : SubViewport in find_children("*", "SubViewport", false, false):
# avoid reallocating textures we don't need to reallocate
if subviewport.size != scaled_size:
subviewport.size = scaled_size
_dont_recurse = false |
Godot version
4.0.2.stable
System information
Windows 11, Vulkan, RTX2070 Super
Issue description
SubViewportContainer does not scale the underlying viewport appropriately to maintain quality in this mode.
Potentially related to #70791 and #76450.
Steps to reproduce
See reproduction project.
Minimal reproduction project
ViewportScalingRepro.zip
The text was updated successfully, but these errors were encountered: