diff --git a/Include/NRD.h b/Include/NRD.h index 39000179..02d03adc 100644 --- a/Include/NRD.h +++ b/Include/NRD.h @@ -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 diff --git a/README.md b/README.md index fd7c9492..2d3cd7df 100644 --- a/README.md +++ b/README.md @@ -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) @@ -226,16 +226,16 @@ 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 | @@ -243,16 +243,16 @@ The *Persistent* column (matches *NRD Permanent pool*) indicates how much of the | | 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 | @@ -260,16 +260,16 @@ The *Persistent* column (matches *NRD Permanent pool*) indicates how much of the | | 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 | diff --git a/Resources/Version.h b/Resources/Version.h index 1c99c81b..4a7e90e0 100644 --- a/Resources/Version.h +++ b/Resources/Version.h @@ -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) diff --git a/Shaders/Include/Common.hlsli b/Shaders/Include/Common.hlsli index 5088f6ec..f54ac89e 100644 --- a/Shaders/Include/Common.hlsli +++ b/Shaders/Include/Common.hlsli @@ -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 //================================================================================================================== @@ -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 ) @@ -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 ); @@ -252,6 +236,8 @@ 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 @@ -259,7 +245,7 @@ float ApplyThinLensEquation( float NoV, float hitDist, float 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: @@ -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 diff --git a/Shaders/Include/REBLUR/REBLUR_Common.hlsli b/Shaders/Include/REBLUR/REBLUR_Common.hlsli index 8656f248..674a8733 100644 --- a/Shaders/Include/REBLUR/REBLUR_Common.hlsli +++ b/Shaders/Include/REBLUR/REBLUR_Common.hlsli @@ -19,12 +19,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. // IMPORTANT: if REBLUR_NORMAL_ULP == 1, then "GetEncodingAwareNormalWeight" for 0-roughness // can return values < 1 even for same normals due to data re-packing #define REBLUR_ROUGHNESS_ULP ( 1.5 / 255.0 ) -#define REBLUR_NORMAL_ULP atan( 1.5 / 255.0 ) +#define REBLUR_NORMAL_ULP ( 2.0 / 255.0 ) #define REBLUR_MAX_ACCUM_FRAME_NUM 63.0 #define REBLUR_ACCUMSPEED_BITS 7 // "( 1 << REBLUR_ACCUMSPEED_BITS ) - 1" must be >= REBLUR_MAX_ACCUM_FRAME_NUM #define REBLUR_MATERIALID_BITS ( 16 - REBLUR_ACCUMSPEED_BITS - REBLUR_ACCUMSPEED_BITS ) -#define REBLUR_CURVATURE_PACKING_SCALE 0.1 // Internal data ( from the previous frame ) @@ -49,7 +48,7 @@ float4 UnpackNormalAndRoughness( float4 p, bool isNormalized = true ) uint PackInternalData( float diffAccumSpeed, float specAccumSpeed, float materialID ) { float3 t = float3( diffAccumSpeed, specAccumSpeed, materialID ); - t.xy = min( t.xy, gMaxAccumulatedFrameNum ) / REBLUR_MAX_ACCUM_FRAME_NUM; + t.xy /= REBLUR_MAX_ACCUM_FRAME_NUM; uint p = STL::Packing::RgbaToUint( t.xyzz, REBLUR_ACCUMSPEED_BITS, REBLUR_ACCUMSPEED_BITS, REBLUR_MATERIALID_BITS, 0 ); @@ -94,60 +93,46 @@ float4 UnpackData1( float4 p ) return p; } -float4 PackData2( float fbits, float curvature, float virtualHistoryAmount, float viewZ ) +uint PackData2( float fbits, float curvature, float virtualHistoryAmount ) { // BITS: - // 0 - free // TODO: can be used to store "skip HistoryFix" bit - // 1 - CatRom flag - // 2,3,4,5 - occlusion 2x2 - // 6 - free // TODO: free! - // 7 - curvature sign + // 0 - CatRom flag + // 1-4 - occlusion 2x2 + // other - free // TODO: use if needed - float pixelSize = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); - float packedCurvature = curvature * pixelSize * REBLUR_CURVATURE_PACKING_SCALE; // to fit into 8-bits + uint p = uint( fbits + 0.5 ); - fbits += 128.0 * ( packedCurvature < 0.0 ? 1 : 0 ); + p |= uint( saturate( virtualHistoryAmount ) * 255.0 + 0.5 ) << 8; + p |= f32tof16( curvature ) << 16; - float4 r; - r.x = saturate( ( fbits + 0.5 ) / 255.0 ); - r.y = abs( packedCurvature ); - r.z = virtualHistoryAmount; - r.w = 0.0; // TODO: unused - - // Optional - r.yzw = STL::Math::Sqrt01( r.yzw ); - - return r; + return p; } -float3 UnpackData2( float4 p, float viewZ, out uint bits ) +float2 UnpackData2( uint p, float viewZ, out uint bits ) { - // Optional - p.yzw *= p.yzw; - - bits = uint( p.x * 255.0 + 0.5 ); + bits = p & 0xFF; - float pixelSize = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); - float sgn = ( bits & 128 ) != 0 ? -1.0 : 1.0; - float curvature = p.y * sgn / ( pixelSize * REBLUR_CURVATURE_PACKING_SCALE ); + float virtualHistoryAmount = float( ( p >> 8 ) & 0xFF ) / 255.0; + float curvature = f16tof32( p >> 16 ); - return float3( p.zw, curvature ); + return float2( virtualHistoryAmount, curvature ); } // Accumulation speed -float GetFPS( float period = 1.0 ) +float GetFPS( float period = 1.0 ) // TODO: can be handy, but not used { - // TODO: can be handy, but not used return gFramerateScale * 30.0 * period; } -float GetSmbAccumSpeed( float smbSpecAccumSpeedFactor, float vmbPixelsTraveled, float viewZ, float specAccumSpeed, float maxAngle ) +float GetSmbAccumSpeed( float smbSpecAccumSpeedFactor, float diffParallaxInPixels, float viewZ, float specAccumSpeed, float maxAngle ) { - float smbSpecAccumSpeed = gMaxAccumulatedFrameNum / ( 1.0 + smbSpecAccumSpeedFactor * vmbPixelsTraveled ); + // "diffParallaxInPixels" is the difference between true specular motion (vmb) and surface based motion (smb), + // but "vmb" parallax can only be used if virtual motion confidence is high + float smbSpecAccumSpeed = gMaxAccumulatedFrameNum / ( 1.0 + smbSpecAccumSpeedFactor * diffParallaxInPixels ); // Tests 142, 148 and 155 ( or anything with very low roughness and curved surfaces ) - float ta = PixelRadiusToWorld( gUnproject, gOrthoMode, vmbPixelsTraveled, viewZ ) / viewZ; + float ta = PixelRadiusToWorld( gUnproject, gOrthoMode, diffParallaxInPixels, viewZ ) / viewZ; float ca = STL::Math::Rsqrt( 1.0 + ta * ta ); float angle = STL::Math::AcosApprox( ca ); smbSpecAccumSpeed *= STL::Math::SmoothStep( maxAngle, 0.0, angle ); @@ -351,7 +336,7 @@ float ComputeAntilagScale( ) { // On-edge strictness - m1 = lerp( m1, signal, abs( curvatureMulPixelSize ) ); + m1 = lerp( m1, signal, saturate( abs( curvatureMulPixelSize ) ) ); // Antilag float2 h = float2( GetLuma( history ), ExtractHitDist( history ) ); diff --git a/Shaders/Include/REBLUR/REBLUR_Common_SpecularSpatialFilter.hlsli b/Shaders/Include/REBLUR/REBLUR_Common_SpecularSpatialFilter.hlsli index 34931d91..1769edd9 100644 --- a/Shaders/Include/REBLUR/REBLUR_Common_SpecularSpatialFilter.hlsli +++ b/Shaders/Include/REBLUR/REBLUR_Common_SpecularSpatialFilter.hlsli @@ -212,7 +212,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #if( REBLUR_SPATIAL_MODE == REBLUR_PRE_BLUR ) // Output - gOut_Spec_MinHitDist[ pixelPos ] = minHitDist * hitDistScale; // TODO: lerp to ExtractHitDist( spec ) based on NoV or NoD? + gOut_Spec_HitDistForTracking[ pixelPos ] = minHitDist; // TODO: lerp to ExtractHitDist( spec ) based on NoV or NoD? } // Checkerboard resolve ( if pre-pass failed ) diff --git a/Shaders/Include/REBLUR/REBLUR_Config.hlsli b/Shaders/Include/REBLUR/REBLUR_Config.hlsli index 6f4164d0..8e51844d 100644 --- a/Shaders/Include/REBLUR/REBLUR_Config.hlsli +++ b/Shaders/Include/REBLUR/REBLUR_Config.hlsli @@ -137,7 +137,7 @@ static const float3 g_Special8[ 8 ] = NRD_CONSTANT( uint, gFrameIndex ) \ NRD_CONSTANT( uint, gDiffMaterialMask ) \ NRD_CONSTANT( uint, gSpecMaterialMask ) \ - NRD_CONSTANT( uint, gResetHistory ) + NRD_CONSTANT( uint, gResetHistory ) // IMPORTANT: used only in validation // 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 diff --git a/Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli b/Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli index df0aa3d3..84cfbe4f 100644 --- a/Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli +++ b/Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli @@ -28,7 +28,7 @@ void Preload( uint2 sharedPos, int2 globalPos ) REBLUR_TYPE spec = gIn_Spec[ pos ]; float hitDistForTracking = ExtractHitDist( spec ); #ifndef REBLUR_OCCLUSION - hitDistForTracking = gSpecPrepassBlurRadius != 0.0 ? gOut_SpecFast[ globalPos ].x : hitDistForTracking; + hitDistForTracking = gSpecPrepassBlurRadius != 0.0 ? gIn_Spec_HitDistForTracking[ globalPos ] : hitDistForTracking; #endif temp.w = hitDistForTracking; #endif @@ -112,8 +112,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : } // Parallax - float smbParallax = ComputeParallax( Xprev - gCameraDelta, gOrthoMode == 0.0 ? pixelUv : smbPixelUv, gWorldToClip, gRectSize, gUnproject, gOrthoMode ); - float smbParallaxInPixels = GetParallaxInPixels( smbParallax, gUnproject ); + float smbParallaxInPixels = ComputeParallaxInPixels( Xprev - gCameraDelta, gOrthoMode == 0.0 ? pixelUv : smbPixelUv, gWorldToClip, gRectSize ); // Curvature estimation along predicted motion ( tests 15, 40, 76, 133, 146, 147, 148 ) float curvature = 0; @@ -124,8 +123,8 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : cameraMotion2d /= max( length( cameraMotion2d ), 1.0 / ( 1.0 + gMaxAccumulatedFrameNum ) ); cameraMotion2d *= gInvRectSize; - // Low parallax - bilinear ( SMEM ) - float2 uv = pixelUv + cameraMotion2d * 0.5; + // Low parallax + float2 uv = pixelUv + cameraMotion2d * 0.99; STL::Filtering::Bilinear f = STL::Filtering::GetBilinearFilter( uv, gRectSize ); int2 pos = threadPos + BORDER + int2( f.origin ) - pixelPos; @@ -139,11 +138,27 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float3 n = STL::Filtering::ApplyBilinearFilter( n00, n10, n01, n11, f ); n = normalize( n ); - // High parallax - nearest ( fetch ) - float2 uvHigh = gRectOffset + pixelUv + cameraMotion2d * smbParallaxInPixels; - float3 nHigh = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness.SampleLevel( gNearestClamp, uvHigh * gResolutionScale, 0 ) ).xyz; - float zHigh = abs( gIn_ViewZ.SampleLevel( gNearestClamp, uvHigh * gResolutionScale, 0 ) ); + // High parallax + float2 uvHigh = pixelUv + cameraMotion2d * smbParallaxInPixels; + #if( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_R10G10B10A2_UNORM ) + f = STL::Filtering::GetBilinearFilter( uvHigh, gRectSize ); + + pos = gRectOrigin + int2( f.origin ); + pos = clamp( pos, 0, int2( gRectSize ) - 2 ); + + n00 = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pos ] ).xyz; + n10 = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pos + int2( 1, 0 ) ] ).xyz; + n01 = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pos + int2( 0, 1 ) ] ).xyz; + n11 = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pos + int2( 1, 1 ) ] ).xyz; + + float3 nHigh = STL::Filtering::ApplyBilinearFilter( n00, n10, n01, n11, f ); + nHigh = normalize( nHigh ); + #else + float3 nHigh = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness.SampleLevel( gLinearClamp, gRectOffset + uvHigh * gResolutionScale, 0 ) ).xyz; + #endif + + float zHigh = abs( gIn_ViewZ.SampleLevel( gLinearClamp, gRectOffset + uvHigh * gResolutionScale, 0 ) ); float zError = abs( zHigh - viewZ ) * rcp( max( zHigh, viewZ ) ); bool cmp = smbParallaxInPixels > 1.0 && zError < 0.1 && IsInScreen( uvHigh ); @@ -159,7 +174,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float d = STL::Math::ManhattanDistance( N, n ); float s = STL::Math::LinearStep( NRD_NORMAL_ENCODING_ERROR, 2.0 * NRD_NORMAL_ENCODING_ERROR, d ); - curvature = EstimateCurvature( n, v, N, X ) * s; + curvature = EstimateCurvature( normalize( Navg ), n, v, N, X ) * s; } #endif @@ -269,8 +284,11 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : smbFootprintQualityWithMaterialID *= sizeQuality; // Bits - float fbits = smbAllowCatRom * 2.0; - fbits += smbOcclusion0.z * 4.0 + smbOcclusion1.y * 8.0 + smbOcclusion2.y * 16.0 + smbOcclusion3.x * 32.0; + float fbits = smbAllowCatRom * 1.0; + fbits += smbOcclusion0.z * 2.0; + fbits += smbOcclusion1.y * 4.0; + fbits += smbOcclusion2.y * 8.0; + fbits += smbOcclusion3.x * 16.0; // Update accumulation speeds #ifdef REBLUR_DIFFUSE @@ -283,6 +301,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float diffAccumSpeed = STL::Filtering::ApplyBilinearCustomWeights( diffAccumSpeeds.x, diffAccumSpeeds.y, diffAccumSpeeds.z, diffAccumSpeeds.w, diffOcclusionWeights ); diffAccumSpeed *= lerp( diffHistoryConfidence, 1.0, 1.0 / ( 1.0 + diffAccumSpeed ) ); + diffAccumSpeed = min( diffAccumSpeed, gMaxAccumulatedFrameNum ); #endif #ifdef REBLUR_SPECULAR @@ -295,6 +314,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float specAccumSpeed = STL::Filtering::ApplyBilinearCustomWeights( specAccumSpeeds.x, specAccumSpeeds.y, specAccumSpeeds.z, specAccumSpeeds.w, specOcclusionWeights ); specAccumSpeed *= lerp( specHistoryConfidence, 1.0, 1.0 / ( 1.0 + specAccumSpeed ) ); + specAccumSpeed = min( specAccumSpeed, gMaxAccumulatedFrameNum ); #endif uint checkerboard = STL::Sequence::CheckerBoard( pixelPos, gFrameIndex ); @@ -436,7 +456,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Hit distance for tracking ( tests 8, 110, 139 ) float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gHitDistParams, roughness ); - hitDistForTracking *= gSpecPrepassBlurRadius != 0.0 ? 1.0 : hitDistScale; // TODO: clamp to +/- 3 sigma? + hitDistForTracking *= hitDistScale; // TODO: clamp to +/- 3 sigma? // Virtual motion float4 D = STL::ImportanceSampling::GetSpecularDominantDirection( N, V, roughness, STL_SPECULAR_DOMINANT_DIRECTION_G2 ); @@ -447,24 +467,22 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 vmbDelta = vmbPixelUv - smbPixelUv; float vmbPixelsTraveled = length( vmbDelta * gRectSize ); - // Adjust curvature if curvature sign oscillation is forseen // TODO: is there a better way? fix curvature? - float curvatureCorrectionThreshold = smbParallaxInPixels + gInvRectSize.x; - float curvatureCorrection = STL::Math::SmoothStep( 1.05 * curvatureCorrectionThreshold, 0.95 * curvatureCorrectionThreshold, vmbPixelsTraveled ); + // Adjust curvature if curvature sign oscillation is forseen // TODO:it's a hack, incompatible with concave mirrors + float curvatureCorrection = float( vmbPixelsTraveled < 3.0 * smbParallaxInPixels + gInvRectSize.x ); curvature *= curvatureCorrection; Xvirtual = GetXvirtual( NoV, hitDistForTracking, curvature, X, Xprev, V, D.w ); vmbPixelUv = STL::Geometry::GetScreenUv( gWorldToClipPrev, Xvirtual ); - float XvirtualLength = length( Xvirtual ); - // Update after curvature correction vmbDelta = vmbPixelUv - smbPixelUv; vmbPixelsTraveled = length( vmbDelta * gRectSize ); + float XvirtualLength = length( Xvirtual ); + // Virtual history amount - base float virtualHistoryAmount = IsInScreen( vmbPixelUv ); virtualHistoryAmount *= D.w; - virtualHistoryAmount *= gNonReferenceAccumulation; // Virtual motion amount - surface STL::Filtering::Bilinear vmbBilinearFilter = STL::Filtering::GetBilinearFilter( saturate( vmbPixelUv ), gRectSizePrev ); @@ -619,11 +637,15 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : smbSpecAccumSpeedFactor *= gFramerateScale; smbSpecAccumSpeedFactor *= lerp( 0.5 + 0.5 * virtualHistoryRoughnessBasedConfidence, 1.0, virtualHistoryAmount ); - float smbSpecAccumSpeed = GetSmbAccumSpeed( smbSpecAccumSpeedFactor, vmbPixelsTraveled, viewZ, specAccumSpeed, angle ); + float diffParallaxInPixels = lerp( smbParallaxInPixels, vmbPixelsTraveled, virtualHistoryAmount ); + float smbSpecAccumSpeed = GetSmbAccumSpeed( smbSpecAccumSpeedFactor, diffParallaxInPixels, viewZ, specAccumSpeed, angle ); // Fallback to surface motion if virtual motion doesn't go well ( tests 103, 111, 132, e9, e11 ) virtualHistoryAmount *= saturate( vmbSpecAccumSpeed / ( smbSpecAccumSpeed + NRD_EPS ) ); + // Disable virtual motion in reference accumulation mode + virtualHistoryAmount *= gNonReferenceAccumulation; // TODO: remove reference accumulation mode from settings? + // Accumulation with checkerboard resolve // TODO: materialID support? specAccumSpeed = lerp( smbSpecAccumSpeed, vmbSpecAccumSpeed, virtualHistoryAmount ); @@ -696,6 +718,6 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : gOut_Data1[ pixelPos ] = PackData1( diffAccumSpeed, diffError, specAccumSpeed, specError ); #ifndef REBLUR_OCCLUSION - gOut_Data2[ pixelPos ] = PackData2( fbits, curvature, virtualHistoryAmount, viewZ ); + gOut_Data2[ pixelPos ] = PackData2( fbits, curvature, virtualHistoryAmount ); #endif } diff --git a/Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli b/Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli index fb26fd6b..eb1fca40 100644 --- a/Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli +++ b/Shaders/Include/REBLUR/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli @@ -218,11 +218,9 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Shared data uint bits; float4 data1 = UnpackData1( gIn_Data1[ pixelPos ] ); - float3 data2 = UnpackData2( gIn_Data2[ pixelPos ], viewZ, bits ); + float2 data2 = UnpackData2( gIn_Data2[ pixelPos ], viewZ, bits ); - float virtualHistoryAmount = data2.x; - float curvature = data2.z; - float4 smbOcclusion = float4( ( bits & uint4( 4, 8, 16, 32 ) ) != 0 ); + 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 ); @@ -231,7 +229,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Only for "...WithMaterialID" even if material ID test is disabled float4 smbOcclusionWeights = STL::Filtering::GetBilinearCustomWeights( smbBilinearFilter, smbOcclusion ); - bool smbIsCatromAllowed = ( bits & 2 ) != 0 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS; + bool smbIsCatromAllowed = ( bits & 1 ) != 0 && 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 ); @@ -262,7 +260,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float diffAntilag = ComputeAntilagScale( smbDiffHistory, diff, diffM1, diffSigma, gAntilagMinMaxThreshold, gAntilagSigmaScale, diffStabilizationStrength, - curvature * pixelSize, data1.x + 0.0, data1.x ); // Clamp history and combine with the current frame @@ -298,6 +296,9 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Specular #ifdef REBLUR_SPECULAR + float virtualHistoryAmount = data2.x; + float curvature = data2.y; + // Hit distance for tracking ( tests 6, 67, 155 ) float hitDistForTracking = min( spec.w, specMin.y ); @@ -354,9 +355,10 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float lumSpec = STL::Color::Luminance( Fenv ); float lumDiff = STL::Color::Luminance( albedo * ( 1.0 - Fenv ) ); - float specProb = lumSpec / ( lumDiff + lumSpec + NRD_EPS ); + float f = STL::Math::SmoothStep( gSpecularProbabilityThresholdsForMvModification.x, gSpecularProbabilityThresholdsForMvModification.y, specProb ); + f *= virtualHistoryAmount; if( f != 0.0 ) { diff --git a/Shaders/Include/RELAX/RELAX_DiffuseSpecular_TemporalAccumulation.hlsli b/Shaders/Include/RELAX/RELAX_DiffuseSpecular_TemporalAccumulation.hlsli index 6fe7fd84..ad723bed 100644 --- a/Shaders/Include/RELAX/RELAX_DiffuseSpecular_TemporalAccumulation.hlsli +++ b/Shaders/Include/RELAX/RELAX_DiffuseSpecular_TemporalAccumulation.hlsli @@ -235,7 +235,7 @@ float loadVirtualMotionBasedPrevData( float currentMaterialID, uint materialIDMask, float2 prevSurfaceMotionBasedUV, - float parallax, + float parallaxInPixels, float NdotV, float mixedDisocclusionDepthThreshold, out float4 prevSpecularIllumAnd2ndMoment, @@ -260,7 +260,7 @@ float loadVirtualMotionBasedPrevData( // too far from surface motion based UV, // then recalculate UV using the non-focused HitT [flatten] - if (length(prevUVVMB - prevSurfaceMotionBasedUV) > (parallax / NRD_PARALLAX_NORMALIZATION) + 0.001) + if (length((prevUVVMB - prevSurfaceMotionBasedUV) * gRectSize) > parallaxInPixels + 0.001) { virtualViewVector = normalize(currentViewVector) * hitDistOriginal; prevVirtualWorldPos = prevWorldPos + virtualViewVector; @@ -492,8 +492,7 @@ NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPo #endif // Calculating surface parallax - float parallax = ComputeParallax(prevWorldPos - gPrevCameraPosition.xyz, gOrthoMode == 0.0 ? pixelUv : prevUVSMB, gWorldToClip, gRectSize, gUnproject, gOrthoMode); - float parallaxInPixels = GetParallaxInPixels(parallax, gUnproject); + float parallaxInPixels = ComputeParallaxInPixels(prevWorldPos - gPrevCameraPosition.xyz, gOrthoMode == 0.0 ? pixelUv : prevUVSMB, gWorldToClip, gRectSize); // Calculating curvature along the direction of motion #ifdef RELAX_SPECULAR @@ -530,7 +529,7 @@ NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPo float d = STL::Math::ManhattanDistance(pNormal, currentNormal); float s = STL::Math::LinearStep(NRD_NORMAL_ENCODING_ERROR, 2.0 * NRD_NORMAL_ENCODING_ERROR, d); - curvature += EstimateCurvature(pNormal, v, currentNormal, currentWorldPos) * s; + curvature += EstimateCurvature(normalize(currentNormalAveraged), pNormal, v, currentNormal, currentWorldPos) * s; } curvature *= 0.5; #endif @@ -696,7 +695,7 @@ NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPo currentMaterialID, gSpecMaterialMask, prevUVSMB, - parallax, + parallaxInPixels, NoV, mixedDisocclusionDepthThreshold, prevSpecularIlluminationAnd2ndMomentVMB, @@ -841,7 +840,7 @@ NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPo float accumulatedSpecularM2VMB = lerp(prevSpecularIlluminationAnd2ndMomentVMB.a, specular2ndMoment, specVMBAlpha); float3 accumulatedSpecularVMBResponsive = lerp(prevSpecularIlluminationAnd2ndMomentVMBResponsive.rgb, specularIllumination.xyz, specVMBResponsiveAlpha); - // Fallback to surface motion if virtual motion doesn't go well + // Fallback to surface motion if virtual motion doesn't go well virtualHistoryAmount *= saturate(specVMBConfidence / (specSMBConfidence + NRD_EPS)); // Temporal accumulation of reflection HitT diff --git a/Shaders/Resources/REBLUR_DiffuseSpecular_PrePass.resources.hlsli b/Shaders/Resources/REBLUR_DiffuseSpecular_PrePass.resources.hlsli index b26e56b2..41b352a4 100644 --- a/Shaders/Resources/REBLUR_DiffuseSpecular_PrePass.resources.hlsli +++ b/Shaders/Resources/REBLUR_DiffuseSpecular_PrePass.resources.hlsli @@ -38,7 +38,7 @@ NRD_CONSTANTS_END NRD_OUTPUT_TEXTURE_START NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec_MinHitDist, u, 2 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec_HitDistForTracking, u, 2 ) #ifdef REBLUR_SH NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_DiffSh, u, 3 ) NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_SpecSh, u, 4 ) @@ -76,7 +76,7 @@ NRD_CONSTANTS_END NRD_OUTPUT_TEXTURE_START NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec_MinHitDist, u, 1 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec_HitDistForTracking, u, 1 ) #ifdef REBLUR_SH NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_SpecSh, u, 2 ) #endif diff --git a/Shaders/Resources/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli b/Shaders/Resources/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli index 267f472e..94503097 100644 --- a/Shaders/Resources/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli +++ b/Shaders/Resources/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli @@ -51,11 +51,14 @@ NRD_CONSTANTS_END NRD_INPUT_TEXTURE( Texture2D, gIn_Spec_History, t, 12 ) NRD_INPUT_TEXTURE( Texture2D, gIn_DiffFast_History, t, 13 ) NRD_INPUT_TEXTURE( Texture2D, gIn_SpecFast_History, t, 14 ) + #ifndef REBLUR_OCCLUSION + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec_HitDistForTracking, t, 15 ) + #endif #ifdef REBLUR_SH - NRD_INPUT_TEXTURE( Texture2D, gIn_DiffSh, t, 15 ) - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecSh, t, 16 ) - NRD_INPUT_TEXTURE( Texture2D, gIn_DiffSh_History, t, 17 ) - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecSh_History, t, 18 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_DiffSh, t, 16 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecSh, t, 17 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_DiffSh_History, t, 18 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecSh_History, t, 19 ) #endif NRD_INPUT_TEXTURE_END @@ -66,7 +69,7 @@ NRD_CONSTANTS_END NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_DiffFast, u, 3 ) NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_SpecFast, u, 4 ) #ifndef REBLUR_OCCLUSION - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Data2, u, 5 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Data2, u, 5 ) #endif #ifdef REBLUR_SH NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_DiffSh, u, 6 ) @@ -99,7 +102,7 @@ NRD_CONSTANTS_END NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Data1, u, 1 ) NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_DiffFast, u, 2 ) #ifndef REBLUR_OCCLUSION - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Data2, u, 3 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Data2, u, 3 ) #endif #ifdef REBLUR_SH NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_DiffSh, u, 4 ) @@ -120,9 +123,12 @@ NRD_CONSTANTS_END NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 8 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Spec_History, t, 9 ) NRD_INPUT_TEXTURE( Texture2D, gIn_SpecFast_History, t, 10 ) + #ifndef REBLUR_OCCLUSION + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec_HitDistForTracking, t, 11 ) + #endif #ifdef REBLUR_SH - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecSh, t, 11 ) - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecSh_History, t, 12 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecSh, t, 12 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecSh_History, t, 13 ) #endif NRD_INPUT_TEXTURE_END @@ -131,7 +137,7 @@ NRD_CONSTANTS_END NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Data1, u, 1 ) NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_SpecFast, u, 2 ) #ifndef REBLUR_OCCLUSION - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Data2, u, 3 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Data2, u, 3 ) #endif #ifdef REBLUR_SH NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_SpecSh, u, 4 ) diff --git a/Shaders/Resources/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli b/Shaders/Resources/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli index f13e4200..4fbc7a15 100644 --- a/Shaders/Resources/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli +++ b/Shaders/Resources/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli @@ -36,7 +36,7 @@ NRD_CONSTANTS_END NRD_INPUT_TEXTURE( Texture2D, gIn_BaseColor_Metalness, t, 1 ) NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 2 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Data1, t, 3 ) - NRD_INPUT_TEXTURE( Texture2D, gIn_Data2, t, 4 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_Data2, t, 4 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 5 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 6 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Diff_StabilizedHistory, t, 7 ) @@ -67,7 +67,7 @@ NRD_CONSTANTS_END NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Data1, t, 2 ) - NRD_INPUT_TEXTURE( Texture2D, gIn_Data2, t, 3 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_Data2, t, 3 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 4 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Diff_StabilizedHistory, t, 5 ) #ifdef REBLUR_SH @@ -92,7 +92,7 @@ NRD_CONSTANTS_END NRD_INPUT_TEXTURE( Texture2D, gIn_BaseColor_Metalness, t, 1 ) NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 2 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Data1, t, 3 ) - NRD_INPUT_TEXTURE( Texture2D, gIn_Data2, t, 4 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_Data2, t, 4 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 5 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Spec_StabilizedHistory, t, 6 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Spec_FastHistory, t, 7 ) diff --git a/Shaders/Resources/REBLUR_Validation.resources.hlsli b/Shaders/Resources/REBLUR_Validation.resources.hlsli index d658c0fe..d2ec1433 100644 --- a/Shaders/Resources/REBLUR_Validation.resources.hlsli +++ b/Shaders/Resources/REBLUR_Validation.resources.hlsli @@ -30,7 +30,7 @@ NRD_INPUT_TEXTURE_START NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Mv, t, 2 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Data1, t, 3 ) - NRD_INPUT_TEXTURE( Texture2D, gIn_Data2, t, 4 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_Data2, t, 4 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 5 ) NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 6 ) NRD_INPUT_TEXTURE_END diff --git a/Shaders/Source/REBLUR_Validation.cs.hlsl b/Shaders/Source/REBLUR_Validation.cs.hlsl index 8a0863e1..3207f86f 100644 --- a/Shaders/Source/REBLUR_Validation.cs.hlsl +++ b/Shaders/Source/REBLUR_Validation.cs.hlsl @@ -58,7 +58,7 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 pixelPos : SV_DispatchThreadId ) data1.xz *= REBLUR_MAX_ACCUM_FRAME_NUM; uint bits; - float3 data2 = UnpackData2( gIn_Data2.SampleLevel( gNearestClamp, viewportUvScaled, 0 ), abs( viewZ ), bits ); + float2 data2 = UnpackData2( gIn_Data2[ uint2( viewportUvScaled * gScreenSize ) ], abs( viewZ ), bits ); float3 N = normalAndRoughness.xyz; float roughness = normalAndRoughness.w; diff --git a/Shaders/Source/SpecularReflectionMv_Compute.cs.hlsl b/Shaders/Source/SpecularReflectionMv_Compute.cs.hlsl index 242edf3a..534f8b07 100644 --- a/Shaders/Source/SpecularReflectionMv_Compute.cs.hlsl +++ b/Shaders/Source/SpecularReflectionMv_Compute.cs.hlsl @@ -95,8 +95,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float roughnessModified = STL::Filtering::GetModifiedRoughnessFromNormalVariance( roughness, Navg ); // Parallax - float smbParallax = ComputeParallax( Xprev - gCameraDelta, gOrthoMode == 0.0 ? pixelUv : smbPixelUv, gWorldToClip, gRectSize, gUnproject, gOrthoMode ); - float smbParallaxInPixels = GetParallaxInPixels( smbParallax, gUnproject ); + float smbParallaxInPixels = ComputeParallaxInPixels( Xprev - gCameraDelta, gOrthoMode == 0.0 ? pixelUv : smbPixelUv, gWorldToClip, gRectSize ); // Camera motion in screen-space float2 motionUv = STL::Geometry::GetScreenUv( gWorldToClip, Xprev - gCameraDelta ); @@ -104,8 +103,8 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : cameraMotion2d /= max( length( cameraMotion2d ), 1.0 / 64.0 ); cameraMotion2d *= gInvRectSize; - // Low parallax - bilinear ( SMEM ) - float2 uv = pixelUv + cameraMotion2d * 0.5; + // Low parallax + float2 uv = pixelUv + cameraMotion2d * 0.99; STL::Filtering::Bilinear f = STL::Filtering::GetBilinearFilter( uv, gRectSize ); int2 pos = threadPos + BORDER + int2( f.origin ) - pixelPos; @@ -119,11 +118,27 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float3 n = STL::Filtering::ApplyBilinearFilter( n00, n10, n01, n11, f ); n = normalize( n ); - // High parallax - nearest ( fetch ) - float2 uvHigh = gRectOffset + pixelUv + cameraMotion2d * smbParallaxInPixels; - float3 nHigh = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness.SampleLevel( gNearestClamp, uvHigh * gResolutionScale, 0 ) ).xyz; - float zHigh = abs( gIn_ViewZ.SampleLevel( gNearestClamp, uvHigh * gResolutionScale, 0 ) ); + // High parallax + float2 uvHigh = pixelUv + cameraMotion2d * smbParallaxInPixels; + #if( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_R10G10B10A2_UNORM ) + f = STL::Filtering::GetBilinearFilter( uvHigh, gRectSize ); + + pos = gRectOrigin + int2( f.origin ); + pos = clamp( pos, 0, int2( gRectSize ) - 2 ); + + n00 = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pos ] ).xyz; + n10 = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pos + int2( 1, 0 ) ] ).xyz; + n01 = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pos + int2( 0, 1 ) ] ).xyz; + n11 = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pos + int2( 1, 1 ) ] ).xyz; + + float3 nHigh = STL::Filtering::ApplyBilinearFilter( n00, n10, n01, n11, f ); + nHigh = normalize( nHigh ); + #else + float3 nHigh = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness.SampleLevel( gLinearClamp, gRectOffset + uvHigh * gResolutionScale, 0 ) ).xyz; + #endif + + float zHigh = abs( gIn_ViewZ.SampleLevel( gLinearClamp, gRectOffset + uvHigh * gResolutionScale, 0 ) ); float zError = abs( zHigh - viewZ ) * rcp( max( zHigh, viewZ ) ); bool cmp = smbParallaxInPixels > 1.0 && zError < 0.1 && IsInScreen( uvHigh ); @@ -139,7 +154,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float d = STL::Math::ManhattanDistance( N, n ); float s = STL::Math::LinearStep( NRD_NORMAL_ENCODING_ERROR, 2.0 * NRD_NORMAL_ENCODING_ERROR, d ); - float curvature = EstimateCurvature( n, v, N, X ) * s; + float curvature = EstimateCurvature( normalize( Navg ), n, v, N, X ) * s; // Virtual motion float3 V = GetViewVector( X ); diff --git a/Source/DenoiserImpl.cpp b/Source/DenoiserImpl.cpp index af42af2d..9a1ec6e6 100644 --- a/Source/DenoiserImpl.cpp +++ b/Source/DenoiserImpl.cpp @@ -921,7 +921,7 @@ nrd::Result nrd::DenoiserImpl::Create(const DenoiserCreationDesc& denoiserCreati if (!isFound) { // Texture props - uint32_t w = methodDesc.fullResolutionHeight; + uint32_t w = methodDesc.fullResolutionWidth; uint32_t h = methodDesc.fullResolutionHeight; bool isInteger = false; @@ -1254,9 +1254,6 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const CommonSettings& commonSetting memcpy(&m_CommonSettings, &commonSettings, sizeof(commonSettings)); - if (m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE) - m_CommonSettings.frameIndex = 0; - // Rotators ml::float4 rndScale = ml::float4(1.0f) + ml::Rand::sf4(&m_FastRandState) * 0.25f; ml::float4 rndAngle = ml::Rand::uf4(&m_FastRandState) * ml::DegToRad(360.0f); diff --git a/Source/Methods/Reblur_Diffuse.hpp b/Source/Methods/Reblur_Diffuse.hpp index 9dd3c839..1d615a1b 100644 --- a/Source/Methods/Reblur_Diffuse.hpp +++ b/Source/Methods/Reblur_Diffuse.hpp @@ -62,6 +62,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_FORMAT_DIFF_FAST_HISTORY Format::R16_SFLOAT #define REBLUR_FORMAT_SPEC_FAST_HISTORY Format::RG16_SFLOAT // .y = hit distance for tracking +#define REBLUR_FORMAT_SPEC_HITDIST_FOR_TRACKING Format::R16_UNORM // use R16_SFLOAT if pre-pass outputs unnormalized hit distance + #define REBLUR_FORMAT_OCCLUSION Format::R16_UNORM #define REBLUR_FORMAT_DIRECTIONAL_OCCLUSION Format::RGBA16_SNORM @@ -146,7 +148,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuse(MethodData& methodData) }; m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); + m_TransientPool.push_back( {Format::R8_UINT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); diff --git a/Source/Methods/Reblur_DiffuseDirectionalOcclusion.hpp b/Source/Methods/Reblur_DiffuseDirectionalOcclusion.hpp index fe365f2f..8f85e4a1 100644 --- a/Source/Methods/Reblur_DiffuseDirectionalOcclusion.hpp +++ b/Source/Methods/Reblur_DiffuseDirectionalOcclusion.hpp @@ -16,7 +16,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(MethodData& methodData.settings.reblur = ReblurSettings(); methodData.settingsSize = sizeof(methodData.settings.reblur); - + uint16_t w = methodData.desc.fullResolutionWidth; uint16_t h = methodData.desc.fullResolutionHeight; @@ -48,7 +48,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(MethodData& }; m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); + m_TransientPool.push_back( {Format::R8_UINT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT_DIRECTIONAL_OCCLUSION, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT_DIRECTIONAL_OCCLUSION, w, h, 1} ); @@ -124,7 +124,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(MethodData& PushInput( isAfterPrepass ? DIFF_TEMP1 : AsUint(ResourceType::IN_DIFF_DIRECTION_HITDIST) ); PushInput( isTemporalStabilization ? AsUint(Permanent::DIFF_HISTORY) : AsUint(ResourceType::OUT_DIFF_DIRECTION_HITDIST) ); PushInput( AsUint(Permanent::DIFF_FAST_HISTORY_PING), 0, 1, AsUint(Permanent::DIFF_FAST_HISTORY_PONG) ); - + // Outputs PushOutput( DIFF_TEMP2 ); PushOutput( AsUint(Transient::DATA1) ); diff --git a/Source/Methods/Reblur_DiffuseSh.hpp b/Source/Methods/Reblur_DiffuseSh.hpp index 6c4563c2..d23d6b7e 100644 --- a/Source/Methods/Reblur_DiffuseSh.hpp +++ b/Source/Methods/Reblur_DiffuseSh.hpp @@ -52,7 +52,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSh(MethodData& methodData) }; m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); + m_TransientPool.push_back( {Format::R8_UINT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); diff --git a/Source/Methods/Reblur_DiffuseSpecular.hpp b/Source/Methods/Reblur_DiffuseSpecular.hpp index 2e8aa6fa..17a038b1 100644 --- a/Source/Methods/Reblur_DiffuseSpecular.hpp +++ b/Source/Methods/Reblur_DiffuseSpecular.hpp @@ -49,6 +49,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(MethodData& methodData) { DATA1 = TRANSIENT_POOL_START, DATA2, + SPEC_HITDIST_FOR_TRACKING, DIFF_TMP1, DIFF_TMP2, SPEC_TMP1, @@ -56,7 +57,8 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(MethodData& methodData) }; m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); + m_TransientPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_TransientPool.push_back( {REBLUR_FORMAT_SPEC_HITDIST_FOR_TRACKING, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); @@ -110,7 +112,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(MethodData& methodData) // Outputs PushOutput( DIFF_TEMP1 ); PushOutput( SPEC_TEMP1 ); - PushOutput( AsUint(Permanent::SPEC_FAST_HISTORY_PONG), 0, 1, AsUint(Permanent::SPEC_FAST_HISTORY_PING) ); + PushOutput( AsUint(Transient::SPEC_HITDIST_FOR_TRACKING) ); // Shaders AddDispatch( REBLUR_DiffuseSpecular_PrePass, REBLUR_PREPASS_CONSTANT_NUM, REBLUR_PREPASS_NUM_THREADS, 1 ); @@ -143,6 +145,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(MethodData& methodData) PushInput( isTemporalStabilization ? AsUint(Permanent::SPEC_HISTORY) : AsUint(ResourceType::OUT_SPEC_RADIANCE_HITDIST) ); PushInput( AsUint(Permanent::DIFF_FAST_HISTORY_PING), 0, 1, AsUint(Permanent::DIFF_FAST_HISTORY_PONG) ); PushInput( AsUint(Permanent::SPEC_FAST_HISTORY_PING), 0, 1, AsUint(Permanent::SPEC_FAST_HISTORY_PONG) ); + PushInput( AsUint(Transient::SPEC_HITDIST_FOR_TRACKING) ); // Outputs PushOutput( DIFF_TEMP2 ); diff --git a/Source/Methods/Reblur_DiffuseSpecularSh.hpp b/Source/Methods/Reblur_DiffuseSpecularSh.hpp index e0aab8aa..c6fde80a 100644 --- a/Source/Methods/Reblur_DiffuseSpecularSh.hpp +++ b/Source/Methods/Reblur_DiffuseSpecularSh.hpp @@ -57,6 +57,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularSh(MethodData& methodData { DATA1 = TRANSIENT_POOL_START, DATA2, + SPEC_HITDIST_FOR_TRACKING, DIFF_TMP1, DIFF_TMP2, DIFF_SH_TMP1, @@ -68,7 +69,8 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularSh(MethodData& methodData }; m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); + m_TransientPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_TransientPool.push_back( {REBLUR_FORMAT_SPEC_HITDIST_FOR_TRACKING, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); @@ -128,7 +130,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularSh(MethodData& methodData // Outputs PushOutput( DIFF_TEMP1 ); PushOutput( SPEC_TEMP1 ); - PushOutput( AsUint(Permanent::SPEC_FAST_HISTORY_PONG), 0, 1, AsUint(Permanent::SPEC_FAST_HISTORY_PING) ); + PushOutput( AsUint(Transient::SPEC_HITDIST_FOR_TRACKING) ); PushOutput( DIFF_SH_TEMP1 ); PushOutput( SPEC_SH_TEMP1 ); @@ -163,6 +165,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularSh(MethodData& methodData PushInput( isTemporalStabilization ? AsUint(Permanent::SPEC_HISTORY) : AsUint(ResourceType::OUT_SPEC_SH0) ); PushInput( AsUint(Permanent::DIFF_FAST_HISTORY_PING), 0, 1, AsUint(Permanent::DIFF_FAST_HISTORY_PONG) ); PushInput( AsUint(Permanent::SPEC_FAST_HISTORY_PING), 0, 1, AsUint(Permanent::SPEC_FAST_HISTORY_PONG) ); + PushInput( AsUint(Transient::SPEC_HITDIST_FOR_TRACKING) ); PushInput( isAfterPrepass ? DIFF_SH_TEMP1 : AsUint(ResourceType::IN_DIFF_SH1) ); PushInput( isAfterPrepass ? SPEC_SH_TEMP1 : AsUint(ResourceType::IN_SPEC_SH1) ); PushInput( isTemporalStabilization ? AsUint(Permanent::DIFF_SH_HISTORY) : AsUint(ResourceType::OUT_DIFF_SH1) ); diff --git a/Source/Methods/Reblur_Specular.hpp b/Source/Methods/Reblur_Specular.hpp index f6a25cb4..f25862ac 100644 --- a/Source/Methods/Reblur_Specular.hpp +++ b/Source/Methods/Reblur_Specular.hpp @@ -41,12 +41,14 @@ void nrd::DenoiserImpl::AddMethod_ReblurSpecular(MethodData& methodData) { DATA1 = TRANSIENT_POOL_START, DATA2, + SPEC_HITDIST_FOR_TRACKING, SPEC_TMP1, SPEC_TMP2, }; m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); + m_TransientPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_TransientPool.push_back( {REBLUR_FORMAT_SPEC_HITDIST_FOR_TRACKING, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); @@ -94,7 +96,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurSpecular(MethodData& methodData) // Outputs PushOutput( SPEC_TEMP1 ); - PushOutput( AsUint(Permanent::SPEC_FAST_HISTORY_PONG), 0, 1, AsUint(Permanent::SPEC_FAST_HISTORY_PING) ); + PushOutput( AsUint(Transient::SPEC_HITDIST_FOR_TRACKING) ); // Shaders AddDispatch( REBLUR_Specular_PrePass, REBLUR_PREPASS_CONSTANT_NUM, REBLUR_PREPASS_NUM_THREADS, 1 ); @@ -123,6 +125,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurSpecular(MethodData& methodData) PushInput( isAfterPrepass ? SPEC_TEMP1 : AsUint(ResourceType::IN_SPEC_RADIANCE_HITDIST) ); PushInput( isTemporalStabilization ? AsUint(Permanent::SPEC_HISTORY) : AsUint(ResourceType::OUT_SPEC_RADIANCE_HITDIST) ); PushInput( AsUint(Permanent::SPEC_FAST_HISTORY_PING), 0, 1, AsUint(Permanent::SPEC_FAST_HISTORY_PONG) ); + PushInput( AsUint(Transient::SPEC_HITDIST_FOR_TRACKING) ); // Outputs PushOutput( SPEC_TEMP2 ); diff --git a/Source/Methods/Reblur_SpecularSh.hpp b/Source/Methods/Reblur_SpecularSh.hpp index 0fc2a50d..548b1116 100644 --- a/Source/Methods/Reblur_SpecularSh.hpp +++ b/Source/Methods/Reblur_SpecularSh.hpp @@ -45,6 +45,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurSpecularSh(MethodData& methodData) { DATA1 = TRANSIENT_POOL_START, DATA2, + SPEC_HITDIST_FOR_TRACKING, SPEC_TMP1, SPEC_TMP2, SPEC_SH_TMP1, @@ -52,7 +53,8 @@ void nrd::DenoiserImpl::AddMethod_ReblurSpecularSh(MethodData& methodData) }; m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); + m_TransientPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_TransientPool.push_back( {REBLUR_FORMAT_SPEC_HITDIST_FOR_TRACKING, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); m_TransientPool.push_back( {REBLUR_FORMAT, w, h, 1} ); @@ -103,7 +105,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurSpecularSh(MethodData& methodData) // Outputs PushOutput( SPEC_TEMP1 ); - PushOutput( AsUint(Permanent::SPEC_FAST_HISTORY_PONG), 0, 1, AsUint(Permanent::SPEC_FAST_HISTORY_PING) ); + PushOutput( AsUint(Transient::SPEC_HITDIST_FOR_TRACKING) ); PushOutput( SPEC_SH_TEMP1 ); // Shaders @@ -133,6 +135,7 @@ void nrd::DenoiserImpl::AddMethod_ReblurSpecularSh(MethodData& methodData) PushInput( isAfterPrepass ? SPEC_TEMP1 : AsUint(ResourceType::IN_SPEC_SH0) ); PushInput( isTemporalStabilization ? AsUint(Permanent::SPEC_HISTORY) : AsUint(ResourceType::OUT_SPEC_SH0) ); PushInput( AsUint(Permanent::SPEC_FAST_HISTORY_PING), 0, 1, AsUint(Permanent::SPEC_FAST_HISTORY_PONG) ); + PushInput( AsUint(Transient::SPEC_HITDIST_FOR_TRACKING) ); PushInput( isAfterPrepass ? SPEC_SH_TEMP1 : AsUint(ResourceType::IN_SPEC_SH1) ); PushInput( isTemporalStabilization ? AsUint(Permanent::SPEC_SH_HISTORY) : AsUint(ResourceType::OUT_SPEC_SH1) );