Skip to content

Conversation

cdxntchou
Copy link

@cdxntchou cdxntchou commented Sep 27, 2021

Purpose of this PR

*** This backport is paused, waiting on full fix for regression introduced by original PR ***

Fix for https://fogbugz.unity3d.com/f/cases/1352662/

2022.1:

2021.2 backport:

This PR includes both of the 2022.1 PRs.
TODO: include third PR

The issue is that the calculation for screenspace position is calculated from world space position via applying the matrix transforms. However, the calculation is prone to floating point error, that is exacerbated greatly when the camera is far from the origin and the pipeline is not using camera-relative "world" space.

You can see in the examples below that the error can easily grow to be larger than a pixel.

This PR fixes this by changing the calculation in the fragment shader, to be based on the value returned by the VPOS fragment input. This value is not based on the projection matrices, independent of camera position, and much more accurate overall.

Docs ticket: https://jira.unity3d.com/browse/GSG-593

Test example:
Left sphere visualizes frac(screenspace pixel coordinate) using a gradient (red, black, green) where 0.5 is black.
Right sphere shows a screenspace checkerboard alphatest pattern

Before: (at 20000 distance from origin) -- quite a bit of inaccuracy
image

After: (at 20000 distance from origin) -- perfect 0.5 centered pixel coordinates everywhere!
image

Implementation Details:
We introduce two new global values that ShaderGraph can produce, and nodes can request, in addition to ScreenPosition.
The values are defined as:
PixelPosition 2D pixel coordinate of the current fragment or vertex. Pixels are centered at 0.5.
NDCPosition 2D coordinate (0,1) across the viewport; equal to PixelPosition / ScreenResolution.
ScreenPosition (raw) 4D Clip Space homogenous coordinates of the current fragment or vertex.

Both PixelPosition and NDCPosition are calculated from VPOS in the fragment stage, and are calculated from ScreenPosition in other stages.


Testing status

Tested in both HDRP and URP:

  • Tested that Screen Position node and slots work correctly in both fragment and vertex shader.
  • Validated that "Raw" mode works identically to previous, returning clip space ZW.
  • Tested that the other modes return exact values in the fragment shader, based off of the VPOS value.
  • Tested that VFX screen position works.

Added a Yamato test to validate screen position accuracy in fragment shader. Previously you would have a good amount of error in the screen position from the floating point roundoff on the matrix transform calculations. Now it gives exact pixel coordinate values out to at least 3 fractional digits.

Updated reference images. Note that the new accuracy actually changes the test results for the dither node, because the position is slightly different (now more accurate), and the specific test we use is extremely position sensitive.

Master base branch: 34fcac4

Yamato:
ShaderGraph: 🟢
https://yamato.cds.internal.unity3d.com/jobs/902-Graphics/tree/2021.2%252Fsg%252Ffix%252F1352662/.yamato%252Fall-shadergraph.yml%2523Nightly_ShaderGraph_2021.2/9020876/job/pipeline

HDRP: 🟡 -- failures same as master
https://yamato.cds.internal.unity3d.com/jobs/902-Graphics/tree/2021.2%252Fsg%252Ffix%252F1352662/.yamato%252Fall-hdrp.yml%2523PR_HDRP_2021.2/9018618/job/pipeline

master:
https://yamato.cds.internal.unity3d.com/jobs/902-Graphics/tree/2021.2%252Fstaging/.yamato%252Fall-hdrp.yml%2523PR_HDRP_2021.2/8982528/job/pipeline

failures: -- same as master
HDRP on Linux_Vulkan_playmode_mono_Linear on version 2021.2 -- same 2 failures (after rerun) 🟡
HDRP on OSX_Metal_playmode_mono_Linear on version 2021.2 -- same 3 failures 🟡
HDRP on Win_Vulkan_playmode_mono_Linear on version 2021.2 -- same 2 failures 🟡
HDRP on Win_DX12_playmode_mono_Linear on version 2021.2 -- same 2 failures 🟡
HDRP on Win_DX11_playmode_XR_mono_Linear on version 2021.2 -- same 2 failures (after rerun) 🟡
HDRP on Win_DX11_playmode_mono_Linear on version 2021.2 -- same 2 failures 🟡

URP: 🟡 -- failures same as master
https://yamato.cds.internal.unity3d.com/jobs/902-Graphics/tree/2021.2%252Fsg%252Ffix%252F1352662/.yamato%252Fall-urp.yml%2523PR_URP_2021.2/9021101/job/pipeline

master:
https://yamato.cds.internal.unity3d.com/jobs/902-Graphics/tree/2021.2%252Fstaging/.yamato%252Fall-urp.yml%2523PR_URP_2021.2/8982696/job/pipeline

