[URP] FSR Upscaling Filter by gmitrano-unity · Pull Request #6262 · Unity-Technologies/Graphics · GitHub
Skip to content

[URP] FSR Upscaling Filter#6262

Merged
phi-lira merged 47 commits into
masterfrom
urp/fsr-merged
Jan 28, 2022
Merged

[URP] FSR Upscaling Filter#6262
phi-lira merged 47 commits into
masterfrom
urp/fsr-merged

Conversation

@gmitrano-unity

@gmitrano-unity gmitrano-unity commented Nov 9, 2021

Copy link
Copy Markdown
Contributor

Purpose of this PR

Add FSR Upscaling Filter to URP

This change adds a new upscaling filter to URP that uses FidelityFX
Super Resolution. It is only available on platforms that support
shader target 4.5 or above. On unsupported platforms, it will behave
as if the user selected the "Auto" filter in the pipeline asset.

Unlike other filters, this filter will execute even when the renderer
is not configured to scale. HDRP has the same behavior. This allows the
FSR shaders to improve visual quality even when scaling is not active.

77% Scaling with Bilinear Filter:
image

77% Scaling with FSR Filter:
image

100% Scaling (Native):
image

All images were rendered with 1080p as their final resolution and include the mip bias changes currently out for review in a different PR.


Testing status

Tested on Windows with Vulkan, Android with Vulkan. Still needs XR testing and more comprehensive testing in general.


Comments to reviewers

This PR currently contains commits from two other outstanding PRs. This PR should not be merged until those commits are merged into master.


Notes for QA

Please test each filter type at 0.5 resolution scale, and 0.77 resolution scale with FXAA on and off (AA should either be FXAA or MSAA). A fixed viewport size should be used for this (such as 1920x1080) to make sure the integer scaling path is triggered during Auto.


TODO

  • Changelog updates
  • Documentation updates
  • Automated graphics tests
  • Re-enable 16-bit mode before merging (Fix black-screen issue in RCAS)

@github-actions

github-actions Bot commented Nov 9, 2021

Copy link
Copy Markdown

@LaserYGD

Copy link
Copy Markdown

Will there be a sharpening value parameter exposed to users?

@m0nsky

m0nsky commented Nov 15, 2021

Copy link
Copy Markdown

Hi @gmitrano-unity, great work, I hope it's alright to leave some feedback. I've had good results trying this branch on desktop. I've also tried this branch in XR since you mentioned it needs further testing, and I am mainly interested in using this tech in XR.

Currently it seems to result in a black screen in XR (using both mock hmd and on the actual device itself)

Example:

urp fsr xr

I've also set up a plug & play repository with everything pre-configured to hopefully make things easier. Keep in mind I have done two slight namespace changes to the URP package for 2021.2 compatibility, but these are unrelated to FSR.

Repository:

https://github.com/m0nsky/urp_fsr_xr

  1. Open Scenes/SampleScene
  2. Hit play
  3. Open Settings/UniversalRP-LowQuality and set the Upscaling Filter to FidelityFX Super Resolution 1.0

@gmitrano-unity

Copy link
Copy Markdown
Contributor Author

Will there be a sharpening value parameter exposed to users?

That's a good question, I'll ask some folks internally and see what the plan is.

@gmitrano-unity

Copy link
Copy Markdown
Contributor Author

@m0nsky Feedback is much appreciated! :)

I just pushed a new commit that disables the 16-bit FSR implementation since I've seen it cause similar black-screen results on some hardware/software configs. Could you please let me know which GPU hardware and graphics API you were using when you saw the black screen and if the most recent commit fixes your issue? I've seen the issue on Nvidia + DX11, but only when the project target is Android.

@gmitrano-unity

Copy link
Copy Markdown
Contributor Author

@m0nsky Nevermind, I just tried it out in the Mock HMD locally and the 16-bit change doesn't fix the issue. I'll investigate this. Thanks!

@gmitrano-unity

Copy link
Copy Markdown
Contributor Author

@m0nsky I just tested my latest commit in your example xr project and it seems to fix the black screen issue for me. I also tried in Viking Village with the XR mock HMD enabled and that now works as well.

@m0nsky

m0nsky commented Nov 15, 2021

Copy link
Copy Markdown

