Skip to content

Commit

Permalink
v4.3.4:
Browse files Browse the repository at this point in the history
HIGHLIGHTS:
- NRD: improved IQ
- NRD: fixed regressions
- REBLUR: improved behavior for highly variadic (noisy) roughness�
DETAILS:
- NRD: fixed curvature related regression
- RELAX / REBLUR: fixed snapping to screen edges in some cases
- RELAX: small improvement to specular "smb" confidence
- REBLUR: improved temporal stabilization (better behavior on screen edges and in disocclusions)
- REBLUR: improved roughness based disocclusion (less sensitive to noise in roughness)
- REBLUR: improved step between taps in prev-prev test
- Cmake: fixed minor bug in SIMD selection
  • Loading branch information
dzhdanNV committed Oct 24, 2023
1 parent a35adb4 commit 2d94c1f
Show file tree
Hide file tree
Showing 12 changed files with 193 additions and 160 deletions.
10 changes: 5 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ if (MSVC)
endif ()

# Compile options
IF(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
SET(SIMD -msse4.1)
ELSE(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
SET(SIMD -fPIC)
ENDIF()
if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64")
set (SIMD -msse4.1)
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
set (SIMD -fPIC)
endif ()

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set (COMPILE_OPTIONS ${SIMD} -Wextra)
Expand Down
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 3
#define NRD_VERSION_DATE "12 October 2023"
#define NRD_VERSION_BUILD 4
#define NRD_VERSION_DATE "20 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.3 (NRD)
# NVIDIA REAL-TIME DENOISERS v4.3.4 (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 3
#define VERSION_BUILD 4

#define VERSION_STRING STR(VERSION_MAJOR.VERSION_MINOR.VERSION_BUILD encoding=NRD_NORMAL_ENCODING.NRD_ROUGHNESS_ENCODING)
16 changes: 16 additions & 0 deletions Shaders/Include/Common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,24 @@ float4 GetBlurKernelRotation( compiletime const uint mode, uint2 pixelPos, float
return baseRotator;
}

// IMPORTANT: use "IsInScreen2x2" in critical places
float IsInScreen( float2 uv )
{
return float( all( saturate( uv ) == uv ) );
}

// x y
// z w
float4 IsInScreen2x2( float2 footprintOrigin, float2 rectSize )
{
float4 p = footprintOrigin.xyxy + float4( 0, 0, 1, 1 );

float4 r = float4( p >= 0.0 );
r *= float4( p < rectSize.xyxy );

return r.xzxz * r.yyww;
}

float2 ApplyCheckerboardShift( float2 uv, uint mode, uint counter, float2 screenSize, float2 invScreenSize, uint frameIndex )
{
int2 uvi = int2( uv * screenSize );
Expand Down Expand Up @@ -385,6 +398,9 @@ float2 GetRelaxedRoughnessWeightParams( float m, float fraction = 1.0, float sen
#define ComputeNonExponentialWeight( x, px, py ) \
STL::Math::SmoothStep( 0.999, 0.001, abs( ( x ) * px + py ) )

#define ComputeNonExponentialWeightWithSigma( x, px, py, sigma ) \
STL::Math::SmoothStep( 0.999, 0.001, abs( ( x ) * px + py ) - sigma * px )

#if( NRD_USE_EXPONENTIAL_WEIGHTS == 1 )
#define ComputeWeight( x, px, py ) ComputeExponentialWeight( x, px, py )
#else
Expand Down
2 changes: 1 addition & 1 deletion Shaders/Include/NRD.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ float4 NRD_FrontEnd_UnpackNormalAndRoughness( float4 p, out float materialID )
#if( NRD_ROUGHNESS_ENCODING == NRD_ROUGHNESS_ENCODING_SQRT_LINEAR )
r.w *= r.w;
#elif( NRD_ROUGHNESS_ENCODING == NRD_ROUGHNESS_ENCODING_SQ_LINEAR )
r.w = sqrt( r.w );
r.w = sqrt( saturate( r.w ) );
#endif

return r;
Expand Down
5 changes: 2 additions & 3 deletions Shaders/Include/REBLUR/REBLUR_Common.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,8 @@ float4 UnpackData1( float4 p )
uint PackData2( float fbits, float curvature, float virtualHistoryAmount )
{
// BITS:
// 0 - smbAllowCatRom
// 1-4 - smbOcclusion 2x2
// other - free // TODO: use if needed
// 0-3 - smbOcclusion 2x2
// 4-7 - vmbOcclusion 2x2

uint p = uint( fbits + 0.5 );
p |= uint( saturate( virtualHistoryAmount ) * 255.0 + 0.5 ) << 8;
Expand Down
8 changes: 8 additions & 0 deletions Shaders/Include/REBLUR/REBLUR_Config.hlsli
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ static const float3 g_Special8[ 8 ] =
float3( -0.25 * sqrt( 2.0 ) , -0.25 * sqrt( 2.0 ) , 0.5 )
};

#ifdef REBLUR_DIRECTIONAL_OCCLUSION
#undef REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA
#define REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA 0

#undef REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TA
#define REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TA 0
#endif

// PERFORMANCE MODE: x1.25 perf boost by sacrificing IQ ( DIFFUSE_SPECULAR on RTX 3090 @ 1440p 2.05 vs 2.55 ms )
#ifdef REBLUR_PERFORMANCE_MODE
#undef REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -224,22 +224,16 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :
float4 data1 = UnpackData1( gIn_Data1[ pixelPos ] );
float2 data2 = UnpackData2( gIn_Data2[ pixelPos ], bits );

float4 smbOcclusion = float4( ( bits & uint4( 2, 4, 8, 16 ) ) != 0 );

float pixelSize = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ );
float stabilizationStrength = gStabilizationStrength * float( pixelUv.x >= gSplitScreen );

STL::Filtering::Bilinear smbBilinearFilter = STL::Filtering::GetBilinearFilter( saturate( smbPixelUv ), gRectSizePrev );

// Only for "...WithMaterialID" even if material ID test is disabled
// Surface motion footprint
STL::Filtering::Bilinear smbBilinearFilter = STL::Filtering::GetBilinearFilter( smbPixelUv, gRectSizePrev );
float4 smbOcclusion = float4( ( bits & uint4( 1, 2, 4, 8 ) ) != 0 );
float4 smbOcclusionWeights = STL::Filtering::GetBilinearCustomWeights( smbBilinearFilter, smbOcclusion );
bool smbIsCatromAllowed = ( bits & 1 ) != 0 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS;

bool smbAllowCatRom = dot( smbOcclusion, 1.0 ) > 3.5 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS;
float smbFootprintQuality = STL::Filtering::ApplyBilinearFilter( smbOcclusion.x, smbOcclusion.y, smbOcclusion.z, smbOcclusion.w, smbBilinearFilter );
smbFootprintQuality = STL::Math::Sqrt01( smbFootprintQuality );

float smbIsInScreenMulFootprintQuality = IsInScreen( smbPixelUv ) * smbFootprintQuality;

// Diffuse
#ifdef REBLUR_DIFFUSE
// Sample history - surface motion
Expand All @@ -248,7 +242,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :

BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights(
saturate( smbPixelUv ) * gRectSizePrev, gInvScreenSize,
smbOcclusionWeights, smbIsCatromAllowed,
smbOcclusionWeights, smbAllowCatRom,
gIn_Diff_StabilizedHistory, smbDiffHistory
#ifdef REBLUR_SH
, gIn_DiffSh_StabilizedHistory, smbDiffShHistory
Expand All @@ -260,10 +254,10 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :

// Compute antilag
float diffStabilizationStrength = stabilizationStrength * float( smbPixelUv.x >= gSplitScreen );
float diffAntilag = ComputeAntilag( smbDiffHistory, diff, diffSigma, gAntilagParams, data1.x );
float diffAntilag = ComputeAntilag( smbDiffHistory, diff, diffSigma, gAntilagParams, smbFootprintQuality * data1.x );

// Clamp history and combine with the current frame
float2 diffTemporalAccumulationParams = GetTemporalAccumulationParams( smbIsInScreenMulFootprintQuality, data1.x );
float2 diffTemporalAccumulationParams = GetTemporalAccumulationParams( smbFootprintQuality, data1.x );

float diffHistoryWeight = diffTemporalAccumulationParams.x;
diffHistoryWeight *= diffAntilag; // this is important
Expand Down Expand Up @@ -352,28 +346,33 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :

BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights(
saturate( smbPixelUv ) * gRectSizePrev, gInvScreenSize,
smbOcclusionWeights, smbIsCatromAllowed,
smbOcclusionWeights, smbAllowCatRom,
gIn_Spec_StabilizedHistory, smbSpecHistory
#ifdef REBLUR_SH
, gIn_SpecSh_StabilizedHistory, smbSpecShHistory
#endif
);

// Virtual motion footprint
STL::Filtering::Bilinear vmbBilinearFilter = STL::Filtering::GetBilinearFilter( vmbPixelUv, gRectSizePrev );
float4 vmbOcclusion = float4( ( bits & uint4( 16, 32, 64, 128 ) ) != 0 );
float4 vmbOcclusionWeights = STL::Filtering::GetBilinearCustomWeights( vmbBilinearFilter, vmbOcclusion );
bool vmbAllowCatRom = dot( vmbOcclusion, 1.0 ) > 3.5 && REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS;
float vmbFootprintQuality = STL::Filtering::ApplyBilinearFilter( vmbOcclusion.x, vmbOcclusion.y, vmbOcclusion.z, vmbOcclusion.w, vmbBilinearFilter );
vmbFootprintQuality = STL::Math::Sqrt01( vmbFootprintQuality );

// Sample history - virtual motion
REBLUR_TYPE vmbSpecHistory;
#if( REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS == 1 )
BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights(
saturate( vmbPixelUv ) * gRectSizePrev, gInvScreenSize,
0, true,
gIn_Spec_StabilizedHistory, vmbSpecHistory
);
#else
vmbSpecHistory = gIn_Spec_StabilizedHistory.SampleLevel( gLinearClamp, vmbPixelUv * gResolutionScalePrev, 0 );
#endif
REBLUR_SH_TYPE vmbSpecShHistory;

#ifdef REBLUR_SH
float4 vmbSpecShHistory = gIn_SpecSh_StabilizedHistory.SampleLevel( gLinearClamp, vmbPixelUv * gResolutionScalePrev, 0 );
#endif
BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights(
saturate( vmbPixelUv ) * gRectSizePrev, gInvScreenSize,
vmbOcclusionWeights, vmbAllowCatRom,
gIn_Spec_StabilizedHistory, vmbSpecHistory
#ifdef REBLUR_SH
, gIn_SpecSh_StabilizedHistory, vmbSpecShHistory
#endif
);

// Avoid negative values
smbSpecHistory = ClampNegativeToZero( smbSpecHistory );
Expand All @@ -394,11 +393,11 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos :
if( virtualHistoryAmount != 0.0 )
specStabilizationStrength *= float( vmbPixelUv.x >= gSplitScreen );

float specAntilag = ComputeAntilag( specHistory, spec, specSigma, gAntilagParams, data1.z );
float footprintQuality = lerp( smbFootprintQuality, vmbFootprintQuality, virtualHistoryAmount );
float specAntilag = ComputeAntilag( specHistory, spec, specSigma, gAntilagParams, footprintQuality * data1.z );

// Clamp history and combine with the current frame
float isInScreenMulFootprintQuality = lerp( smbIsInScreenMulFootprintQuality, 1.0, virtualHistoryAmount );
float2 specTemporalAccumulationParams = GetTemporalAccumulationParams( isInScreenMulFootprintQuality, data1.z );
float2 specTemporalAccumulationParams = GetTemporalAccumulationParams( footprintQuality, data1.z );

// TODO: roughness should affect stabilization:
// - use "virtualHistoryRoughnessBasedConfidence" from TA
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,6 @@ float loadSurfaceMotionBasedPrevData(
#endif
)
{
// Calculating disocclusion threshold
float pixelSize = PixelRadiusToWorld(gUnproject, gOrthoMode, 1.0, currentLinearZ);
float frustumSize = pixelSize * min(gRectSize.x, gRectSize.y);
float disocclusionThreshold = mixedDisocclusionDepthThreshold * frustumSize / lerp(NdotV, 1.0, saturate(parallaxInPixels / 30.0));

// Calculating previous pixel position
float2 prevPixelPosFloat = prevUVSMB * gRectSizePrev;

Expand Down Expand Up @@ -106,16 +101,23 @@ float loadSurfaceMotionBasedPrevData(
float4 prevMaterialIDs01 = gPrevMaterialID.GatherRed(gNearestClamp, gatherOrigin01).wzxy;
float4 prevMaterialIDs11 = gPrevMaterialID.GatherRed(gNearestClamp, gatherOrigin11).wzxy;

// Calculating disocclusion threshold
float pixelSize = PixelRadiusToWorld(gUnproject, gOrthoMode, 1.0, currentLinearZ);
float frustumSize = pixelSize * min(gRectSize.x, gRectSize.y);
float4 disocclusionThreshold = mixedDisocclusionDepthThreshold * frustumSize / lerp(NdotV, 1.0, saturate(parallaxInPixels / 30.0));
disocclusionThreshold *= IsInScreen2x2( bilinearOrigin, gRectSizePrev );
disocclusionThreshold -= NRD_EPS;

// Calculating validity of 12 bicubic taps, 4 of those are bilinear taps
float3 prevViewPos = STL::Geometry::AffineTransform(gPrevWorldToView, prevWorldPos);
float3 planeDist0 = abs(prevViewZs00.yzw - prevViewPos.zzz);
float3 planeDist1 = abs(prevViewZs10.xzw - prevViewPos.zzz);
float3 planeDist2 = abs(prevViewZs01.xyw - prevViewPos.zzz);
float3 planeDist3 = abs(prevViewZs11.xyz - prevViewPos.zzz);
float3 tapsValid0 = step(planeDist0, disocclusionThreshold);
float3 tapsValid1 = step(planeDist1, disocclusionThreshold);
float3 tapsValid2 = step(planeDist2, disocclusionThreshold);
float3 tapsValid3 = step(planeDist3, disocclusionThreshold);
float3 tapsValid0 = step(planeDist0, disocclusionThreshold.x);
float3 tapsValid1 = step(planeDist1, disocclusionThreshold.y);
float3 tapsValid2 = step(planeDist2, disocclusionThreshold.z);
float3 tapsValid3 = step(planeDist3, disocclusionThreshold.w);
tapsValid0 *= CompareMaterials(currentMaterialID.xxx, prevMaterialIDs00.yzw, materialIDMask);
tapsValid1 *= CompareMaterials(currentMaterialID.xxx, prevMaterialIDs10.xzw, materialIDMask);
tapsValid2 *= CompareMaterials(currentMaterialID.xxx, prevMaterialIDs01.xyw, materialIDMask);
Expand All @@ -138,16 +140,6 @@ float loadSurfaceMotionBasedPrevData(
bicubicFootprintValid = 0;
}

// Checking bicubic footprint validity for being in screen
[flatten]
if (any(bilinearOrigin < int2(1, 1)) || any(bilinearOrigin >= int2(gRectSizePrev)-int2(2, 2)))
{
bicubicFootprintValid = 0;
}

// Checking bilinear footprint validity for being in screen
bilinearTapsValid *= IsInScreen(prevUVSMB);

// Calculating bilinear weights in advance
STL::Filtering::Bilinear bilinear;
bilinear.weights = bilinearWeights;
Expand Down Expand Up @@ -278,7 +270,6 @@ float loadVirtualMotionBasedPrevData(
prevUVVMB = prevVirtualClipPos.xy * float2(0.5, -0.5) + float2(0.5, 0.5);

float2 prevVirtualPixelPosFloat = prevUVVMB * gRectSizePrev;
float disocclusionThreshold = mixedDisocclusionDepthThreshold * (gOrthoMode == 0 ? currentLinearZ : 1.0);

// Consider reprojection to the same pixel index a small motion.
// It is useful for skipping reprojection test for static camera when the jitter is the only source of motion.
Expand All @@ -294,27 +285,29 @@ float loadVirtualMotionBasedPrevData(
// Taking care of camera motion, because world-space is always centered at camera position in NRD
currentWorldPos -= gPrevCameraPosition.xyz;

// Calculating disocclusion threshold
float4 disocclusionThreshold = mixedDisocclusionDepthThreshold * (gOrthoMode == 0 ? currentLinearZ : 1.0);
disocclusionThreshold *= IsInScreen2x2( bilinearOrigin, gRectSizePrev );
disocclusionThreshold -= NRD_EPS;

// Checking bilinear footprint only for virtual motion based specular reprojection
float4 prevViewZs = gPrevViewZ.GatherRed(gNearestClamp, gatherOrigin).wzxy;
float4 prevMaterialIDs = gPrevMaterialID.GatherRed(gNearestClamp, gatherOrigin).wzxy;
float3 prevWorldPosInTap;
float4 bilinearTapsValid;

prevWorldPosInTap = GetPreviousWorldPosFromPixelPos(bilinearOrigin + int2(0, 0), prevViewZs.x);
bilinearTapsValid.x = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold);
bilinearTapsValid.x = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold.x);
prevWorldPosInTap = GetPreviousWorldPosFromPixelPos(bilinearOrigin + int2(1, 0), prevViewZs.y);
bilinearTapsValid.y = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold);
bilinearTapsValid.y = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold.y);
prevWorldPosInTap = GetPreviousWorldPosFromPixelPos(bilinearOrigin + int2(0, 1), prevViewZs.z);
bilinearTapsValid.z = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold);
bilinearTapsValid.z = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold.z);
prevWorldPosInTap = GetPreviousWorldPosFromPixelPos(bilinearOrigin + int2(1, 1), prevViewZs.w);
bilinearTapsValid.w = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold);
bilinearTapsValid.w = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold.w);