failures: -- same as master
URP_Lighting on Android_OpenGLES3_Standalone_il2cpp_Linear on version 2021.2 -- non-test-related failures on both 🟡
URP_Lighting on Win_Vulkan_Standalone_mono_Linear on version 2021.2 -- same 1 failure 🟡
URP_Terrain on OSX_Metal_playmode_mono_Linear on version 2021.2 -- green on rerun 🟢
URP_Foundation on Android_Vulkan_Standalone_il2cpp_Linear on version 2021.2 -- green on rerun 🟢

Console Tests:

Console Test PR:


Comments to reviewers

Notes for the reviewers you have assigned.

…creenspace calculations (#5428)

* Using SV_Position to calculate screenspace, instead of projection equations.  This might be incorrect though for anyone who wants to read zw...

* Working URP ScreenPositions

* Adding changelog

* Adding "ScreenPosition_Accuracy" to the input nodes tests

* Fixes for HDRP target

* Updating reference images

* Fixing vertex color slot -- was using wrong interface

* Fix for HDRP

* Fix VFX ScreenPos usage

* Convert VFX to use VPOS in fragment shader
# Conflicts:
#	com.unity.shadergraph/CHANGELOG.md
#	com.unity.shadergraph/Editor/Data/Util/ScreenSpaceType.cs
@github-actions
Copy link

Hi! This comment will help you figure out which jobs to run before merging your PR. The suggestions are dynamic based on what files you have changed.
Link to Yamato: https://yamato.cds.internal.unity3d.com/jobs/902-Graphics
Search for your PR branch using the sidebar on the left, then add the following segment(s) to the end of the URL (you may need multiple tabs depending on how many packages you change)

HDRP
/.yamato%252Fall-hdrp.yml%2523PR_HDRP_2021.2

URP
/.yamato%252Fall-urp.yml%2523PR_URP_2021.2

Shader Graph
/.yamato%252Fall-shadergraph.yml%2523PR_ShaderGraph_2021.2
Depending on your PR, you may also want
/.yamato%252Fall-shadergraph_builtin_foundation.yml%2523PR_ShaderGraph_BuiltIn_Foundation_2021.2
/.yamato%252Fall-shadergraph_builtin_lighting.yml%2523PR_ShaderGraph_BuiltIn_Lighting_2021.2

VFX
/.yamato%252Fall-vfx.yml%2523PR_VFX_2021.2

Depending on the scope of your PR, you may need to run more jobs than what has been suggested. Please speak to your lead or a Graphics SDET (#devs-graphics-automation) if you are unsure.

* Fix inconsistent NeedsPositionWorldInterpolator

Use common function to factorize the requirement test from SG
Regression introduced by #5428

* Better fix & Better performance

Isolate screen computation from the world dependancy
See #5784 (comment)
/!\ Remove the VFXTransformPositionWorldToClip evaluated in fragment /!\
GraphicTest are 🟢 locally

* Fix incorrect computation of INSG.ScreenPosition

If we want to be consistent with SG implementation, we have to reproduced this code: https://github.com/Unity-Technologies/Graphics/blob/75f4b421fa774d43000d703f2bbf05d7a1ca6606/com.unity.render-pipelines.universal/Editor/ShaderGraph/Templates/SharedCode.template.hlsl#L56
```
$SurfaceDescriptionInputs.ScreenPosition: output.ScreenPosition = ComputeScreenPos(TransformWorldToHClip(input.positionWS), _ProjectionParams.x);
```
Checked manually the values were consistent with VFX
@cdxntchou cdxntchou marked this pull request as ready for review September 27, 2021 23:16
@cdxntchou cdxntchou requested review from a team as code owners September 27, 2021 23:16
Copy link
Contributor

@jessebarker jessebarker left a comment

Choose a reason for hiding this comment

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

LGTM (matches PR to master)

@cdxntchou cdxntchou requested a review from ellioman September 28, 2021 01:10
@cdxntchou cdxntchou changed the title [ShaderGraph] [bugfix 1352662] [2021.2] Use VPOS for fragment stage screenspace calculations [ShaderGraph] [backport] [2021.2] Use VPOS for fragment stage screenspace calculations Sep 28, 2021
Copy link

@ernestasKupciunas ernestasKupciunas left a comment

Choose a reason for hiding this comment

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

Approving without testing. Looks good! Developer did a great job by manually testing his changes and adding new automated tests.

Copy link
Contributor

@PaulDemeulenaere PaulDemeulenaere left a comment

Choose a reason for hiding this comment

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

I double check the expected changes from 4f9f0c8
Launching full VFX yamato by security but concerned job (VFX_URP) are already 🟢
LGTM! Thanks for the backport.

@sebastienlagarde
Copy link
Contributor

@cdxntchou what is the status of this PR?

@cdxntchou
Copy link
Author

Closing this for now, the number of regressions on the change in trunk is too high

@cdxntchou cdxntchou closed this Dec 9, 2021
PaulDemeulenaere added a commit that referenced this pull request Dec 13, 2021
The refactor from #5817 hasn't been backported
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