diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a7d81c5..e6f68aa9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,8 +32,10 @@ set (NRD_NORMAL_ENCODING "2" CACHE STRING "Normal encoding variant (0-4, matches set (NRD_ROUGHNESS_ENCODING "1" CACHE STRING "Roughness encoding variant (0-2, matches nrd::RoughnessEncoding)") # Generate PDB for Release builds -set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi") -set (CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") +if (MSVC) + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi") + set (CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG /OPT:REF /OPT:ICF") +endif () # Create project file (READ "Include/NRD.h" ver_h) diff --git a/External/MathLib b/External/MathLib index 099f0ee3..3940a7be 160000 --- a/External/MathLib +++ b/External/MathLib @@ -1 +1 @@ -Subproject commit 099f0ee3fd31aaf77a647b78db2c1f5da274b63b +Subproject commit 3940a7bef553c406e617c94ac6e72042f1054f4e diff --git a/External/ShaderMake b/External/ShaderMake index 13867771..95818b6d 160000 --- a/External/ShaderMake +++ b/External/ShaderMake @@ -1 +1 @@ -Subproject commit 13867771f6142f35690a5e2103c1e1efdd90cb0e +Subproject commit 95818b6d42196fd95d494517607acc1aa3f624ba diff --git a/Include/NRD.h b/Include/NRD.h index fa0ce732..582d44ce 100644 --- a/Include/NRD.h +++ b/Include/NRD.h @@ -28,9 +28,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include #define NRD_VERSION_MAJOR 4 -#define NRD_VERSION_MINOR 5 +#define NRD_VERSION_MINOR 6 #define NRD_VERSION_BUILD 0 -#define NRD_VERSION_DATE "20 February 2024" +#define NRD_VERSION_DATE "19 March 2024" #if defined(_MSC_VER) #define NRD_CALL __fastcall diff --git a/Include/NRDDescs.h b/Include/NRDDescs.h index 4516bead..770301e5 100644 --- a/Include/NRDDescs.h +++ b/Include/NRDDescs.h @@ -11,7 +11,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #pragma once #define NRD_DESCS_VERSION_MAJOR 4 -#define NRD_DESCS_VERSION_MINOR 5 +#define NRD_DESCS_VERSION_MINOR 6 static_assert(NRD_VERSION_MAJOR == NRD_DESCS_VERSION_MAJOR && NRD_VERSION_MINOR == NRD_DESCS_VERSION_MINOR, "Please, update all NRD SDK files"); @@ -168,6 +168,8 @@ namespace nrd /* IMPORTANT: IN_MV, IN_NORMAL_ROUGHNESS, IN_VIEWZ are used by any denoiser These denoisers DON'T use: + SIGMA_SHADOW - IN_VIEWZ + SIGMA_SHADOW_TRANSLUCENCY - IN_VIEWZ REFERENCE - IN_MV, IN_NORMAL_ROUGHNESS, IN_VIEWZ SPECULAR_DELTA_MV - IN_NORMAL_ROUGHNESS, IN_VIEWZ */ diff --git a/Include/NRDSettings.h b/Include/NRDSettings.h index ef155432..cd48012e 100644 --- a/Include/NRDSettings.h +++ b/Include/NRDSettings.h @@ -11,7 +11,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #pragma once #define NRD_SETTINGS_VERSION_MAJOR 4 -#define NRD_SETTINGS_VERSION_MINOR 5 +#define NRD_SETTINGS_VERSION_MINOR 6 static_assert(NRD_VERSION_MAJOR == NRD_SETTINGS_VERSION_MAJOR && NRD_VERSION_MINOR == NRD_SETTINGS_VERSION_MINOR, "Please, update all NRD SDK files"); @@ -203,15 +203,18 @@ namespace nrd // [0; 3] - number of reconstructed frames after history reset (less than "maxFastAccumulatedFrameNum") uint32_t historyFixFrameNum = 3; - // (pixels) - pre-accumulation spatial reuse pass blur radius (0 = disabled, recommended in case of probabilistic sampling) + // (pixels) - pre-accumulation spatial reuse pass blur radius (0 = disabled, must be used in case of badly defined signals and probabilistic sampling) float diffusePrepassBlurRadius = 30.0f; float specularPrepassBlurRadius = 50.0f; - // (pixels) - base denoising radius (30 is a baseline for 1440p) - float blurRadius = 15.0f; + // (pixels) - min denoising radius (for converged state) + float minBlurRadius = 1.0f; + + // (pixels) - max denoising radius (gets reduced over time, 30 is a baseline for 1440p) + float maxBlurRadius = 15.0f; // (normalized %) - base fraction of diffuse or specular lobe angle used to drive normal based rejection - float lobeAngleFraction = 0.15f; + float lobeAngleFraction = 0.2f; // (normalized %) - base fraction of center roughness used to drive roughness based rejection float roughnessFraction = 0.15f; @@ -249,7 +252,7 @@ namespace nrd // worsening the situation. Despite that it's a problem of sampling, the denoiser needs to // handle it somehow on its side too. Diffuse pre-pass can be just disabled, but for specular // it's still needed to find optimal hit distance for tracking. This boolean allow to use - // specular pre-pass for tracking purposes only + // specular pre-pass for tracking purposes only (use with care) bool usePrepassOnlyForSpecularMotionEstimation = false; }; diff --git a/Integration/NRDIntegration.h b/Integration/NRDIntegration.h index bdc7d0d6..24e57671 100644 --- a/Integration/NRDIntegration.h +++ b/Integration/NRDIntegration.h @@ -23,8 +23,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include #define NRD_INTEGRATION_MAJOR 1 -#define NRD_INTEGRATION_MINOR 10 -#define NRD_INTEGRATION_DATE "26 December 2023" +#define NRD_INTEGRATION_MINOR 11 +#define NRD_INTEGRATION_DATE "19 March 2024" #define NRD_INTEGRATION 1 #define NRD_INTEGRATION_DEBUG_LOGGING 0 diff --git a/Integration/NRDIntegration.hpp b/Integration/NRDIntegration.hpp index b5479e8c..4ac4f2cc 100644 --- a/Integration/NRDIntegration.hpp +++ b/Integration/NRDIntegration.hpp @@ -10,8 +10,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRDIntegration.h" -static_assert(NRD_VERSION_MAJOR >= 4 && NRD_VERSION_MINOR >= 4, "Unsupported NRD version!"); -static_assert(NRI_VERSION_MAJOR >= 1 && NRI_VERSION_MINOR >= 118, "Unsupported NRI version!"); +static_assert(NRD_VERSION_MAJOR >= 4 && NRD_VERSION_MINOR >= 5, "Unsupported NRD version!"); +static_assert(NRI_VERSION_MAJOR >= 1 && NRI_VERSION_MINOR >= 125, "Unsupported NRI version!"); #ifdef _WIN32 #define alloca _alloca @@ -520,7 +520,7 @@ void NrdIntegration::Dispatch(nri::CommandBuffer& commandBuffer, nri::Descriptor if (isStateChanged || isStorageBarrier) transitions[transitionBarriers.textureNum++] = nri::TextureBarrierFromState(*nrdTexture->state, {nextAccess, nextLayout}, 0, 1); - uint64_t resource = m_NRI->GetTextureNativeObject(*nrdTexture->state->texture, 0); + uint64_t resource = m_NRI->GetTextureNativeObject(*nrdTexture->state->texture); uint64_t key = NRD_CreateDescriptorKey(resource, isStorage); const auto& entry = m_CachedDescriptors.find(key); @@ -551,7 +551,7 @@ void NrdIntegration::Dispatch(nri::CommandBuffer& commandBuffer, nri::Descriptor for (uint32_t i = 0; i < descriptorSetNum; i++) { if (!samplersAreInSeparateSet || i != descriptorSetSamplersIndex) - NRD_INTEGRATION_ABORT_ON_FAILURE(m_NRI->AllocateDescriptorSets(descriptorPool, *pipelineLayout, i, &descriptorSets[i], 1, nri::ALL_NODES, 0)); + NRD_INTEGRATION_ABORT_ON_FAILURE(m_NRI->AllocateDescriptorSets(descriptorPool, *pipelineLayout, i, &descriptorSets[i], 1, 0)); } // Updating constants @@ -569,7 +569,7 @@ void NrdIntegration::Dispatch(nri::CommandBuffer& commandBuffer, nri::Descriptor m_NRI->UnmapBuffer(*m_ConstantBuffer); } - m_NRI->UpdateDynamicConstantBuffers(*descriptorSets[0], nri::ALL_NODES, 0, 1, &m_ConstantBufferView); + m_NRI->UpdateDynamicConstantBuffers(*descriptorSets[0], 0, 1, &m_ConstantBufferView); dynamicConstantBufferOffset = m_ConstantBufferOffset; m_ConstantBufferOffset += m_ConstantBufferViewSize; @@ -582,17 +582,17 @@ void NrdIntegration::Dispatch(nri::CommandBuffer& commandBuffer, nri::Descriptor nri::DescriptorSet*& descriptorSetSamplers = m_DescriptorSetSamplers[m_DescriptorPoolIndex]; if (!descriptorSetSamplers) { - NRD_INTEGRATION_ABORT_ON_FAILURE(m_NRI->AllocateDescriptorSets(descriptorPool, *pipelineLayout, descriptorSetSamplersIndex, &descriptorSetSamplers, 1, nri::ALL_NODES, 0)); - m_NRI->UpdateDescriptorRanges(*descriptorSetSamplers, nri::ALL_NODES, 0, 1, &samplersDescriptorRange); + NRD_INTEGRATION_ABORT_ON_FAILURE(m_NRI->AllocateDescriptorSets(descriptorPool, *pipelineLayout, descriptorSetSamplersIndex, &descriptorSetSamplers, 1, 0)); + m_NRI->UpdateDescriptorRanges(*descriptorSetSamplers, 0, 1, &samplersDescriptorRange); } descriptorSets[descriptorSetSamplersIndex] = descriptorSetSamplers; } else - m_NRI->UpdateDescriptorRanges(*descriptorSets[descriptorSetSamplersIndex], nri::ALL_NODES, 0, 1, &samplersDescriptorRange); + m_NRI->UpdateDescriptorRanges(*descriptorSets[descriptorSetSamplersIndex], 0, 1, &samplersDescriptorRange); // Updating resources - m_NRI->UpdateDescriptorRanges(*descriptorSets[descriptorSetResourcesIndex], nri::ALL_NODES, instanceDesc.samplersSpaceIndex == instanceDesc.resourcesSpaceIndex ? 1 : 0, pipelineDesc.resourceRangesNum, resourceRanges); + m_NRI->UpdateDescriptorRanges(*descriptorSets[descriptorSetResourcesIndex], instanceDesc.samplersSpaceIndex == instanceDesc.resourcesSpaceIndex ? 1 : 0, pipelineDesc.resourceRangesNum, resourceRanges); // Rendering m_NRI->CmdBarrier(commandBuffer, transitionBarriers); @@ -604,7 +604,7 @@ void NrdIntegration::Dispatch(nri::CommandBuffer& commandBuffer, nri::Descriptor for (uint32_t i = 0; i < descriptorSetNum; i++) m_NRI->CmdSetDescriptorSet(commandBuffer, i, *descriptorSets[i], i == 0 ? &dynamicConstantBufferOffset : nullptr); - m_NRI->CmdDispatch(commandBuffer, dispatchDesc.gridWidth, dispatchDesc.gridHeight, 1); + m_NRI->CmdDispatch(commandBuffer, {dispatchDesc.gridWidth, dispatchDesc.gridHeight, 1}); // Debug logging #if( NRD_INTEGRATION_DEBUG_LOGGING == 1 ) diff --git a/README.md b/README.md index 67936d83..8e4dde5d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# NVIDIA REAL-TIME DENOISERS v4.5.0 (NRD) +# NVIDIA REAL-TIME DENOISERS v4.6.0 (NRD) [![Build NRD SDK](https://github.com/NVIDIAGameWorks/RayTracingDenoiser/actions/workflows/build.yml/badge.svg)](https://github.com/NVIDIAGameWorks/RayTracingDenoiser/actions/workflows/build.yml) @@ -190,6 +190,7 @@ NRD sample is a good start to familiarize yourself with input requirements and b - `hitDistanceReconstructionMode` must be set to something other than `OFF`, but bear in mind that the search area is limited to 3x3 or 5x5. In other words, it's the application's responsibility to guarantee a valid sample in this area. It can be achieved by clamping probabilities and using Bayer-like dithering (see the sample for more details) - Pre-pass must be enabled (i.e. `diffusePrepassBlurRadius` and `specularPrepassBlurRadius` must be set to 20-70 pixels) to compensate entropy increase, since radiance in valid samples is divided by probability to compensate 0 values in some neighbors - Probabilistic sampling for 2nd+ bounces is absolutely acceptable +- in case of many paths per pixel `hitT` for specular must be "averaged" by `NRD_FrontEnd_SpecHitDistAveraging_*` functions from `NRD.hlsli` See `NRDDescs.h` for more details and descriptions of other inputs and outputs. diff --git a/Resources/Version.h b/Resources/Version.h index b1acf017..799314d6 100644 --- a/Resources/Version.h +++ b/Resources/Version.h @@ -22,7 +22,7 @@ Versioning rules: */ #define VERSION_MAJOR 4 -#define VERSION_MINOR 5 +#define VERSION_MINOR 6 #define VERSION_BUILD 0 #define VERSION_STRING STR(VERSION_MAJOR.VERSION_MINOR.VERSION_BUILD encoding=NRD_NORMAL_ENCODING.NRD_ROUGHNESS_ENCODING) diff --git a/Shaders/Include/Common.hlsli b/Shaders/Include/Common.hlsli index bbd4ad24..dc5cf46e 100644 --- a/Shaders/Include/Common.hlsli +++ b/Shaders/Include/Common.hlsli @@ -36,9 +36,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. //================================================================================================================== // Switches ( default 1 ) -#define NRD_USE_TILE_CHECK 1 +#define NRD_USE_TILE_CHECK 1 // significantly improves performance by skipping computations in "empty" regions #define NRD_USE_HIGH_PARALLAX_CURVATURE 1 -#define NRD_USE_DENANIFICATION 1 // needed only if inputs have NAN / INF outside of viewport or denoising range range +#define NRD_USE_DENANIFICATION 1 // needed only if inputs have NAN / INF outside of viewport or denoising range // Switches ( default 0 ) #define NRD_USE_QUADRATIC_DISTRIBUTION 0 diff --git a/Shaders/Include/NRD.hlsli b/Shaders/Include/NRD.hlsli index 02a458d1..787051ac 100644 --- a/Shaders/Include/NRD.hlsli +++ b/Shaders/Include/NRD.hlsli @@ -8,7 +8,7 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -// NRD v4.4 +// NRD v4.6 //================================================================================================================================= // INPUT PARAMETERS @@ -618,6 +618,7 @@ float NRD_FrontEnd_SpecHitDistAveraging_Begin( ) void NRD_FrontEnd_SpecHitDistAveraging_Add( inout float accumulatedSpecHitDist, float hitDist ) { + // TODO: for high roughness it can be blended to average accumulatedSpecHitDist = min( accumulatedSpecHitDist, hitDist == 0.0 ? NRD_INF : hitDist ); } diff --git a/Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli b/Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli index cfba0a9d..b639bb44 100644 --- a/Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli +++ b/Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli @@ -66,15 +66,14 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. float diffNonLinearAccumSpeed = 1.0 / ( 1.0 + REBLUR_SAMPLES_PER_FRAME * ( 1.0 - boost ) * data1.x ); // Blur radius - main - float blurRadius = gBlurRadius * ( 1.0 + 2.0 * boost ) / 3.0; + float blurRadius = gMaxBlurRadius * ( 1.0 + 2.0 * boost ) / 3.0; blurRadius *= hitDistFactor; // Blur radius - addition to avoid underblurring - blurRadius += 1.0; + blurRadius += gMinBlurRadius; // Blur radius - scaling blurRadius *= radiusScale; - blurRadius *= float( gBlurRadius != 0 ); #endif // Weights diff --git a/Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli b/Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli index d00fc3de..d91e6faf 100644 --- a/Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli +++ b/Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli @@ -83,16 +83,15 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. float hitDistFactorAdditionallyRelaxedByRoughness = lerp( 1.0, hitDistFactorRelaxedByError, roughness ); // Blur radius - main - float blurRadius = smc * gBlurRadius * ( 1.0 + 2.0 * boost ) / 3.0; + float blurRadius = smc * gMaxBlurRadius * ( 1.0 + 2.0 * boost ) / 3.0; blurRadius *= lerp( hitDistFactorRelaxedByError, hitDistFactorAdditionallyRelaxedByRoughness, specNonLinearAccumSpeed ); blurRadius = min( blurRadius, minBlurRadius ); // Blur radius - addition to avoid underblurring - blurRadius += smc; // TODO: a source of contact detail loss + blurRadius += gMinBlurRadius * smc; // TODO: a source of contact detail loss // Blur radius - scaling blurRadius *= radiusScale; - blurRadius *= float( gBlurRadius != 0 ); #endif // Weights @@ -187,13 +186,6 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. // Decrease weight for samples that most likely are very close to reflection contact which should not be blurred float t = hs / ( d + hitDist ); w *= lerp( saturate( t ), 1.0, STL::Math::LinearStep( 0.5, 1.0, roughness ) ); - - // Adjust blur radius "on the fly" if taps have short hit distances - #if( REBLUR_USE_ADJUSTED_ON_THE_FLY_BLUR_RADIUS_IN_PRE_BLUR == 1 ) - float hitDistFactorAtSample = GetHitDistFactor( hs * NoD, frustumSize ); - float blurRadiusScale = lerp( hitDistFactorAtSample, 1.0, NoD ); - blurRadius *= lerp( 1.0, blurRadiusScale, n / ( 1.0 + n ) ); - #endif #endif w *= lerp( minHitDistWeight, 1.0, ComputeExponentialWeight( ExtractHitDist( s ), hitDistanceWeightParams.x, hitDistanceWeightParams.y ) ); w *= GetGaussianWeight( offset.z ); diff --git a/Shaders/Include/REBLUR_Config.hlsli b/Shaders/Include/REBLUR_Config.hlsli index 4a20dd3a..7aef79cb 100644 --- a/Shaders/Include/REBLUR_Config.hlsli +++ b/Shaders/Include/REBLUR_Config.hlsli @@ -25,7 +25,6 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_USE_SCREEN_SPACE_SAMPLING 0 #define REBLUR_USE_ANTILAG_NOT_INVOKING_HISTORY_FIX 0 #define REBLUR_USE_DECOMPRESSED_HIT_DIST_IN_RECONSTRUCTION 0 // compression helps to preserve "lobe important" values -#define REBLUR_USE_ADJUSTED_ON_THE_FLY_BLUR_RADIUS_IN_PRE_BLUR 0 // TODO: verify that not needed and delete... #ifdef REBLUR_OCCLUSION #undef REBLUR_USE_ANTIFIREFLY @@ -70,7 +69,6 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #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_HISTORY_FIX_BUMPED_ROUGHNESS 0.08 #define REBLUR_FIREFLY_SUPPRESSOR_MAX_RELATIVE_INTENSITY float2( 10.0, 1.1 ) #define REBLUR_FIREFLY_SUPPRESSOR_RADIUS_SCALE 0.1 #define REBLUR_ANTI_FIREFLY_FILTER_RADIUS 4 // pixels @@ -125,15 +123,16 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_CONSTANT( float, gDenoisingRange ) \ NRD_CONSTANT( float, gPlaneDistSensitivity ) \ NRD_CONSTANT( float, gFramerateScale ) \ - NRD_CONSTANT( float, gBlurRadius ) \ + NRD_CONSTANT( float, gMinBlurRadius ) \ + NRD_CONSTANT( float, gMaxBlurRadius ) \ + NRD_CONSTANT( float, gDiffPrepassBlurRadius ) \ + NRD_CONSTANT( float, gSpecPrepassBlurRadius ) \ NRD_CONSTANT( float, gMaxAccumulatedFrameNum ) \ NRD_CONSTANT( float, gMaxFastAccumulatedFrameNum ) \ NRD_CONSTANT( float, gAntiFirefly ) \ NRD_CONSTANT( float, gLobeAngleFraction ) \ NRD_CONSTANT( float, gRoughnessFraction ) \ NRD_CONSTANT( float, gResponsiveAccumulationRoughnessThreshold ) \ - NRD_CONSTANT( float, gDiffPrepassBlurRadius ) \ - NRD_CONSTANT( float, gSpecPrepassBlurRadius ) \ NRD_CONSTANT( float, gHistoryFixFrameNum ) \ NRD_CONSTANT( float, gMinRectDimMulUnproject ) \ NRD_CONSTANT( float, gUsePrepassNotOnlyForSpecularMotionEstimation ) \ diff --git a/Shaders/Include/REBLUR_HistoryFix.hlsli b/Shaders/Include/REBLUR_HistoryFix.hlsli index 586e2a93..014b4b88 100644 --- a/Shaders/Include/REBLUR_HistoryFix.hlsli +++ b/Shaders/Include/REBLUR_HistoryFix.hlsli @@ -364,9 +364,6 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : w *= 1.0 + UnpackData1( gIn_Data1[ pos ] ).z; #endif - // TODO: ideally "diffuseness at hit" needed... - // TODO: for roughness closer to REBLUR_HISTORY_FIX_BUMPED_ROUGHNESS "saturate( hitDistNormAtCenter - ExtractHitDist( s ) )" could be used. - // It allows bleeding of background to foreground, but not vice versa ( doesn't suit for 0 roughness ) REBLUR_TYPE s = gIn_Spec[ pos ]; s = Denanify( w, s ); diff --git a/Shaders/Include/REBLUR_TemporalAccumulation.hlsli b/Shaders/Include/REBLUR_TemporalAccumulation.hlsli index 469a8764..73a0b2f1 100644 --- a/Shaders/Include/REBLUR_TemporalAccumulation.hlsli +++ b/Shaders/Include/REBLUR_TemporalAccumulation.hlsli @@ -672,7 +672,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : REBLUR_TYPE specHistory = lerp( smbSpecHistory, vmbSpecHistory, virtualHistoryAmount ); // Anti-firefly suppressor - float specAntifireflyFactor = specAccumSpeed * gBlurRadius * REBLUR_FIREFLY_SUPPRESSOR_RADIUS_SCALE * smc; + float specAntifireflyFactor = specAccumSpeed * ( gMinBlurRadius + gMaxBlurRadius ) * REBLUR_FIREFLY_SUPPRESSOR_RADIUS_SCALE * smc; specAntifireflyFactor /= 1.0 + specAntifireflyFactor; float specHitDistResult = ExtractHitDist( specResult ); @@ -806,7 +806,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #endif // Anti-firefly suppressor - float diffAntifireflyFactor = diffAccumSpeed * gBlurRadius * REBLUR_FIREFLY_SUPPRESSOR_RADIUS_SCALE; + float diffAntifireflyFactor = diffAccumSpeed * ( gMinBlurRadius + gMaxBlurRadius ) * REBLUR_FIREFLY_SUPPRESSOR_RADIUS_SCALE; diffAntifireflyFactor /= 1.0 + diffAntifireflyFactor; float diffHitDistResult = ExtractHitDist( diffResult ); diff --git a/Shaders/Include/REBLUR_TemporalStabilization.hlsli b/Shaders/Include/REBLUR_TemporalStabilization.hlsli index 0e8147ba..fe37d7a7 100644 --- a/Shaders/Include/REBLUR_TemporalStabilization.hlsli +++ b/Shaders/Include/REBLUR_TemporalStabilization.hlsli @@ -165,7 +165,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float diffLumaClamped = clamp( diffLuma, diffMin.x, diffMax.x ); [flatten] - if( gBlurRadius != 0 ) + if( gMaxBlurRadius != 0 ) { diff = ChangeLuma( diff, diffLumaClamped ); diff.w = clamp( diff.w, diffMin.y, diffMax.y ); @@ -189,7 +189,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float specLumaClamped = clamp( specLuma, specMin.x, specMax.x ); [flatten] - if( gBlurRadius != 0 ) + if( gMaxBlurRadius != 0 ) { spec = ChangeLuma( spec, specLumaClamped ); spec.w = clamp( spec.w, specMin.y, specMax.y ); diff --git a/Shaders/Include/SIGMA_Blur.hlsli b/Shaders/Include/SIGMA_Blur.hlsli index cdeffd1a..7bfb39d2 100644 --- a/Shaders/Include/SIGMA_Blur.hlsli +++ b/Shaders/Include/SIGMA_Blur.hlsli @@ -56,18 +56,18 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : if( viewZ > gDenoisingRange ) return; - float2 pixelUv = float2( pixelPos + 0.5 ) * gRectSizeInv; + // Copy history #ifdef SIGMA_FIRST_PASS - // Copy history gOut_History[ pixelPos ] = gIn_History[ pixelPos ]; + #endif - float tileValue = TextureCubic( gIn_Tiles, pixelUv * gResolutionScale ); + // Tile-based early out ( potentially ) + float2 pixelUv = float2( pixelPos + 0.5 ) * gRectSizeInv; + float tileValue = TextureCubic( gIn_Tiles, pixelUv * gResolutionScale ); + #ifdef SIGMA_FIRST_PASS tileValue *= all( pixelPos < gRectSize ); // due to USE_MAX_DIMS - #else - float tileValue = 1.0; #endif - // Early out if( ( tileValue == 0.0 && NRD_USE_TILE_CHECK ) || centerHitDist == 0.0 ) { gOut_Shadow_Translucency[ pixelPos ] = PackShadow( s_Shadow_Translucency[ smemPos.y ][ smemPos.x ] ); @@ -151,7 +151,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float3 Bv = mWorldToLocal[ 1 ] * worldRadius; // Random rotation - float4 rotator = GetBlurKernelRotation( NRD_PIXEL, pixelPos, gRotator, gFrameIndex ); + float4 rotator = GetBlurKernelRotation( SIGMA_ROTATOR_MODE, pixelPos, gRotator, gFrameIndex ); // Denoising sum = 1.0; diff --git a/Shaders/Include/SIGMA_Common.hlsli b/Shaders/Include/SIGMA_Common.hlsli index b49384ae..321547e4 100644 --- a/Shaders/Include/SIGMA_Common.hlsli +++ b/Shaders/Include/SIGMA_Common.hlsli @@ -8,11 +8,6 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -// Debug - -#define SIGMA_REFERENCE 0 // works better with 16-bit precision -#define SIGMA_SHOW_TILES 0 - // Misc #define PackShadow( s ) STL::Math::Sqrt01( s ) diff --git a/Shaders/Include/SIGMA_Config.hlsli b/Shaders/Include/SIGMA_Config.hlsli index 98f9cc2f..5be9710d 100644 --- a/Shaders/Include/SIGMA_Config.hlsli +++ b/Shaders/Include/SIGMA_Config.hlsli @@ -15,7 +15,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define SIGMA_5X5_TEMPORAL_KERNEL 1 // provides variance estimation in a wider radius #define SIGMA_5X5_BLUR_RADIUS_ESTIMATION_KERNEL 1 // helps to improve stability, but adds 10% of overhead +// Switches ( default 0 ) +#define SIGMA_REFERENCE 0 // works better with 16-bit precision +#define SIGMA_SHOW_TILES 0 + // Settings +#define SIGMA_ROTATOR_MODE NRD_PIXEL // NRD_FRAME? #define SIGMA_POISSON_SAMPLE_NUM 8 #define SIGMA_POISSON_SAMPLES g_Poisson8 #define SIGMA_MAX_PIXEL_RADIUS 32.0 diff --git a/Source/Reblur.cpp b/Source/Reblur.cpp index f371f65a..3f2b22fc 100644 --- a/Source/Reblur.cpp +++ b/Source/Reblur.cpp @@ -309,7 +309,7 @@ void nrd::InstanceImpl::AddSharedConstants_Reblur(const ReblurSettings& settings bool isHistoryReset = m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE; float unproject = 1.0f / (0.5f * rectH * m_ProjectY); float worstResolutionScale = Min(float(rectW) / float(resourceW), float(rectH) / float(resourceH)); - float blurRadius = settings.blurRadius * worstResolutionScale; + float maxBlurRadius = settings.maxBlurRadius * worstResolutionScale; float diffusePrepassBlurRadius = settings.diffusePrepassBlurRadius * worstResolutionScale; float specularPrepassBlurRadius = settings.specularPrepassBlurRadius * worstResolutionScale; float disocclusionThresholdBonus = (1.0f + m_JitterDelta) / float(rectH); @@ -368,15 +368,16 @@ void nrd::InstanceImpl::AddSharedConstants_Reblur(const ReblurSettings& settings consts->gDenoisingRange = m_CommonSettings.denoisingRange; consts->gPlaneDistSensitivity = settings.planeDistanceSensitivity; consts->gFramerateScale = m_FrameRateScale; - consts->gBlurRadius = blurRadius; + consts->gMaxBlurRadius = maxBlurRadius; + consts->gMinBlurRadius = settings.minBlurRadius; + consts->gDiffPrepassBlurRadius = diffusePrepassBlurRadius; + consts->gSpecPrepassBlurRadius = specularPrepassBlurRadius; consts->gMaxAccumulatedFrameNum = isHistoryReset ? 0 : float(maxAccumulatedFrameNum); consts->gMaxFastAccumulatedFrameNum = float(settings.maxFastAccumulatedFrameNum); consts->gAntiFirefly = settings.enableAntiFirefly ? 1.0f : 0.0f; consts->gLobeAngleFraction = settings.lobeAngleFraction; consts->gRoughnessFraction = settings.roughnessFraction; consts->gResponsiveAccumulationRoughnessThreshold = settings.responsiveAccumulationRoughnessThreshold; - consts->gDiffPrepassBlurRadius = diffusePrepassBlurRadius; - consts->gSpecPrepassBlurRadius = specularPrepassBlurRadius; consts->gHistoryFixFrameNum = (float)Min(settings.historyFixFrameNum, 3u); consts->gMinRectDimMulUnproject = (float)Min(rectW, rectH) * unproject; consts->gUsePrepassNotOnlyForSpecularMotionEstimation = settings.usePrepassOnlyForSpecularMotionEstimation ? 0.0f : 1.0f; diff --git a/UPDATE.md b/UPDATE.md index 0c258791..2553c964 100644 --- a/UPDATE.md +++ b/UPDATE.md @@ -218,3 +218,9 @@ A single NRD instance can now include any combination of denoisers, including re - *API*: - `ResourceDesc::stateNeeded` renamed to `ResourceDesc::descriptorType` to match `ResourceRangeDesc::descriptorType` because the former is a concatenation of the latter + +## To v4.6 + +- *REBLUR*: + - `blurRadius` renamed to `maxBlurRadius` + - exposed `minBlurRadius` with the default value matching older versions