### Describe the project you are working on
A low-res 2D platformer with a hi…gh-res UI, smooth camera movement, and zoom.
### Describe the problem or limitation you are having in your project
In 3.0x+, the [common method](https://www.youtube.com/watch?v=zxVQsi9wnw8&t=338s) for making pixel perfect games with a high resolution UI was fairly straightforward. You would toggle the 2D stretch mode, set your project resolution to something like 1920 x 1080, and throw your game inside a viewport node at a desired base resolution (such as 640 x 360). If you wanted take it a step further and implement a smooth camera, a common solution was to use a [framebuffer shader with custom camera logic](https://code-disaster.com/2016/02/subpixel-perfect-smooth-scrolling.html). Although a bit cumbersome, it did the trick well enough.
In 4.0, it's no longer this simple. Implementing a high-res UI with a low-res game is doable, but every known method for smooth camera movement I could find no longer works as effectively in 4.0. Additionally, 4.0 introduces even more factors that impact how pixels are displayed in 4.0, each creating dozens of different combinations that produce vastly different, loosely documented, and often undesirable effects. While not all specific to 4.0, here are some factors I can think of:
- Viewport stretch settings in project settings, also may cause sprites to render incorrectly when combined with subviewports as seen with [#61301](https://github.com/godotengine/godot/issues/61301)
- Viewport and window override resolution in project settings
- "Resize" toggle in project settings (may contribute to pixel distortion as per [#62869](https://github.com/godotengine/godot/issues/62869))
- Size and Size 2D override in SubViewport inspector
- "Snap 2D Transforms to Pixel" and "Snap 2D Vertices to Pixel" in project settings, which introduces jitter as per [#71074](https://github.com/godotengine/godot/issues/71074) as well as [#63185](https://github.com/godotengine/godot/issues/63185), blur as shown in [#66527](https://github.com/godotengine/godot/issues/66527), as well as undesirable scaling and rotation behavior as seen with [#60443](https://github.com/godotengine/godot/issues/60443)
- "Snap 2D Transforms to Pixel" and "Snap 2D Vertices to Pixel" in the SubViewport node inspector, which may induce blurring with movement [#66527](https://github.com/godotengine/godot/issues/66527) and rotation [#57221](https://github.com/godotengine/godot/issues/57221)
- Texture filtering options for sprites as well as subviewports
- The “centered” toggle for objects, especially sprites with odd dimensions
- Editor grid pixel snap (which still occasionally places objects at non-integer positions)
- Camera node smoothing options (seems to always introduce jitter to some degree)
- Camera and player movement (ensuring that position is rounded to an integer, or vice versa)
- Calculating camera or player movement in _physics_process vs _process, see [#71226](https://github.com/godotengine/godot/issues/71226)
- Collision shapes being offset at subpixel values at runtime
- [Physics interpolation](https://github.com/lawnjelly/smoothing-addon) (not implemented in 4.0)
- The position of the game window (causes unpredictable sprite bleed as shown in [#67164](https://github.com/godotengine/godot/issues/67164)?)
- Usage of integer scaling (not a feature in the engine, [here's a community made option.](https://github.com/ShatReal/integer-scaling))
To me, this is a painful amount of variables to deal with for such a common use case. I have tried every combination of these options alongside upscaling shaders, pixel buffers, custom camera smoothing, viewport textures, and more. The resulting process is a maddening game of cat-and-mouse in which you're constantly balancing jitter, blur, and sprite distortion while never quite eliminating one or the other.
This is the closest I was able to get before throwing in the towel. I achieved smooth camera movement on the sides of the screen, but it introduces pixel distortion. Enabling pixel/vertices snap gets rid of the pixel distortion, but introduces blur on everything. I'm not sure which is worse, so I just avoided using it.
https://user-images.githubusercontent.com/121070110/222317317-b9291247-93ce-490e-9b0f-3cfdf3f63916.mp4
### Describe the feature / enhancement and how it helps to overcome the problem or limitation
The exact solution to this problem is complicated, as it is most likely a complex combination of intentional engine design, user error, and lack of documentation. However, I think a few things would help in this regard.
Before mentioning any in-engine solutions, it's worth mentioning that a detailed and precise collection in the docs outlining the best practices for pixel perfect games, especially in regards to smooth camera movement or zoom, would help a great deal without needing to touch the engine itself. It wouldn't fix the inherent issue of complexity here, but combined with some sort of "hybrid pixel perfect" starting template, it would be a decent remedy.
In terms of in-engine solutions, a few preexisting proposals such as [integrated integer scaling](https://github.com/godotengine/godot-proposals/issues/1666) would help alleviate this problem to some degree. However, I think a "PixelCamera2D" node or something similar designed specifically for this common use case would be wildly beneficial.
### Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
An example would be a camera node called "PixelCamera2D" that would allow functionality for sub-pixel perfect smooth scrolling in 2D games. This concept isn't new or particularly complicated, [and this write up by Daniel Ludwig](https://code-disaster.com/2016/02/subpixel-perfect-smooth-scrolling.html) is a perfect starting point for how it could be implemented. In essence, it would just be a standard camera with extended framebuffer capabilities that would be used for low-res subviewports. The issue with this approach is that it isn't perfect (especially with parallax) and doesn't sufficiently mitigate jitter or distortion in 4.0+ for some reason.
An alternate approach may be necessary that avoids using a pixel buffer entirely that utilizes the core engine to achieve smooth camera movement in some other way. This goes well beyond my scope, but definitely worth looking into.
### If this enhancement will not be used often, can it be worked around with a few lines of script?
I imagine it would be used very frequently, at least by indie developers who work with pixel art a lot. It could very easily optionally just not be used.
### Is there a reason why this should be core and not an add-on in the asset library?
Normally just implementing that method on a per-project basis or as an addon would be more than sufficient, but as previously mentioned, things have changed quite a bit. Here's a few reasons why I believe this should be a core feature:
- Pixel perfect games (and ones with smooth camera movement by extension) are an absurdly common use case and having that functionality available out of the box would be a game changer for quality of life
- Godot 4.0 introduces a plethora of new changes and modifications to the render server that makes dealing with this issue unreasonably cumbersome as a user, let alone anybody working with the core engine.
- This is a frustrating issue that I imagine many users will have to deal with, and I'm not sure it will ever be completely addressed through an addon any time soon (especially if it needs to be addressed through additions to the core engine)