Skip to content

Commit

Permalink
v4.0.2:
Browse files Browse the repository at this point in the history
HIGHLIGHTS:
- NRD: improved curvature estimation
- NRD: fixed some bugs
- REBLUR: improved specular tracking
- REBLUR: fixed some bugs
- RELAX: implicit curvature-related improvements

DETAILS:
- NRD: improved curvature estimation
- NRD: fixed wrong width of input resources in clear calls
- NRD: fixed thin lens equation in case of concave curvature
- NRD: simplified "ComputeParallax" to "ComputeParallaxInPixels" and adjusted related calculations
- NRD / REBLUR: tweaked ULP thresholds
- REBLUR: fixed potential race conditions while accessing "hitDistForTracking" (affected specular tracking)
- REBLUR: fixed optional MV modification
- REBLUR: fixed 1-frame delay in reaction to "max number of accumulated frames"
- REBLUR: improved precision of curvature packing used in TS pass
- REBLUR: improved precision of curvature calculations in case of high parallax
- REBLUR: tuned curvature adjustment hack
- REBLUR: slightly reduced memory usage of diffuse denoisers
- REBLUR / SPECULAR_REFLECTION_MV: fixed wrong usage of "rect offset" in curvature calculations
- SPECULAR_REFLECTION_MV: improved curvature calculations in case of high parallax
  • Loading branch information
dzhdanNV committed Jan 16, 2023
1 parent efb227a commit a28ad93
Show file tree
Hide file tree
Showing 24 changed files with 210 additions and 213 deletions.
4 changes: 2 additions & 2 deletions Include/NRD.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.

#define NRD_VERSION_MAJOR 4
#define NRD_VERSION_MINOR 0
#define NRD_VERSION_BUILD 1
#define NRD_VERSION_DATE "21 December 2022"
#define NRD_VERSION_BUILD 2
#define NRD_VERSION_DATE "23 January 2023"

#if defined(_MSC_VER)
#define NRD_CALL __fastcall
Expand Down
44 changes: 22 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# NVIDIA Real-time Denoisers v4.0.1 (NRD)
# NVIDIA Real-time Denoisers v4.0.2 (NRD)

