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

Implement overscan in the Vulkan renderer to improve screen-space effect stability in motion #3854

Open
Calinou opened this issue Jan 24, 2022 · 2 comments

Comments

@Calinou
Copy link
Member

Calinou commented Jan 24, 2022

Describe the project you are working on

The Godot editor 🙂

Describe the problem or limitation you are having in your project

Screen-space effects like SSAO, SSR, SSIL and glow suffer from artifacts that are mostly noticeable in notion. The camera doesn't "know" what's located outside the view frustum, so it cannot apply screen-space effects based on geometry positioned outside the view frustum (such as a wall or a glowing object). This is an inherent limitation due to the screen-space nature of those shaders.

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

We can sidestep this limitation of screen-space effects by performing overscan on the 3D viewport buffers. This consists in rendering the viewport at a larger resolution, increasing the camera FOV (like you'd do when supporting widescreen in old games) and displaying the middle of the viewport on the screen (letting the viewport's corners go outside the screen).

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

The videos below are recorded from a demo project which I developed. You can read more about oversampling in that repository's README.

Still image comparison1

Still images aren't the best way to show the difference between not using overscan and using overscan, since motion is where the difference is the most obvious.

However, the effect can be demonstrated well in certain situations, such as this one:

SSAO only
Before (0% overscan) After (8% overscan per side)
ssao_only_100 ssao_only_108
SSAO and SSIL
Before (0% overscan) After (8% overscan per side)
ssao_and_ssil_100 ssao_and_ssil_108

Thanks to overscan, the renderer can figure out that the staircase's bottom step is actually a step, rather than a tall wall.

Video comparison

Focus on the staircase's steps and the bottom of the wall on the right.

Without overscan
no-overscan.mp4
With 8% overscan on each side of the viewport
with-1.08-overscan.mp4

Thanks to overscan, screen-space effects become much more stable when the camera moves or rotates.

Higher overscan percentages are more expensive on the GPU. Values between 5% and 8% are usually the sweet spot, bringing noticeable improvements to screen-space effect stability with a moderate performance impact.

With variable rate shading (VRS), we can optimize overscan by rendering areas outside the viewport at a lower shading resolution (2×2 or even 4×4 on hardware supporting it). This will make overscan faster to render while looking nearly as good, since you won't actually see those pixels with a lower shading rate on your screen. Those pixels will still influence screen-space effects you can see on your screen, though.

From an implementation side:

  • The overscan range should be adjustable between 0% and 15% per side. There are diminishing returns to using larger values than 15% per side, and screen-space effects will actually tend to look worse at high overscan values.
  • Overscan should be disabled by default, as it has a non-negligible cost and no benefit if no screen-space shaders are used.
  • If overscan is enabled but no screen-space effects are enabled in the Environment resource, a warning should be printed on startup (or emitted as a node configuration warning).
  • It should be investigated whether exposing overscan in a number of pixels per side (rather than a percentage of the viewport width/height) is a better idea. In this case, the range should probably be between 0 and 250 pixels per side.

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

This enhancement is likely to be used often in high-end 3D games, at least as an option for people with GPU power to spare. Overscan can also be useful for offline rendering, especially when coupled with supersampling to further improve image stability in motion.

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

This feature can be implemented as an add-on, as demonstrated by godot-overscan-demo. However, an optimal implementation will require integration into core, specifically to automatically make use of VRS as mentioned above.

Footnotes

  1. Overscanned images currently appear less sharp. This is likely an issue with my implementation which could be fixed.

@ArseniyMirniy
Copy link

May I ask if SSAO needed, when SSIL is in use? The SSIL alone creates noticeable shading around objects and SSAO makes the scene less realistic in many cases I've tried.

@Calinou
Copy link
Member Author

Calinou commented Feb 10, 2022

May I ask if SSAO needed, when SSIL is in use? The SSIL alone creates noticeable shading around objects and SSAO makes the scene less realistic in many cases I've tried.

You can use both SSAO and SSIL at the same time for maximum quality, but you don't have to. SSIL alone will naturally bring some kind of SSAO effect along with it, although it doesn't look the same. SSIL's ambient occlusion effect generally looks a bit better for larger details, and a bit worse for smaller details.

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

No branches or pull requests

3 participants