bilinearTapsValid *= CompareMaterials(currentMaterialID.xxxx, prevMaterialIDs.xyzw, materialIDMask);
bilinearTapsValid = skipReprojectionTest ? float4(1.0, 1.0, 1.0, 1.0) : bilinearTapsValid;

// Checking bilinear footprint validity for being in screen
bilinearTapsValid *= IsInScreen(prevUVVMB);

// Applying reprojection
prevSpecularIllumAnd2ndMoment = 0;
prevSpecularResponsiveIllum = 0;
Expand Down Expand Up @@ -684,9 +677,9 @@ NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPo

// ( Optional ) High parallax - flattens surface on high motion ( test 132, e9 )
// IMPORTANT: a must for 8-bit and 10-bit normals ( tests b7, b10, b33 )
deltaUvLen *= NRD_USE_HIGH_PARALLAX_CURVATURE_SILHOUETTE_FIX ? NoV : 1.0;
float2 motionUvHigh = pixelUv + deltaUvLen * deltaUv * gInvRectSize;
if (NRD_USE_HIGH_PARALLAX_CURVATURE && deltaUvLen > 1.0 && IsInScreen(motionUvHigh))
float deltaUvLenFixed = deltaUvLen * ( NRD_USE_HIGH_PARALLAX_CURVATURE_SILHOUETTE_FIX ? NoV : 1.0 ); // it fixes silhouettes, but leads to less flattening
float2 motionUvHigh = pixelUv + deltaUvLenFixed * deltaUv * gInvRectSize;
if (NRD_USE_HIGH_PARALLAX_CURVATURE && deltaUvLenFixed > 1.0 && IsInScreen(motionUvHigh))
{
float zHigh = abs(gViewZ.SampleLevel(gLinearClamp, gRectOffset + motionUvHigh * gResolutionScale, 0));
float3 xHigh = GetCurrentWorldPosFromClipSpaceXY(motionUvHigh * 2.0 - 1.0, zHigh);
Expand Down Expand Up @@ -728,8 +721,7 @@ NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPo
float2 uv1 = STL::Geometry::GetScreenUv(gPrevWorldToClip, currentWorldPos - V * ApplyThinLensEquation(NoV, hitDist, curvature));
float2 uv2 = STL::Geometry::GetScreenUv(gPrevWorldToClip, currentWorldPos);
float a = length((uv1 - uv2) * gRectSize);
float b = length(deltaUv * gRectSize);
curvature *= float(a < 3.0 * b + gInvRectSize.x); // TODO:it's a hack, incompatible with concave mirrors ( tests 22b, 23b, 25b )
curvature *= float(a < 3.0 * deltaUvLen + gInvRectSize.x); // TODO:it's a hack, incompatible with concave mirrors ( tests 22b, 23b, 25b )

// Thin lens equation for adjusting reflection HitT
float hitDistFocused = ApplyThinLensEquation(NoV, hitDist, curvature);
Expand Down Expand Up @@ -861,10 +853,8 @@ NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPo
virtualHistoryHitDistConfidence *= STL::Math::SmoothStep(lobeRadiusInPixels + 0.25, 0.0, deltaParallaxInPixels);

// Current specular signal ( surface motion )
float smcFactor = lerp(0.25, 0.001, SMC); // TODO: tune better?
smcFactor *= lerp(1.0, lerp(1.0, 0.25, SMC), NoV);
float specSMBConfidence = (SMBReprojectionFound > 0 ? 1.0 : 0.0) / (1.0 + smcFactor * parallaxInPixels);
specSMBConfidence *= GetNormalWeight(V, Vprev, lobeHalfAngle * NoV / gFramerateScale);
float specSMBConfidence = (SMBReprojectionFound > 0 ? 1.0 : 0.0) *
GetNormalWeight(V, Vprev, lobeHalfAngle * NoV / gFramerateScale);

float specSMBAlpha = 1.0 - specSMBConfidence;
float specSMBResponsiveAlpha = 1.0 - specSMBConfidence;
Expand Down

0 comments on commit 2d94c1f

Please sign in to comment.