@gmitrano-unity the black screen fix (latest) worked for Mock HMD in the editor initially. I tried building for Oculus Quest and got some errors regarding FXAA (probably related to your other PR #6178).

fxaa err

I temporarily worked around this by commenting out the ApplyFXAA calls. After doing this, the build completed successfully and it seems like FSR is running native on the Oculus Quest. (screenshots taken on device)

fsr on quest

I haven't had any more issues with both commits merged locally, would love to see 16-bit + FXAA working.

Edit
Fixed it locally by converting ApplyFXAA, FXAALoad & FXAAFetch to accept TEXTURE2D_X as inputs, will see what you come up with for an official fix, I could probably learn something here.

@gmitrano-unity

Copy link
Copy Markdown
Contributor Author

Edit Fixed it locally by converting ApplyFXAA, FXAALoad & FXAAFetch to accept TEXTURE2D_X as inputs, will see what you come up with for an official fix, I could probably learn something here.

I think that's the correct fix actually. :)
Once I turned on FXAA locally, the issue reproduced once the mock HMD was set to use single pass instancing mode.
Adding the "_X" suffixes fixes the issue by adding handling for the 2d array case which is exclusive to single pass instance mode (afaik). I've added that change to this PR and the other FXAA PR.

I haven't had any more issues with both commits merged locally, would love to see 16-bit + FXAA working.

Great! Thanks for all the help with testing!

You can try out the 16-bit FSR implementation if you'd like by removing the comment sections I added in this commit: 2ced160
I just disabled it for now to avoid causing further confusion relating to compatibility since there are some known issues. I'm hoping to have those resolved before this PR gets merged though.

@LaserYGD

Copy link
Copy Markdown

Thank you for exposing sharpness value
I've been asking the same for HDRP for sometime but no luck, it would be great if HDRP would follow URP with that bit.

Thanks again 😄

This change moves the FXAA HLSL implementation into the common post
processing shader file. This will make it easier to execute the FXAA
shader logic outside of the FinalPost pass which is a prerequisite for
FSR.

This change also modifies the FXAA Load helper function to make it use
point sampling instead of linear sampling on GLES. This should yield
more consistent behavior between GLES and non-GLES environments.
This change adds a new property to the pipeline asset that allows users
to control which filter is used when upscaling is performed. The current
implementation supports selecting either bilinear or nearest-neighbor.
Additional methods of filtering will be added in future changes.
This change adds a new enum called ImageScaling which enumerates all
possible image scaling scenarios. This helps make the scaling related
conditional logic easier to read.
This change splits the upscaling filter selected by the user from the
one used within URP's implementation to allow for a "meta filter"
called Auto. This new filter automatically switches between bilinear
and nearest-neighbor filtering based on the current rendering
environment's ability to perform integer scaling.
This change renames the _FILTER_POINT macro to _POINT_SAMPLING to
improve consistency with future FSR changes.
This change updates the FXAA common shader functions to support 2d array
input textures which are used in XR's single pass instanced mode.
This commit adds new test cases for the upscaling filters that were
added in a previous change.
@gmitrano-unity gmitrano-unity force-pushed the urp/fsr-merged branch 2 times, most recently from 45c919b to bb3c681 Compare November 23, 2021 20:42
This change updates the upscaling setup logic to use an RTHandle instead
of a temporary render target.
Updated the URP changelog to reflect the upscaling filter changes and
the FXAA scaling fix.
This change integrates the mip bias logic from HDRP into URP. This logic
ensures that shaders select their mips based on the final screen
resolution rather than the current render resolution. In cases where
aggressive upscaling is taking place, this can significantly improve
texture detail in the final image.
This change resolves a black screen issue on XR platforms
(tested in the mock HMD) which was caused by missing support for
draw procedural in the upscaling setup shader.
@manuele-bonanno manuele-bonanno self-requested a review December 1, 2021 09:15
upscaleRtDesc.height = cameraData.pixelHeight;

// EASU
RenderingUtils.ReAllocateIfNeeded(ref m_UpscaledTarget, upscaleRtDesc, FilterMode.Point, TextureWrapMode.Clamp, name: "_UpscaledTexture");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we expecting the desc to change during runtime?
If not, you can just Allocate once and not check every frame.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a place in the ScriptableRenderPass that only gets called when the backbuffer resizes? This particular render target is always the same size as the backbuffer. The other render target used above this one will change size whenever render scale changes so I'm not sure if it's possible to optimize that one.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no place that I am aware of

Comment thread com.unity.render-pipelines.universal/Runtime/UniversalRenderPipeline.cs Outdated
This change removes the 16-bit option in the FSRCommon.hlsl in favor of
an automatic solution based on REAL_IS_HALF. Users of the FSR code no
longer need to explicitly opt-in to the 16-bit implementation. It will
now be enabled automatically whenever the target platform has support.

There are currently two exceptions for the logic that automatically
enables the 16-bit FSR implementation:

1. Some vendors have issues with 16-bit floating point casts to uint16
   which are required for FSR's math approximations. This issue only
   occurs on DX11 drivers, so the 16-bit implementation is currently
   disabled whenever DX11 is in use until this is fixed.
2. There's currently a known shader compiler issue that affects
   platforms running Metal with FP16 support. (Case 1387697) Due to
   this issue, the 16-bit implementation is also disabled for Metal.

This change also contains a small modification for the uint to float
conversion logic used inside FSRUtils.cs:SetRcasConstants. The updated
logic avoids an unnecessary memory allocation which was causing
failures in URP's graphics tests.
This change adds a new test scene for the URP post processing graphics
tests which verifies the functionality of the FSR upscaling filter.
This commit actually pulls the correct changes for the memory allocation
failure in the SetRcasConstants function.

@ernestasKupciunas ernestasKupciunas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.
Found 1 issue regards the M1 Pro Max chip - Balck screen in the Game view @gmitrano-unity is aware of this already.

Full testing doc: https://docs.google.com/document/d/1l536oqerdT1M-OJcy-ynjDCpf0IMPLGtdO0LZHnYdRI/edit#
Also, 1 issue not related to this PR: Depth of field effect gives screen distortions on Adreno 620GPU

Testing devices:
MacBook Pro (16-inch, 2021), CPU: Apple M1 Max, Memory: 64 GB, macOS: Monterey 12.0
Samsung Galaxy S10+, 10.0.0, Exynos 9 9820, Mali-G76
OnePlus Nord, 10, Snapdragon 765G SM7250-AB, Adreno 620
iPad Air4, SoC: A14, iOS: 14.0
iPhone 13Pro Max, SoC: A15, iOS: 15.0.1

@gmitrano-unity

Copy link
Copy Markdown
Contributor Author

@ernestasKupciunas I pushed a few commits to this PR later last week that should address the black screen issue. Could you please verify that the most recent version of this PR no longer reproduces the problem? (4efaf1e)

This change updates the integer scaling logic to prefer the use of the
built-in approximation function over direct float comparisons.
@gmitrano-unity gmitrano-unity marked this pull request as ready for review December 13, 2021 20:20
@gmitrano-unity gmitrano-unity requested review from a team as code owners December 13, 2021 20:20
@gmitrano-unity gmitrano-unity requested a review from a team December 13, 2021 20:20

@ernestasKupciunas ernestasKupciunas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gmitrano-unity checked both, iOS and Android. Works fine and renders the Scene and Game views as expected. Good job!

Comment on lines +694 to +706
public UpscalingFilterSelection upscalingFilter
{
get { return m_UpscalingFilter; }
set { m_UpscalingFilter = value; }
}

public bool fsrOverrideSharpness
{
get { return m_FsrOverrideSharpness; }
set { m_FsrOverrideSharpness = value; }
}

public float fsrSharpness

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still missing API docs or did I miss something?

{
HLSLINCLUDE
#pragma exclude_renderers gles
#pragma multi_compile_local_fragment _ _GAMMA_20

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_GAMMA_20 and _LINEAR_TO_SRGB_CONVERSION are mutually exclusive right? If so, I guess we can make
multi_compile_local_fragment _ GAMMA_20 _LINEAR_TO_SRGB_CONVERSION and save some variants.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dug into this a bit and realized that FSR didn't play well with the gamma color encoding project setting so I fixed that in a new commit and addressed the unnecessary shader variants as well.

gmitrano-unity and others added 2 commits January 12, 2022 17:19
This change resolves some color issues that occur when the project color
encoding is set to Gamma instead of Linear. When running with gamma
encoding, we now just use sRGB encoded color data instead of gamma 2.0
for EASU since it's already encoded that way. Visual quality should be
similar since EASU's requirement is for perceptual encoded color data,
not specifically gamma 2.0 encoded color data.

This change also moves the _GAMMA_20 shader keyword for UberPost into
the same group as _LINEAR_TO_SRGB_CONVERSION since they're mutually
exclusive.
@phi-lira

Copy link
Copy Markdown
Contributor

URPUpdate on Win_DX11_playmode_mono_Linear on version trunk - failing on master, we are investigating.
ShaderGraph on OSX_OpenGLCore_editmode_mono_Linear on version trunk - failing on master as well.

@phi-lira

Copy link
Copy Markdown
Contributor

@phi-lira phi-lira merged commit bdddfec into master Jan 28, 2022
@phi-lira phi-lira deleted the urp/fsr-merged branch January 28, 2022 14:01
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.

7 participants