[![Build NRD SDK](https://github.com/NVIDIAGameWorks/RayTracingDenoiser/actions/workflows/build.yml/badge.svg)](https://github.com/NVIDIAGameWorks/RayTracingDenoiser/actions/workflows/build.yml)

Expand Down Expand Up @@ -226,50 +226,50 @@ The *Persistent* column (matches *NRD Permanent pool*) indicates how much of the

| Resolution | Denoiser | Working set (Mb) | Persistent (Mb) | Aliasable (Mb) |
|------------|--------------------------------------|------------------|------------------|------------------|
| 1080p | REBLUR_DIFFUSE | 88.75 | 46.50 | 42.25 |
| 1080p | REBLUR_DIFFUSE | 86.62 | 46.50 | 40.12 |
| | REBLUR_DIFFUSE_OCCLUSION | 42.38 | 29.62 | 12.75 |
| | REBLUR_DIFFUSE_SH | 139.38 | 63.38 | 76.00 |
| | REBLUR_SPECULAR | 101.31 | 54.88 | 46.44 |
| | REBLUR_DIFFUSE_SH | 137.25 | 63.38 | 73.88 |
| | REBLUR_SPECULAR | 105.56 | 54.88 | 50.69 |
| | REBLUR_SPECULAR_OCCLUSION | 50.75 | 38.00 | 12.75 |
| | REBLUR_SPECULAR_SH | 151.94 | 71.75 | 80.19 |
| | REBLUR_DIFFUSE_SPECULAR | 164.62 | 80.25 | 84.38 |
| | REBLUR_SPECULAR_SH | 156.19 | 71.75 | 84.44 |
| | REBLUR_DIFFUSE_SPECULAR | 168.88 | 80.25 | 88.62 |
| | REBLUR_DIFFUSE_SPECULAR_OCCLUSION | 71.94 | 46.50 | 25.44 |
| | REBLUR_DIFFUSE_SPECULAR_SH | 265.88 | 114.00 | 151.88 |
| | REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION | 88.75 | 46.50 | 42.25 |
| | REBLUR_DIFFUSE_SPECULAR_SH | 270.12 | 114.00 | 156.12 |
| | REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION | 86.62 | 46.50 | 40.12 |
| | SIGMA_SHADOW | 23.38 | 0.00 | 23.38 |
| | SIGMA_SHADOW_TRANSLUCENCY | 42.31 | 0.00 | 42.31 |
| | RELAX_DIFFUSE | 120.31 | 65.44 | 54.88 |
| | RELAX_SPECULAR | 130.94 | 73.94 | 57.00 |
| | RELAX_DIFFUSE_SPECULAR | 215.31 | 107.69 | 107.62 |
| | REFERENCE | 33.75 | 33.75 | 0.00 |
| | | | | |
| 1440p | REBLUR_DIFFUSE | 157.50 | 82.50 | 75.00 |
| 1440p | REBLUR_DIFFUSE | 153.75 | 82.50 | 71.25 |
| | REBLUR_DIFFUSE_OCCLUSION | 75.00 | 52.50 | 22.50 |
| | REBLUR_DIFFUSE_SH | 247.50 | 112.50 | 135.00 |
| | REBLUR_SPECULAR | 180.00 | 97.50 | 82.50 |
| | REBLUR_DIFFUSE_SH | 243.75 | 112.50 | 131.25 |
| | REBLUR_SPECULAR | 187.50 | 97.50 | 90.00 |
| | REBLUR_SPECULAR_OCCLUSION | 90.00 | 67.50 | 22.50 |
| | REBLUR_SPECULAR_SH | 270.00 | 127.50 | 142.50 |
| | REBLUR_DIFFUSE_SPECULAR | 292.50 | 142.50 | 150.00 |
| | REBLUR_SPECULAR_SH | 277.50 | 127.50 | 150.00 |
| | REBLUR_DIFFUSE_SPECULAR | 300.00 | 142.50 | 157.50 |
| | REBLUR_DIFFUSE_SPECULAR_OCCLUSION | 127.50 | 82.50 | 45.00 |
| | REBLUR_DIFFUSE_SPECULAR_SH | 472.50 | 202.50 | 270.00 |
| | REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION | 157.50 | 82.50 | 75.00 |
| | REBLUR_DIFFUSE_SPECULAR_SH | 480.00 | 202.50 | 277.50 |
| | REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION | 153.75 | 82.50 | 71.25 |
| | SIGMA_SHADOW | 41.38 | 0.00 | 41.38 |
| | SIGMA_SHADOW_TRANSLUCENCY | 75.12 | 0.00 | 75.12 |
| | RELAX_DIFFUSE | 213.75 | 116.25 | 97.50 |
| | RELAX_SPECULAR | 232.50 | 131.25 | 101.25 |
| | RELAX_DIFFUSE_SPECULAR | 382.50 | 191.25 | 191.25 |
| | REFERENCE | 60.00 | 60.00 | 0.00 |
| | | | | |
| 2160p | REBLUR_DIFFUSE | 334.69 | 175.31 | 159.38 |
| 2160p | REBLUR_DIFFUSE | 326.75 | 175.31 | 151.44 |
| | REBLUR_DIFFUSE_OCCLUSION | 159.38 | 111.56 | 47.81 |
| | REBLUR_DIFFUSE_SH | 525.94 | 239.06 | 286.88 |
| | REBLUR_SPECULAR | 382.50 | 207.19 | 175.31 |
| | REBLUR_DIFFUSE_SH | 518.00 | 239.06 | 278.94 |
| | REBLUR_SPECULAR | 398.44 | 207.19 | 191.25 |
| | REBLUR_SPECULAR_OCCLUSION | 191.25 | 143.44 | 47.81 |
| | REBLUR_SPECULAR_SH | 573.75 | 270.94 | 302.81 |
| | REBLUR_DIFFUSE_SPECULAR | 621.56 | 302.81 | 318.75 |
| | REBLUR_SPECULAR_SH | 589.69 | 270.94 | 318.75 |
| | REBLUR_DIFFUSE_SPECULAR | 637.50 | 302.81 | 334.69 |
| | REBLUR_DIFFUSE_SPECULAR_OCCLUSION | 270.94 | 175.31 | 95.62 |
| | REBLUR_DIFFUSE_SPECULAR_SH | 1004.06 | 430.31 | 573.75 |
| | REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION | 334.69 | 175.31 | 159.38 |
| | REBLUR_DIFFUSE_SPECULAR_SH | 1020.00 | 430.31 | 589.69 |
| | REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION | 326.75 | 175.31 | 151.44 |
| | SIGMA_SHADOW | 87.94 | 0.00 | 87.94 |
| | SIGMA_SHADOW_TRANSLUCENCY | 159.56 | 0.00 | 159.56 |
| | RELAX_DIFFUSE | 454.31 | 247.12 | 207.19 |
Expand Down
2 changes: 1 addition & 1 deletion Resources/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Versioning rules:

#define VERSION_MAJOR 4
#define VERSION_MINOR 0
#define VERSION_BUILD 1
#define VERSION_BUILD 2
#define VERSION_REVISION 0

#define VERSION_STRING STR(VERSION_MAJOR.VERSION_MINOR.VERSION_BUILD.VERSION_REVISION)
101 changes: 29 additions & 72 deletions Shaders/Include/Common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,15 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
#define NRD_USE_EXPONENTIAL_WEIGHTS 0 // bool
#define NRD_BILATERAL_WEIGHT_CUTOFF 0.03
#define NRD_CATROM_SHARPNESS 0.5 // [ 0; 1 ], 0.5 matches Catmull-Rom
#define NRD_PARALLAX_NORMALIZATION 30.0
#define NRD_RADIANCE_COMPRESSION_MODE 3 // 0-4, specular color compression for spatial passes
#define NRD_EXP_WEIGHT_DEFAULT_SCALE 3.0

#if( NRD_NORMAL_ENCODING < NRD_NORMAL_ENCODING_R10G10B10A2_UNORM )
#define NRD_NORMAL_ENCODING_ERROR ( 0.5 / 256.0 )
#define NRD_NORMAL_ENCODING_ERROR ( 1.0 / 255.0 )
#elif( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_R10G10B10A2_UNORM )
#define NRD_NORMAL_ENCODING_ERROR ( 0.5 / 1024.0 )
#define NRD_NORMAL_ENCODING_ERROR ( 1.0 / 1023.0 )
#else
#define NRD_NORMAL_ENCODING_ERROR ( 0.5 / 65536.0 )
#define NRD_NORMAL_ENCODING_ERROR ( 1.0 / 65535.0 )
#endif

//==================================================================================================================
Expand Down Expand Up @@ -182,31 +181,16 @@ float GetSpecMagicCurve2( float roughness, float percentOfVolume = 0.987 )

/*
Produce same results:
ComputeParallax( Xprev - gCameraDelta, gOrthoMode == 0.0 ? pixelUv : smbPixelUv, gWorldToClip, gRectSize, gUnproject, gOrthoMode );
ComputeParallax( Xprev + gCameraDelta, gOrthoMode == 0.0 ? smbPixelUv : pixelUv, gWorldToClipPrev, gRectSize, gUnproject, gOrthoMode );
ComputeParallaxInPixels( Xprev - gCameraDelta, gOrthoMode == 0.0 ? pixelUv : smbPixelUv, gWorldToClip, gRectSize );
ComputeParallaxInPixels( Xprev + gCameraDelta, gOrthoMode == 0.0 ? smbPixelUv : pixelUv, gWorldToClipPrev, gRectSize );
*/
float ComputeParallax( float3 X, float2 uvForZeroParallax, float4x4 mWorldToClip, float2 rectSize, float unproject, float orthoMode )
float ComputeParallaxInPixels( float3 X, float2 uvForZeroParallax, float4x4 mWorldToClip, float2 rectSize )
{
float3 clip = STL::Geometry::ProjectiveTransform( mWorldToClip, X ).xyw;
clip.xy /= clip.z;
clip.y = -clip.y;

float2 uv = clip.xy * 0.5 + 0.5;
float invDist = orthoMode == 0.0 ? rsqrt( STL::Math::LengthSquared( X ) ) : rcp( clip.z );

float2 uv = STL::Geometry::GetScreenUv( mWorldToClip, X );
float2 parallaxInUv = uv - uvForZeroParallax;
float parallaxInPixels = length( parallaxInUv * rectSize );
float parallaxInUnits = PixelRadiusToWorld( unproject, orthoMode, parallaxInPixels, clip.z );
float parallax = parallaxInUnits * invDist;

return parallax * NRD_PARALLAX_NORMALIZATION;
}

float GetParallaxInPixels( float parallax, float unproject )
{
float smbParallaxInPixels = parallax / ( NRD_PARALLAX_NORMALIZATION * unproject );

return smbParallaxInPixels;
return parallaxInPixels;
}

float GetColorCompressionExposureForSpatialPasses( float roughness )
Expand Down Expand Up @@ -236,12 +220,12 @@ float GetColorCompressionExposureForSpatialPasses( float roughness )

// Thin lens

float EstimateCurvature( float3 n, float3 v, float3 N, float3 X )
float EstimateCurvature( float3 Nplane, float3 n, float3 v, float3 N, float3 X )
{
// https://computergraphics.stackexchange.com/questions/1718/what-is-the-simplest-way-to-compute-principal-curvature-for-a-mesh-triangle

float NoV = dot( N, v );
float3 x = 0 + v * dot( X - 0, N ) / NoV;
float NoV = dot( Nplane, v );
float3 x = 0 + v * dot( X - 0, Nplane ) / NoV;
float3 edge = x - X;
float edgeLenSq = STL::Math::LengthSquared( edge );
float curvature = dot( n - N, edge ) * STL::Math::PositiveRcp( edgeLenSq );
Expand All @@ -252,14 +236,16 @@ float EstimateCurvature( float3 n, float3 v, float3 N, float3 X )
float ApplyThinLensEquation( float NoV, float hitDist, float curvature )
{
/*
https://www.geeksforgeeks.org/sign-convention-for-spherical-mirrors/
Thin lens equation:
1 / F = 1 / O + 1 / I
F = R / 2 - focal distance
C = 1 / R - curvature
Sign convention:
convex : O(-), I(+), C(+)
concave : O(+), I(-), C(-)
concave : O(-), I(+ or -), C(-)
Why NoV?
hitDist is not O, we need to find projection to the axis:
Expand All @@ -275,60 +261,31 @@ float ApplyThinLensEquation( float NoV, float hitDist, float curvature )
I = [ ( O * NoV ) / ( 2CO * NoV - 1 ) ] / NoV
I = O / ( 2CO * NoV - 1 )
*/
float hitDistFocused = hitDist;
hitDistFocused *= -STL::Math::Sign( curvature );
hitDistFocused /= 2.0 * curvature * NoV * hitDistFocused - 1.0;
O is always negative, while hit distance is always positive:
I = -O / ( -2CO * NoV - 1 )
I = O / ( 2CO * NoV + 1 )
Interactive graph:
https://www.desmos.com/calculator/dn9spdgwiz
*/

// A mystical fix for silhouettes of convex surfaces observed under a grazing angle
hitDistFocused *= lerp( NoV, 1.0, 1.0 / ( 1.0 + max( curvature * hitDist, 0.0 ) ) );
// TODO: dropping NoV improves behavior on curved surfaces in general ( see i76, i148, b7, b22, b26 ), but test i133
// ( low curvature surface observed at grazing angle ) looks significantly worse, especially if motion is accelerated
float hitDistFocused = hitDist / ( 2.0 * curvature * hitDist * NoV + 1.0 );

return hitDistFocused;
}

float3 GetXvirtual(
float NoV, float hitDist, float curvature,
float3 X, float3 Xprev, float3 V,
float dominantFactor )
float3 GetXvirtual( float NoV, float hitDist, float curvature, float3 X, float3 Xprev, float3 V, float dominantFactor )
{
/*
C - curvature
O - object distance
I - image distance
F - focal distance
The lens equation:
[Eq 1] 1 / O + 1 / I = 1 / F
[Eq 2] For a spherical mirror F = -0.5 * R
[Eq 3] R = 1 / C
Find I from [Eq 1]:
1 / I = 1 / F - 1 / O
1 / I = ( O - F ) / ( F * O )
I = F * O / ( O - F )
Apply [Eq 2]:
I = -0.5 * R * O / ( O + 0.5 * R )
Apply [Eq 3]:
I = ( -0.5 * O / C ) / ( O + 0.5 / C )
I = ( -0.5 * O / C ) / ( ( O * C + 0.5 ) / C )
I = ( -0.5 * O / C ) * ( C / ( O * C + 0.5 ) )
I = -0.5 * O / ( 0.5 + C * O )
Reverse sign because I is negative:
I = 0.5 * O / ( 0.5 + C * O )
*/

float hitDistFocused = ApplyThinLensEquation( NoV, hitDist, curvature );

// "saturate" is needed to clamp values > 1 if curvature is negative
float compressionRatio = saturate( ( abs( hitDistFocused ) + NRD_EPS ) / ( hitDist + NRD_EPS ) );

float3 Xvirtual = lerp( Xprev, X, compressionRatio * dominantFactor ) - V * hitDistFocused * dominantFactor;
// Only hit distance is provided, not real motion in the virtual world. If the virtual position is close to the
// surface due to focusing, better to replace current position with previous position because surface motion is known.
float closenessToSurface = saturate( abs( hitDistFocused ) / ( hitDist + NRD_EPS ) );

return Xvirtual;
return lerp( Xprev, X, closenessToSurface * dominantFactor ) - V * hitDistFocused * dominantFactor;
}

// Kernel
Expand Down
Loading

0 comments on commit a28ad93

Please sign in to comment.