Skip to content

Commit

Permalink
v4.6.1:
Browse files Browse the repository at this point in the history
HIGHLIGHTS:

- NRD: shaders made compatible with Vulkan 1.2
- NRD: improved curvature
- REBLUR: updated code to reflect fixes in MathLib

DETAILS:

- NRD: shaders made compatible with Vulkan 1.2
- NRD: improved curvature
- REBLUR: updated code to reflect fixes in MathLib
  • Loading branch information
dzhdanNV committed Mar 25, 2024
1 parent dae3b33 commit db4f66f
Show file tree
Hide file tree
Showing 19 changed files with 97 additions and 95 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ if (NOT NRD_DISABLE_SHADER_COMPILATION)
--sourceDir "Shaders/Source"
--allResourcesBound
--WX
--vulkanVersion 1.2
-c Shaders.cfg
-o "${NRD_SHADERS_PATH}"
-I "External/MathLib"
Expand Down
2 changes: 1 addition & 1 deletion External/MathLib
Submodule MathLib updated 1 files
+11 −22 STL.hlsli
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 6
#define NRD_VERSION_BUILD 0
#define NRD_VERSION_DATE "19 March 2024"
#define NRD_VERSION_BUILD 1
#define NRD_VERSION_DATE "25 March 2024"

#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.6.0 (NRD)
# NVIDIA REAL-TIME DENOISERS v4.6.1 (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 6
#define VERSION_BUILD 0
#define VERSION_BUILD 1

#define VERSION_STRING STR(VERSION_MAJOR.VERSION_MINOR.VERSION_BUILD encoding=NRD_NORMAL_ENCODING.NRD_ROUGHNESS_ENCODING)
34 changes: 17 additions & 17 deletions Shaders/Include/Common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
#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 %
#define NRD_MAX_ALLOWED_VIRTUAL_MOTION_ACCELERATION 15.0 // keep relatively high to avoid ruining concave mirrors

// 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
Expand Down Expand Up @@ -288,9 +289,19 @@ float GetColorCompressionExposureForSpatialPasses( float roughness )
#endif
}

float GetSpecLobeTanHalfAngle( float roughness, float percentOfVolume = 0.75 )
{
// TODO: ideally should migrate to fixed "STL::ImportanceSampling::GetSpecularLobeTanHalfAngle", but since
// denoisers behavior have been tuned for the old version, let's continue to use it in critical places
roughness = saturate( roughness );
percentOfVolume = saturate( percentOfVolume );

return roughness * roughness * percentOfVolume / ( 1.0 - percentOfVolume + NRD_EPS );
}

// Thin lens

float ApplyThinLensEquation( float NoV, float hitDist, float curvature )
float ApplyThinLensEquation( float hitDist, float curvature )
{
/*
https://computergraphics.stackexchange.com/questions/1718/what-is-the-simplest-way-to-compute-principal-curvature-for-a-mesh-triangle
Expand All @@ -305,39 +316,28 @@ float ApplyThinLensEquation( float NoV, float hitDist, float curvature )
convex : O(-), I(+), C(+)
concave : O(-), I(+ or -), C(-)
Why NoV?
hitDist is not O, we need to find projection to the axis:
O = hitDist * NoV
hitDistFocused is not I, we need to reproject it back to the view direction:
hitDistFocused = I / NoV
Combine:
2C = 1 / O + 1 / I
1 / I = 2C - 1 / O
1 / I = ( 2CO - 1 ) / O
I = O / ( 2CO - 1 )
I = [ ( O * NoV ) / ( 2CO * NoV - 1 ) ] / NoV
I = O / ( 2CO * NoV - 1 )
O is always negative, while hit distance is always positive:
I = -O / ( -2CO * NoV - 1 )
I = O / ( 2CO * NoV + 1 )
I = -O / ( -2CO - 1 )
I = O / ( 2CO + 1 )
Interactive graph:
https://www.desmos.com/calculator/dn9spdgwiz
*/

// TODO: dropping NoV improves behavior on curved surfaces in general ( see 76, 148, b7, b22, b26 ), but test 133
// ( 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 );
float hitDistFocused = hitDist / ( 2.0 * curvature * hitDist + 1.0 );

return hitDistFocused;
}

float3 GetXvirtual( float NoV, float hitDist, float curvature, float3 X, float3 Xprev, float3 V, float dominantFactor )
float3 GetXvirtual( float hitDist, float curvature, float3 X, float3 Xprev, float3 V, float dominantFactor )
{
float hitDistFocused = ApplyThinLensEquation( NoV, hitDist, curvature );
float hitDistFocused = ApplyThinLensEquation( hitDist, curvature );

// 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.
Expand Down
6 changes: 3 additions & 3 deletions Shaders/Include/REBLUR_Common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,10 @@ float2x3 GetKernelBasis( float3 D, float3 N, float NoD, float roughness = 1.0, f

// Weight parameters

float GetNormalWeightParams( float nonLinearAccumSpeed, float fraction, float roughness = 1.0 )
float GetNormalWeightParams( float nonLinearAccumSpeed, float roughness = 1.0 )
{
float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughness );
angle *= lerp( saturate( fraction ), 1.0, nonLinearAccumSpeed ); // TODO: use as "percentOfVolume" instead?
float percentOfVolume = REBLUR_MAX_PERCENT_OF_LOBE_VOLUME * lerp( gLobeAngleFraction, 1.0, nonLinearAccumSpeed );
float angle = atan( STL::ImportanceSampling::GetSpecularLobeTanHalfAngle( roughness, percentOfVolume ) );

return 1.0 / max( angle, NRD_NORMAL_ULP );
}
Expand Down
4 changes: 1 addition & 3 deletions Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
fractionScale = REBLUR_POST_BLUR_FRACTION_SCALE;
#endif

float lobeAngleFractionScale = saturate( gLobeAngleFraction * fractionScale );

float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gHitDistParams, 1.0 );
float hitDist = ExtractHitDist( diff ) * hitDistScale;

