Skip to content

Commit

Permalink
NRD
Browse files Browse the repository at this point in the history
v4.3.2:

HIGHLIGHTS:
- bug fixes and improvements

DETAILS:
- NRD: improved 2D motion support
- NRD: improved relaxed roughness weight
- NRD: slightly reduced normal thresholds flattening curvature
- NRD: curvature improvements (better support for low precision normals, reintroduced high-parallax curvature)
- REBLUR / RELAX: improved "GetEncodingAwareNormalWeight" usage
- REBLUR: more relaxed roughness weight in HistoryFix pass
- REBLUR: improved specular fast history acceleration
  • Loading branch information
dzhdanNV committed Oct 9, 2023
1 parent e0e122b commit 39648c8
Show file tree
Hide file tree
Showing 23 changed files with 282 additions and 195 deletions.
6 changes: 1 addition & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ if (NOT NRD_DISABLE_SHADER_COMPILATION)

# ShaderMake general arguments
set (SHADERMAKE_GENERAL_ARGS
--header ${NRD_SHADER_BINARIES}
--useAPI --header ${NRD_SHADER_BINARIES}
--flatten
--stripReflection
--sourceDir "Shaders/Source"
Expand All @@ -181,10 +181,6 @@ if (NOT NRD_DISABLE_SHADER_COMPILATION)
-D NRD_INTERNAL
)

if (WIN32)
set (SHADERMAKE_GENERAL_ARGS --useAPI ${SHADERMAKE_GENERAL_ARGS})
endif ()

# ShaderMake commands for each shader code container
set (SHADERMAKE_COMMANDS "")

Expand Down
2 changes: 1 addition & 1 deletion External/MathLib
Submodule MathLib updated 1 files
+1 −1 External/sse2neon
2 changes: 1 addition & 1 deletion External/ShaderMake
Submodule ShaderMake updated 1 files
+4 −2 src/ShaderMake.cpp
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 3
#define NRD_VERSION_BUILD 1
#define NRD_VERSION_DATE "28 September 2023"
#define NRD_VERSION_BUILD 2
#define NRD_VERSION_DATE "9 October 2023"

#if defined(_MSC_VER)
#define NRD_CALL __fastcall
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# NVIDIA REAL-TIME DENOISERS v4.3.1 (NRD)
# NVIDIA REAL-TIME DENOISERS v4.3.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
2 changes: 1 addition & 1 deletion Resources/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ Versioning rules:

#define VERSION_MAJOR 4
#define VERSION_MINOR 3
#define VERSION_BUILD 1
#define VERSION_BUILD 2

#define VERSION_STRING STR(VERSION_MAJOR.VERSION_MINOR.VERSION_BUILD encoding=NRD_NORMAL_ENCODING.NRD_ROUGHNESS_ENCODING)
74 changes: 20 additions & 54 deletions Shaders/Include/Common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -39,28 +39,32 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.

// Switches ( default 1 )
#define NRD_USE_TILE_CHECK 1
#define NRD_USE_HIGH_PARALLAX_CURVATURE 1

// Switches ( default 0 )
#define NRD_USE_QUADRATIC_DISTRIBUTION 0
#define NRD_USE_EXPONENTIAL_WEIGHTS 0
#define NRD_USE_HIGH_PARALLAX_CURVATURE_SILHOUETTE_FIX 0 // it fixes silhouettes, but leads to less flattening on bumpy surfaces ( worse for bumpy surfaces ) and shorter arcs on smooth curved surfaces ( worse for low bit normals )

// Settings
#define NRD_BILATERAL_WEIGHT_CUTOFF 0.03
#define NRD_CATROM_SHARPNESS 0.5 // [ 0; 1 ], 0.5 matches Catmull-Rom
#define NRD_RADIANCE_COMPRESSION_MODE 3 // 0-4, specular color compression for spatial passes
#define NRD_EXP_WEIGHT_DEFAULT_SCALE 3.0
#define NRD_ROUGHNESS_SENSITIVITY 0.01 // smaller => more sensitive
#define NRD_CURVATURE_Z_THRESHOLD 0.1 // normalized %

// IMPORTANT: if == 1, then for 0-roughness "GetEncodingAwareNormalWeight" can return values < 1 even for same normals due to data re-packing
// IMPORTANT: suits for REBLUR and RELAX because both use RGBA8 normals internally
#define NRD_NORMAL_ULP ( 1.5 / 255.0 )

