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

Add a nearest-neighbor scaling option to Viewport's Scaling 3D Mode property #4697

Open
Calinou opened this issue Jun 18, 2022 · 3 comments · May be fixed by godotengine/godot#79731
Open

Add a nearest-neighbor scaling option to Viewport's Scaling 3D Mode property #4697

Calinou opened this issue Jun 18, 2022 · 3 comments · May be fixed by godotengine/godot#79731

Comments

@Calinou
Copy link
Member

Calinou commented Jun 18, 2022

Note: This proposal was discussed with reduz a few months ago and is probably fine to implement.

Related to godotengine/godot#45081.

Describe the project you are working on

The Godot editor 🙂

Describe the problem or limitation you are having in your project

Godot 4.0's Vulkan renderer allows for changing the 3D rendering resolution independently of the 2D rendering resolution, without using a separate Viewport for 3D rendering. This makes it easier to set up something like this, and also performs better compared to using two Viewports. However, only bilinear filtering and FSR 1.0 are currently available.

There are a few scenarios where nearest-neighbor filtering is desired:

  • When using a scale factor of 0.25, ~0.3333 or 0.5, nearest-neighbor filtering looks sharper than bilinear filtering while avoiding any artifacts (since it's an integer scaling factor). While FSR also provides sharper results than bilinear filtering, it's much more expensive on the GPU and may be too slow on integrated graphics.
  • Games with a pixel art appearance generally look better when using nearest-neighbor filtering when 3D graphics are rendered at a lower resolution than the viewport.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add a nearest-neighbor scaling option to Viewport's Scaling 3D Mode property.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Changing this sampler to use RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST instead of RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR does the trick in the Vulkan Clustered backend:

https://github.com/godotengine/godot/blob/4366f8bcd455714a5cd29374726d83b674ff0430/servers/rendering/renderer_rd/effects/tone_mapper.cpp#L135

image

However, doing so will break various effects, so we need to use a different sampler only for the one that actually draws the 3D rendering to the viewport.

This sampler should be adjustable via a new enum option in the rendering/scaling_3d/mode project setting and scaling_3d_mode Viewport property. I suggest adding a SCALING_3D_MODE_NEAREST option as the first option of the Viewport::Scaling3DMode enum. In the Project Settings, the option names would look like this:

  • Nearest-Neighbor (Fastest) (new)
  • Bilinear (Fastest)
  • FSR 1.0 (Fast) (should keep using a bilinear sampler internally)

(There is usually no performance difference between nearest-neighbor and bilinear filtering nowadays.)

If this enhancement will not be used often, can it be worked around with a few lines of script?

No, but you can use a second Viewport to display 2D elements at a higher resolution while still using nearest-neighbor filtering. However, by doing so, you lose on some performance compared to using a single Viewport for everything.

Is there a reason why this should be core and not an add-on in the asset library?

This is about improving performance without decreasing quality too much when FSR is too expensive on a given GPU.

@jitspoe
Copy link

jitspoe commented Oct 4, 2024

Oops, looks like this issue already exists and I created a new one, so I closed that other one and I'll just comment here:

In Godot 3, you could set the scale on the viewport to get this effect, but in 4, the scale got moved to the viewport container, which I don't think is easily accessible (if it even exists) in Godot 4.

I'm building a retro FPS, so it would be nice to be able to scale the resolution down with unfiltered pixels to get that chunky retro look. Also, it seems the game runs poorly at 4K resolution, so that's another reason I'd like to scale it down.

@jotson
Copy link

jotson commented Oct 7, 2024

@Calinou I've been watching this issue for a while now and note that the PR's been waiting for review since May. It seems like a review is the only thing holding it up. Is there anything we can do to help get this one over the finish line?

@Calinou
Copy link
Member Author

Calinou commented Oct 11, 2024

@Calinou I've been watching this issue for a while now and note that the PR's been waiting for review since May. It seems like a review is the only thing holding it up. Is there anything we can do to help get this one over the finish line?

The code is complete on my end; it just needs a rendering maintainer to review it. GodotCon is happening this week, so maintainers are busy and can't look at PRs.

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

Successfully merging a pull request may close this issue.

3 participants