Expand Down Expand Up @@ -78,7 +76,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.

// Weights
float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumSize, Xv, Nv, diffNonLinearAccumSpeed );
float normalWeightParams = GetNormalWeightParams( diffNonLinearAccumSpeed, lobeAngleFractionScale );
float normalWeightParams = GetNormalWeightParams( diffNonLinearAccumSpeed ) / fractionScale;
float2 px = float2( geometryWeightParams.x, normalWeightParams );
float2 py = float2( geometryWeightParams.y, 0.0 );

Expand Down
9 changes: 4 additions & 5 deletions Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,14 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.
fractionScale = REBLUR_POST_BLUR_FRACTION_SCALE;
#endif

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

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

// Min blur radius
float4 Dv = STL::ImportanceSampling::GetSpecularDominantDirection( Nv, Vv, roughness, STL_SPECULAR_DOMINANT_DIRECTION_G2 );
float NoD = abs( dot( Nv, Dv.xyz ) );
float lobeTanHalfAngle = STL::ImportanceSampling::GetSpecularLobeTanHalfAngle( roughness );
float lobeTanHalfAngle = STL::ImportanceSampling::GetSpecularLobeTanHalfAngle( roughness, REBLUR_MAX_PERCENT_OF_LOBE_VOLUME );
float lobeRadius = hitDist * NoD * lobeTanHalfAngle;
float minBlurRadius = lobeRadius / PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ + hitDist * Dv.w );

Expand Down Expand Up @@ -96,8 +95,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.

// Weights
float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumSize, Xv, Nv, specNonLinearAccumSpeed );
float normalWeightParams = GetNormalWeightParams( specNonLinearAccumSpeed, lobeAngleFractionScale, roughness );
float2 roughnessWeightParams = GetRoughnessWeightParams( roughness, roughnessFractionScale );
float normalWeightParams = GetNormalWeightParams( specNonLinearAccumSpeed, roughness ) / fractionScale;
float2 roughnessWeightParams = GetRoughnessWeightParams( roughness, roughnessFractionScaled );
float3 px = float3( geometryWeightParams.x, normalWeightParams, roughnessWeightParams.x );
float3 py = float3( geometryWeightParams.y, 0.0, roughnessWeightParams.y );

Expand Down
1 change: 1 addition & 0 deletions Shaders/Include/REBLUR_Config.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited.

#define REBLUR_HIT_DIST_MIN_WEIGHT( smc ) ( 0.1 * smc ) // was 0.1

#define REBLUR_MAX_PERCENT_OF_LOBE_VOLUME 0.75
#define REBLUR_VIRTUAL_MOTION_PREV_PREV_WEIGHT_ITERATION_NUM 2
#define REBLUR_COLOR_CLAMPING_SIGMA_SCALE 2.0 // using smaller values leads to bias if camera rotates slowly due to reprojection instabilities
#define REBLUR_FIREFLY_SUPPRESSOR_MAX_RELATIVE_INTENSITY float2( 10.0, 1.1 )
Expand Down
8 changes: 2 additions & 6 deletions Shaders/Include/REBLUR_HistoryFix.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :
// Parameters
float diffNonLinearAccumSpeed = 1.0 / ( 1.0 + frameNum.x );

float diffNormalWeightParam = GetNormalWeightParams( diffNonLinearAccumSpeed, 1.0 );
float diffNormalWeightParam = GetNormalWeightParams( diffNonLinearAccumSpeed );
float2 diffGeometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity * slopeScale, frustumSize, Xv, Nv, diffNonLinearAccumSpeed );

float sumd = 1.0 + frameNum.x;
Expand Down Expand Up @@ -305,11 +305,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :
float specNonLinearAccumSpeed = 1.0 / ( 1.0 + frameNum.y );
float hitDistNormAtCenter = ExtractHitDist( spec );

float lobeEnergy = lerp( 0.75, 0.85, specNonLinearAccumSpeed );
float lobeHalfAngle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughness, lobeEnergy ); // up to 85% energy to depend less on normal weight
lobeHalfAngle *= specNonLinearAccumSpeed;

float specNormalWeightParam = 1.0 / max( lobeHalfAngle, NRD_NORMAL_ULP );
float specNormalWeightParam = GetNormalWeightParams( specNonLinearAccumSpeed, roughness );
float2 specGeometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity * slopeScale, frustumSize, Xv, Nv, specNonLinearAccumSpeed );
float2 relaxedRoughnessWeightParams = GetRelaxedRoughnessWeightParams( roughness * roughness, sqrt( gRoughnessFraction ) );
float2 hitDistanceWeightParams = GetHitDistanceWeightParams( hitDistNormAtCenter, specNonLinearAccumSpeed, roughness );
Expand Down
4 changes: 2 additions & 2 deletions Shaders/Include/REBLUR_HitDistReconstruction.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :
float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumSize, Xv, Nv, 1.0 );

float2 relaxedRoughnessWeightParams = GetRelaxedRoughnessWeightParams( roughness * roughness );
float diffNormalWeightParam = GetNormalWeightParams( 1.0, 1.0, 1.0 );
float specNormalWeightParam = GetNormalWeightParams( 1.0, 1.0, roughness );
float diffNormalWeightParam = GetNormalWeightParams( 1.0 );
float specNormalWeightParam = GetNormalWeightParams( 1.0, roughness );

// Hit distance reconstruction
float2 sum = 1000.0 * float2( center.xy != 0.0 );
Expand Down
Loading

0 comments on commit db4f66f

Please sign in to comment.