// IMPORTANT: best fit is critical for non oct-packed variants!
#if( NRD_NORMAL_ENCODING < NRD_NORMAL_ENCODING_R10G10B10A2_UNORM )
#define NRD_NORMAL_ENCODING_ERROR ( 1.0 / 255.0 )
#define NRD_NORMAL_ENCODING_ERROR ( 0.5 / 255.0 )
#elif( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_R10G10B10A2_UNORM )
#define NRD_NORMAL_ENCODING_ERROR ( 1.0 / 1023.0 )
#define NRD_NORMAL_ENCODING_ERROR ( 0.5 / 1023.0 )
#else
#define NRD_NORMAL_ENCODING_ERROR ( 1.0 / 65535.0 )
#define NRD_NORMAL_ENCODING_ERROR ( 0.5 / 65535.0 )
#endif

//==================================================================================================================
Expand Down Expand Up @@ -342,8 +346,6 @@ float2 GetHitDistanceWeightParams( float hitDist, float nonLinearAccumSpeed, flo
return float2( a, -b );
}

// Weights params

float2 GetRoughnessWeightParams( float roughness, float fraction, float sensitivity = NRD_ROUGHNESS_SENSITIVITY )
{
float a = 1.0 / lerp( sensitivity, 1.0, saturate( roughness * fraction ) );
Expand All @@ -352,17 +354,13 @@ float2 GetRoughnessWeightParams( float roughness, float fraction, float sensitiv
return float2( a, -b );
}

float2 GetRelaxedRoughnessWeightParams( float roughness, float roughnessModified = 1.0, float fraction = 1.0, float sensitivity = NRD_ROUGHNESS_SENSITIVITY )
float2 GetRelaxedRoughnessWeightParams( float m, float fraction = 1.0, float sensitivity = NRD_ROUGHNESS_SENSITIVITY )
{
// IMPORTANT: requires "GetRelaxedRoughnessWeight"
// "x ^ 2" makes test less sensitive
// Using "roughnessModified" for threshold allows to make test less sensitive on bumpy surfaces

roughness *= roughness;
roughnessModified *= roughnessModified;
// "m" makes test less sensitive to small deltas

float a = 1.0 / lerp( sensitivity, 1.0, saturate( roughnessModified * fraction ) );
float b = roughness * a;
// https://www.desmos.com/calculator/wkvacka5za
float a = 1.0 / lerp( lerp( m * m, m, fraction ), 1.0, sensitivity );
float b = m * a;

return float2( a, -b );
}
Expand All @@ -378,53 +376,21 @@ float2 GetRelaxedRoughnessWeightParams( float roughness, float roughnessModified

// Must be used for noisy data
// https://www.desmos.com/calculator/9yoyc3is2g
// scale = 3-5 is needed to match energy in "_ComputeNonExponentialWeight" ( especially when used in a recurrent loop )
#define _ComputeExponentialWeight( x, px, py ) \
ExpApprox( -NRD_EXP_WEIGHT_DEFAULT_SCALE * abs( ( x ) * ( px ) + ( py ) ) )
// scale = 3-5 is needed to match energy in "ComputeNonExponentialWeight" ( especially when used in a recurrent loop )
#define ComputeExponentialWeight( x, px, py ) \
ExpApprox( -NRD_EXP_WEIGHT_DEFAULT_SCALE * abs( ( x ) * px + py ) )

// A good choice for non noisy data
// IMPORTANT: cutoffs are needed to minimize floating point precision drifting
#define _ComputeNonExponentialWeight( x, px, py ) \
STL::Math::SmoothStep( 0.999, 0.001, abs( ( x ) * ( px ) + ( py ) ) )
#define ComputeNonExponentialWeight( x, px, py ) \
STL::Math::SmoothStep( 0.999, 0.001, abs( ( x ) * px + py ) )

#if( NRD_USE_EXPONENTIAL_WEIGHTS == 1 )
#define _ComputeWeight( x, px, py ) \
_ComputeExponentialWeight( x, px, py )
#define ComputeWeight( x, px, py ) ComputeExponentialWeight( x, px, py )
#else
#define _ComputeWeight( x, px, py ) \
_ComputeNonExponentialWeight( x, px, py )
#define ComputeWeight( x, px, py ) ComputeNonExponentialWeight( x, px, py )
#endif

float GetRoughnessWeight( float2 params, float roughness )
{
return _ComputeWeight( roughness, params.x, params.y );
}

float GetRelaxedRoughnessWeight( float2 params, float roughness )
{
return GetRoughnessWeight( params, roughness * roughness );
}

float GetHitDistanceWeight( float2 params, float hitDist )
{
return _ComputeExponentialWeight( hitDist, params.x, params.y );
}

float GetGeometryWeight( float2 params, float3 n0, float3 p )
{
float d = dot( n0, p );

return _ComputeWeight( d, params.x, params.y );
}

float GetNormalWeight( float param, float3 N, float3 n )
{
float cosa = saturate( dot( N, n ) );
float angle = STL::Math::AcosApprox( cosa );

return _ComputeWeight( angle, param, 0.0 );
}

float GetGaussianWeight( float r )
{
return exp( -0.66 * r * r ); // assuming r is normalized to 1
Expand All @@ -437,7 +403,7 @@ float GetEncodingAwareNormalWeight( float3 Ncurr, float3 Nprev, float maxAngle,
// Anything below "angleThreshold" is ignored
angleThreshold += NRD_NORMAL_ULP;

float cosa = saturate( dot( Ncurr, Nprev ) );
float cosa = dot( Ncurr, Nprev );

float a = 1.0 / maxAngle;
float d = STL::Math::AcosApprox( cosa );
Expand Down
21 changes: 0 additions & 21 deletions Shaders/Include/REBLUR/REBLUR_Common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ uint PackData2( float fbits, float curvature, float virtualHistoryAmount )
// other - free // TODO: use if needed

uint p = uint( fbits + 0.5 );

p |= uint( saturate( virtualHistoryAmount ) * 255.0 + 0.5 ) << 8;
p |= f32tof16( curvature ) << 16;

Expand Down Expand Up @@ -349,26 +348,6 @@ float2 GetTemporalAccumulationParams( float isInScreenMulFootprintQuality, float

// Weights

float GetCombinedWeight
(
float2 geometryWeightParams, float3 Nv, float3 Xvs,
float normalWeightParams, float3 N, float4 Ns,
float2 roughnessWeightParams = 0
)
{
float3 a = float3( geometryWeightParams.x, normalWeightParams, roughnessWeightParams.x );
float3 b = float3( geometryWeightParams.y, 0.0, roughnessWeightParams.y );

float3 t;
t.x = dot( Nv, Xvs );
t.y = STL::Math::AcosApprox( saturate( dot( N, Ns.xyz ) ) );
t.z = Ns.w; // IMPORTANT: requires "GetRoughnessWeightParams"

float3 w = _ComputeWeight( t, a, b );

return w.x * w.y * w.z;
}

void BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights(
float2 samplePos, float2 invTextureSize,
float4 bilinearCustomWeights, bool useBicubic,
Expand Down
15 changes: 12 additions & 3 deletions Shaders/Include/REBLUR/REBLUR_Common_DiffuseSpatialFilter.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
fractionScale = REBLUR_POST_BLUR_FRACTION_SCALE;
#endif

float lobeAngleFractionScale = gLobeAngleFraction * fractionScale;
float lobeAngleFractionScale = saturate( gLobeAngleFraction * fractionScale );

float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gHitDistParams, 1.0 );
float hitDist = ExtractHitDist( diff ) * hitDistScale;
Expand Down Expand Up @@ -84,6 +84,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
// Weights
float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumSize, Xv, Nv, diffNonLinearAccumSpeed );
float normalWeightParams = GetNormalWeightParams( diffNonLinearAccumSpeed, lobeAngleFractionScale );
float2 px = float2( geometryWeightParams.x, normalWeightParams );
float2 py = float2( geometryWeightParams.y, 0.0 );

float2 hitDistanceWeightParams = GetHitDistanceWeightParams( ExtractHitDist( diff ), diffNonLinearAccumSpeed );
float minHitDistWeight = REBLUR_HIT_DIST_MIN_WEIGHT( 1.0 ) * fractionScale;

Expand Down Expand Up @@ -147,9 +150,15 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.

// Sample weights
float w = CompareMaterials( materialID, materialIDs, gDiffMaterialMask );

float2 x;
x.x = dot( Nv, Xvs );
x.y = STL::Math::AcosApprox( dot( N, Ns.xyz ) );
x = ComputeWeight( x, px, py );
w *= x.x * x.y;

w *= GetGaussianWeight( offset.z );
w *= GetCombinedWeight( geometryWeightParams, Nv, Xvs, normalWeightParams, N, Ns );
w *= lerp( minHitDistWeight, 1.0, GetHitDistanceWeight( hitDistanceWeightParams, ExtractHitDist( s ) ) );
w *= lerp( minHitDistWeight, 1.0, ComputeExponentialWeight( ExtractHitDist( s ), hitDistanceWeightParams.x, hitDistanceWeightParams.y ) );

// Get rid of potential NANs outside of rendering rectangle or denoising range
w = ( IsInScreen( uv ) && !isnan( w ) ) ? w : 0.0;
Expand Down
20 changes: 15 additions & 5 deletions Shaders/Include/REBLUR/REBLUR_Common_SpecularSpatialFilter.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
fractionScale = REBLUR_POST_BLUR_FRACTION_SCALE;
#endif

float lobeAngleFractionScale = gLobeAngleFraction * fractionScale;
float roughnessFractionScale = gRoughnessFraction * fractionScale;
float lobeAngleFractionScale = saturate( gLobeAngleFraction * fractionScale );
float roughnessFractionScale = saturate( gRoughnessFraction * fractionScale );

float hitDist = ExtractHitDist( spec ) * _REBLUR_GetHitDistanceNormalization( viewZ, gHitDistParams, roughness );

Expand Down Expand Up @@ -102,8 +102,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
// Weights
float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumSize, Xv, Nv, specNonLinearAccumSpeed );
float normalWeightParams = GetNormalWeightParams( specNonLinearAccumSpeed, lobeAngleFractionScale, roughness );
float2 hitDistanceWeightParams = GetHitDistanceWeightParams( ExtractHitDist( spec ), specNonLinearAccumSpeed, roughness );
float2 roughnessWeightParams = GetRoughnessWeightParams( roughness, roughnessFractionScale );
float3 px = float3( geometryWeightParams.x, normalWeightParams, roughnessWeightParams.x );
float3 py = float3( geometryWeightParams.y, 0.0, roughnessWeightParams.y );

float2 hitDistanceWeightParams = GetHitDistanceWeightParams( ExtractHitDist( spec ), specNonLinearAccumSpeed, roughness );
float minHitDistWeight = REBLUR_HIT_DIST_MIN_WEIGHT( smc ) * fractionScale;

// Sampling
Expand Down Expand Up @@ -166,10 +169,17 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.

// Sample weights
float w = CompareMaterials( materialID, materialIDs, gSpecMaterialMask );
w *= GetCombinedWeight( geometryWeightParams, Nv, Xvs, normalWeightParams, N, Ns, roughnessWeightParams );

float3 x;
x.x = dot( Nv, Xvs );
x.y = STL::Math::AcosApprox( dot( N, Ns.xyz ) );
x.z = Ns.w;
x = ComputeWeight( x, px, py );
w *= x.x * x.y * x.z;

float geometryWeight = w;
w *= GetGaussianWeight( offset.z );
w *= lerp( minHitDistWeight, 1.0, GetHitDistanceWeight( hitDistanceWeightParams, ExtractHitDist( s ) ) );
w *= lerp( minHitDistWeight, 1.0, ComputeExponentialWeight( ExtractHitDist( s ), hitDistanceWeightParams.x, hitDistanceWeightParams.y ) );

// Get rid of potential NANs outside of rendering rectangle or denoising range
w = ( IsInScreen( uv ) && !isnan( w ) ) ? w : 0.0;
Expand Down
11 changes: 6 additions & 5 deletions Shaders/Include/REBLUR/REBLUR_Config.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
#define REBLUR_SHOW_FAST_HISTORY 1 // requires "blurRadius" = 0
#define REBLUR_SHOW_CURVATURE 2
#define REBLUR_SHOW_CURVATURE_SIGN 3
#define REBLUR_SHOW_VIRTUAL_HISTORY_CONFIDENCE 4
#define REBLUR_SHOW_VIRTUAL_HISTORY_NORMAL_CONFIDENCE 5
#define REBLUR_SHOW_VIRTUAL_HISTORY_ROUGHNESS_CONFIDENCE 6
#define REBLUR_SHOW_VIRTUAL_HISTORY_PARALLAX_CONFIDENCE 7
#define REBLUR_SHOW_HIT_DIST_FOR_TRACKING 8
#define REBLUR_SHOW_SURFACE_HISTORY_CONFIDENCE 4
#define REBLUR_SHOW_VIRTUAL_HISTORY_CONFIDENCE 5
#define REBLUR_SHOW_VIRTUAL_HISTORY_NORMAL_CONFIDENCE 6
#define REBLUR_SHOW_VIRTUAL_HISTORY_ROUGHNESS_CONFIDENCE 7
#define REBLUR_SHOW_VIRTUAL_HISTORY_PARALLAX_CONFIDENCE 8
#define REBLUR_SHOW_HIT_DIST_FOR_TRACKING 9

#define REBLUR_SHOW 0 // 0 or "REBLUR_SHOW_X"

Expand Down
18 changes: 8 additions & 10 deletions Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_HistoryFix.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -145,14 +145,13 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :
float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, z, gOrthoMode );
float NoX = dot( Nv, Xvs );

float cosa = saturate( dot( Ns.xyz, N ) );
float angle = STL::Math::AcosApprox( cosa );
float angle = STL::Math::AcosApprox( dot( Ns.xyz, N ) );

// Accumulate
float w = IsInScreen( uv );
w *= CompareMaterials( materialID, materialIDs, gDiffMaterialMask );
w *= _ComputeWeight( NoX, diffGeometryWeightParams.x, diffGeometryWeightParams.y );
w *= _ComputeExponentialWeight( angle, diffNormalWeightParam, 0.0 );
w *= ComputeWeight( NoX, diffGeometryWeightParams.x, diffGeometryWeightParams.y );
w *= ComputeExponentialWeight( angle, diffNormalWeightParam, 0.0 );

REBLUR_TYPE s = gIn_Diff.SampleLevel( gNearestClamp, uvScaled, 0 );

Expand Down Expand Up @@ -302,7 +301,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :

float specNormalWeightParam = 1.0 / max( lobeHalfAngle, NRD_NORMAL_ULP );
float2 specGeometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumSize, Xv, Nv, specNonLinearAccumSpeed );
float2 relaxedRoughnessWeightParams = GetRelaxedRoughnessWeightParams( roughness, roughness, gRoughnessFraction );
float2 relaxedRoughnessWeightParams = GetRelaxedRoughnessWeightParams( roughness * roughness, sqrt( gRoughnessFraction ) );

float hitDistNormAtCenter = ExtractHitDist( spec );
float smc = GetSpecMagicCurve( roughness );
Expand Down Expand Up @@ -338,15 +337,14 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :
float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, z, gOrthoMode );
float NoX = dot( Nv, Xvs );

float cosa = saturate( dot( Ns.xyz, N ) );
float angle = STL::Math::AcosApprox( cosa );
float angle = STL::Math::AcosApprox( dot( Ns.xyz, N ) );

// Accumulate
float w = IsInScreen( uv );
w *= CompareMaterials( materialID, materialIDs, gSpecMaterialMask );
w *= _ComputeWeight( NoX, specGeometryWeightParams.x, specGeometryWeightParams.y );
w *= _ComputeExponentialWeight( angle, specNormalWeightParam, 0.0 );
w *= _ComputeExponentialWeight( Ns.w * Ns.w, relaxedRoughnessWeightParams.x, relaxedRoughnessWeightParams.y );
w *= ComputeWeight( NoX, specGeometryWeightParams.x, specGeometryWeightParams.y );
w *= ComputeExponentialWeight( angle, specNormalWeightParam, 0.0 );
w *= ComputeExponentialWeight( Ns.w * Ns.w, relaxedRoughnessWeightParams.x, relaxedRoughnessWeightParams.y );

REBLUR_TYPE s = gIn_Spec.SampleLevel( gNearestClamp, uvScaled, 0 );

Expand Down
Loading

0 comments on commit 39648c8

Please sign in to comment.