Skip to content
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

Allow viewport stretch without shrink #76304

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bonjorno7
Copy link
Contributor

@bonjorno7 bonjorno7 commented Apr 20, 2023

For my project I have a low base resolution, and use scaling mode canvas_items.
This lets me have pixel art UI over high res 3D. I set the viewport's resolution via script.

The issue is that when the SubViewportContainer gets scaled up by canvas_items, it becomes much too large.
One solution is to use Stretch, so that the viewport is displayed at the size of its container.
But my problem there is, I don't want to use Stretch Shrink, because it limits the viewport size to the base resolution of the project, meaning it becomes pixelated when increasing the window size.
My solution is to allow shrink to go to 0, where it doesn't force viewport resolution, but still stretches/shrinks the texture to fit the container.
I've also adjusted the relevant input methods and tested all my changes to make sure it works as expected, and updated relevant tooltips.
It seems to work correctly with Size 2D Override and Size 2D Override Stretch too.

Before I made changes to the engine, I worked around this using scripts and a TextureRect, and required math to get mouse position correctly.
SubViewportContainer does have scale, but it gave me issues with floating point imprecision, and was just a hassle.
I think this will be of use to other people too, as it makes SubViewportContainer more versatile.

Here's a test project so you can see it in action: Stretch Shrink Test.zip
I'd love to hear your feedback!

@bonjorno7 bonjorno7 requested review from a team as code owners April 20, 2023 22:43
@bonjorno7 bonjorno7 force-pushed the subviewportcontainer-stretch-without-shrink branch 2 times, most recently from 4e025ca to 8dfc1ce Compare April 20, 2023 23:04
@clayjohn clayjohn added this to the 4.x milestone Apr 20, 2023
@bonjorno7 bonjorno7 requested a review from a team as a code owner April 21, 2023 23:21
Shrink can now go down to zero, and gets special treatment.
Code that forces the viewport resolution checks that shrink is greater than zero.
Transforms are done by dividing the sizes of the viewport and the container (not necessarily in that order), instead of using the shrink value directly.
To accomplish this, _send_event_to_viewports does the scaling now, instead of _gui_input.
I always cast viewport size to floats, because otherwise it casts it implicitly, but only when it's on the right of the operator, and I don't like playing dice.
@bonjorno7 bonjorno7 force-pushed the subviewportcontainer-stretch-without-shrink branch from d1a80f6 to 2dd2e7f Compare May 14, 2023 01:04
@Calinou
Copy link
Member

Calinou commented May 14, 2023

This lets me have pixel art UI over high res 3D. I set the viewport's resolution via script

Note that on the root Viewport (which is a Window), you can set Content Scale Factor (or the equivalent project setting) to achieve this with any stretch mode. This PR makes it possible to achieve the same on SubViewports which may sometimes be useful, but the main use case is really for the root Viewport. (If you split 2D and 3D rendering in separate viewports, you generally keep 2D rendering in the root Viewport, which allows you to use Content ScaleFactor.)

@bonjorno7
Copy link
Contributor Author

High res is one of the options for 3D, but I also allow the user to set a lower target resolution.
It chooses the nearest fraction of the window size.
This is why I use a sub viewport; that and to apply a dithering filter.

@Calinou
Copy link
Member

Calinou commented May 14, 2023

There was some talk about moving Window's stretch modes to Viewport, but I presume doing so will break compatibility.

but I also allow the user to set a lower target resolution.

Note that we have Scaling 3D project settings and Viewport properties since 4.0, although it currently lacks a nearest-neighbor filtering mode and doesn't work with the Compatibility rendering method yet.

@bonjorno7
Copy link
Contributor Author

bonjorno7 commented May 14, 2023

Using 3D scaling either in project settings or a sub viewport spams my errors (All textures in a framebuffer should be the same size.) for me so I haven't messed with it.
And the lack of nearest neighbor is a deal breaker for me.
Either way it feels like a workaround for what I actually want, which is to stretch the viewport texture across the container the way it would with a texture rect.
I could live with a proper workaround but I like my PR more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants