diff --git a/.gitignore b/.gitignore index 67f3f26..83086f5 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,7 @@ Makefile # VS Code .vscode/ -# Shaders +# shaders *.dxbc *.dxil *.spirv @@ -26,7 +26,14 @@ Makefile *.dxil.h *.spirv.h -# Library +# ninja +.ninja_deps +.ninja_log +build.ninja +compile_commands.json +*.log + +# library *.lib *.exp *.dll @@ -36,12 +43,7 @@ Makefile *.so.* *.manifest -# ninja -.ninja_deps -.ninja_log -build.ninja -compile_commands.json -*.log - -# batch script -_NRD_SDK/ \ No newline at end of file +# generated folders +_Build/ +_Compiler/ +_NRD_SDK/ diff --git a/3-Prepare NRD SDK.bat b/3-Prepare NRD SDK.bat index 8728b15..3224507 100644 --- a/3-Prepare NRD SDK.bat +++ b/3-Prepare NRD SDK.bat @@ -27,10 +27,9 @@ if /I "%M%" neq "y" goto END mkdir "Shaders" -copy "..\%NRD_DIR%\Source\Shaders\*" "Shaders" -copy "..\%NRD_DIR%\Source\Shaders\Include\*" "Shaders" -copy "..\%NRD_DIR%\External\MathLib\*.hlsli" "Shaders" -copy "..\%NRD_DIR%\Include\*.hlsli" "Shaders" +xcopy "..\%NRD_DIR%\Source\Shaders\" "Shaders" /s +copy "..\%NRD_DIR%\External\MathLib\*.hlsli" "Shaders\Include" +copy "..\%NRD_DIR%\Include\*.hlsli" "Shaders\Include" :END diff --git a/3-Prepare NRD SDK.sh b/3-Prepare NRD SDK.sh index 5ad84a5..3025d64 100644 --- a/3-Prepare NRD SDK.sh +++ b/3-Prepare NRD SDK.sh @@ -24,8 +24,7 @@ if [[ $REPLY =~ ^[Yy]$ ]] then mkdir -p "Shaders" - cp ../$NRD_DIR/Source/Shaders/*.* "Shaders" - cp ../$NRD_DIR/Source/Shaders/Include/* "Shaders" + cp -r ../$NRD_DIR/Source/Shaders/ "Shaders" cp ../$NRD_DIR/External/MathLib/*.hlsli "Shaders" cp ../$NRD_DIR/Include/*.hlsli "Shaders" fi diff --git a/CMakeLists.txt b/CMakeLists.txt index 37bd120..641ac6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,12 +42,6 @@ set(CMAKE_POSITION_INDEPENDENT_BINARIES ON) set(CMAKE_CXX_VISIBILITY_PRESET hidden) set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) -# warning level 4 and all warnings as errors -if (MSVC) - add_compile_options(/W4 /WX) -else() - add_compile_options(-Wall -Wno-long-long -Werror) -endif() if (NRD_DISABLE_INTERPROCEDURAL_OPTIMIZATION) set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) @@ -69,21 +63,16 @@ if (NOT NRD_DISABLE_SHADER_COMPILATION) file(GLOB_RECURSE NRD_HLSL_MATHLIB_HEADER_FILES "${NRD_MATHLIB_INCLUDE_PATH}/*.hlsli") file(GLOB_RECURSE NRD_HLSL_INCLUDE "Include/*.hlsli") + file(MAKE_DIRECTORY ${NRD_SHADER_OUTPUT_PATH}) include(ShaderCompilation.cmake) - # create "build/Shaders" - add_custom_target(CreateFolderForShaders ALL - COMMAND ${CMAKE_COMMAND} -E make_directory "${NRD_SHADER_OUTPUT_PATH}") - set_property(TARGET CreateFolderForShaders PROPERTY FOLDER "${NRD_PROJECT_FOLDER}") - # define build rules for the shaders list_hlsl_headers("${NRD_HLSL_FILES}" NRD_HEADER_FILES) list_hlsl_headers("${NRD_HLSL_MATHLIB_HEADER_FILES}" NRD_HEADER_FILES) list_hlsl_headers("${NRD_HLSL_INCLUDE}" NRD_HEADER_FILES) list_hlsl_shaders("${NRD_HLSL_FILES}" "${NRD_HEADER_FILES}" NRD_SHADER_FILES) - add_custom_target(NrdShaders ALL DEPENDS ${NRD_SHADER_FILES} SOURCES "${NRD_HEADER_FILES}") - add_dependencies(NrdShaders CreateFolderForShaders) - set_property(TARGET NrdShaders PROPERTY FOLDER "${NRD_PROJECT_FOLDER}") + add_custom_target(NRDShaders ALL DEPENDS ${NRD_SHADER_FILES} SOURCES "${NRD_HEADER_FILES}") + set_property(TARGET NRDShaders PROPERTY FOLDER "${NRD_PROJECT_FOLDER}") endif() if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR}) @@ -116,7 +105,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC "Include" "External") set_property(TARGET ${PROJECT_NAME} PROPERTY FOLDER "${NRD_PROJECT_FOLDER}") if (NOT NRD_DISABLE_SHADER_COMPILATION) - add_dependencies(${PROJECT_NAME} NrdShaders) + add_dependencies(${PROJECT_NAME} NRDShaders) endif() if (NRD_USE_PRECOMPILED_SHADERS) @@ -131,9 +120,7 @@ else() target_compile_definitions(${PROJECT_NAME} PRIVATE NRD_ONLY_SPIRV_SHADERS_AVAILABLE=1) endif() -if (NRD_STATIC_LIBRARY) - target_compile_definitions(${PROJECT_NAME} PUBLIC "NRD_API=extern \"C\"") -else() +if (NOT NRD_STATIC_LIBRARY) if(WIN32) target_compile_definitions(${PROJECT_NAME} PRIVATE "NRD_API=extern \"C\" __declspec(dllexport)") else() @@ -145,10 +132,13 @@ if ((CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64") OR (CMAKE_SYSTEM_PROCESSOR MATCHES set(NRD_ARCHITECTURE_COMPILE_OPTIONS -msse4.1) endif() +# warning level 4 and all warnings as errors if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - target_compile_options(${PROJECT_NAME} PRIVATE ${NRD_ARCHITECTURE_COMPILE_OPTIONS} -Wno-missing-braces -Wno-return-type-c-linkage) + target_compile_options(${PROJECT_NAME} PRIVATE ${NRD_ARCHITECTURE_COMPILE_OPTIONS} -Wextra -Werror -Wno-return-type-c-linkage) elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU") - target_compile_options(${PROJECT_NAME} PRIVATE ${NRD_ARCHITECTURE_COMPILE_OPTIONS}) + target_compile_options(${PROJECT_NAME} PRIVATE ${NRD_ARCHITECTURE_COMPILE_OPTIONS} -Wall -Werror) +elseif (MSVC) + target_compile_options(${PROJECT_NAME} PRIVATE /W4 /WX) endif() if (NOT NRD_IS_SUBMODULE) diff --git a/External/MathLib b/External/MathLib index a5427a0..c062167 160000 --- a/External/MathLib +++ b/External/MathLib @@ -1 +1 @@ -Subproject commit a5427a09bb5a493dcd7775140f776ae6cd2940ae +Subproject commit c062167f92b9b14ab159c69e9787d29819584e20 diff --git a/Include/NRD.h b/Include/NRD.h index 06b0bee..b3c458b 100644 --- a/Include/NRD.h +++ b/Include/NRD.h @@ -30,10 +30,10 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include #include -#define NRD_VERSION_MAJOR 2 -#define NRD_VERSION_MINOR 12 -#define NRD_VERSION_BUILD 2 -#define NRD_VERSION_DATE "11 February 2022" +#define NRD_VERSION_MAJOR 3 +#define NRD_VERSION_MINOR 0 +#define NRD_VERSION_BUILD 0 +#define NRD_VERSION_DATE "21 March 2022" #if defined(_MSC_VER) #define NRD_CALL __fastcall @@ -44,7 +44,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #endif #ifndef NRD_API - #define NRD_API extern "C" + #if NRD_STATIC_LIBRARY + #define NRD_API + #else + #define NRD_API extern "C" + #endif #endif #include "NRDDescs.h" diff --git a/Include/NRD.hlsli b/Include/NRD.hlsli index 0d4b21c..7735cba 100644 --- a/Include/NRD.hlsli +++ b/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 v2.12 +// NRD v3.0 //================================================================================================================================= // INPUT PARAMETERS @@ -26,8 +26,8 @@ float3 radiance: - use VNDF sampling ( or custom importance sampling ) - if radiance is the result of path tracing, pass normalized hit distance as the sum of first 1-3 hits (always ignore primary hit!) -float linearRoughness: - - linearRoughness = sqrt( roughness ), where "roughness" = "m" = "alpha" - specular or real roughness +float roughness: + - "linear roughness" = sqrt( "m" ), where "m" = "alpha" - GGX roughness float normal: - world space normal @@ -60,11 +60,14 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : // IMPORTANT: DO NOT MODIFY THIS FILE WITHOUT FULL RECOMPILATION OF NRD LIBRARY! + #ifndef NRD_INCLUDED + #define NRD_INCLUDED + //================================================================================================================================= // BINDINGS //================================================================================================================================= -#if( defined COMPILER_FXC || defined COMPILER_DXC ) +#if( defined NRD_COMPILER_UNREAL_ENGINE ) #ifndef NRD_CS_MAIN #define NRD_CS_MAIN main @@ -72,15 +75,15 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : #define NRD_EXPORT - #define NRD_CONSTANTS_START cbuffer globalConstants : register( b0 ) { + #define NRD_CONSTANTS_START #define NRD_CONSTANT( constantType, constantName ) constantType constantName; - #define NRD_CONSTANTS_END }; + #define NRD_CONSTANTS_END - #define NRD_INPUT_TEXTURE( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName : register( regName ## bindingIndex ); - #define NRD_OUTPUT_TEXTURE( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName : register( regName ## bindingIndex ); - #define NRD_SAMPLER( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName : register( regName ## bindingIndex ); + #define NRD_INPUT_TEXTURE( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName; + #define NRD_OUTPUT_TEXTURE( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName; + #define NRD_SAMPLER( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName; -#elif( defined COMPILER_UNREAL_ENGINE ) +#elif( defined NRD_COMPILER_FXC || defined NRD_COMPILER_DXC ) #ifndef NRD_CS_MAIN #define NRD_CS_MAIN main @@ -88,15 +91,15 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : #define NRD_EXPORT - #define NRD_CONSTANTS_START + #define NRD_CONSTANTS_START cbuffer globalConstants : register( b0 ) { #define NRD_CONSTANT( constantType, constantName ) constantType constantName; - #define NRD_CONSTANTS_END + #define NRD_CONSTANTS_END }; - #define NRD_INPUT_TEXTURE( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName; - #define NRD_OUTPUT_TEXTURE( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName; - #define NRD_SAMPLER( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName; + #define NRD_INPUT_TEXTURE( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName : register( regName ## bindingIndex ); + #define NRD_OUTPUT_TEXTURE( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName : register( regName ## bindingIndex ); + #define NRD_SAMPLER( resourceType, resourceName, regName, bindingIndex ) resourceType resourceName : register( regName ## bindingIndex ); -#elif( defined COMPILER_PSSLC ) +#elif( defined NRD_COMPILER_PSSLC ) // Helpers #define EXPAND( x ) x @@ -113,7 +116,11 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : #define NRD_CS_MAIN main #endif - #define NRD_EXPORT [ CxxSymbol( EXPORT_NAME ) ] + #ifdef EXPORT_NAME + #define NRD_EXPORT [ CxxSymbol( EXPORT_NAME ) ] + #else + #define NRD_EXPORT + #endif #define NRD_CONSTANTS_START ConstantBuffer globalConstants : register( b0 ) { #define NRD_CONSTANT( constantType, constantName ) constantType constantName; @@ -139,6 +146,7 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : #define reversebits ReverseBits #define InterlockedAdd( ... ) AtomicAdd( __VA_ARGS__ ) #define InterlockedMax( ... ) AtomicMax( __VA_ARGS__ ) + #define unorm #elif( defined( NRD_INPUT_TEXTURE ) && defined( NRD_OUTPUT_TEXTURE ) && defined( NRD_CONSTANTS_START ) && defined( NRD_CONSTANT ) && defined( NRD_CONSTANTS_END ) ) @@ -150,9 +158,9 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : // Custom engine that has already defined all the macros -#else +#elif( !defined( NRD_HEADER_ONLY ) ) - #error "Please, define one of COMPILER_FXC / COMPILER_DXC or COMPILER_UNREAL_ENGINE or add custom bindings. Use already defined platforms as a reference." + #error "Please, define one of NRD_COMPILER_[FXC/DXC/PSSLC/UNREAL_ENGINE] or add custom bindings (use already defined platforms as a reference). Or define NRD_HEADER_ONLY to use this file as a header file only." #endif @@ -166,9 +174,8 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : #define NRD_RADIANCE_COMPRESSION_MODE_BETTER_LOW_ROUGHNESS 3 #define NRD_RADIANCE_COMPRESSION_MODE_SIMPLER_LOW_ROUGHNESS 4 -#define NRD_NORMAL_ENCODING_UNORM8 0 // R8G8B8A8 - worst quality, best perf -#define NRD_NORMAL_ENCODING_OCT10 1 // R10G10B10A2 - adds small overhead, good quality -#define NRD_NORMAL_ENCODING_UNORM16 2 // R16G16B16A16 - best quality, worst perf +#define NRD_NORMAL_ENCODING_UNORM 0 // .xyz - normal, .w - roughness +#define NRD_NORMAL_ENCODING_OCT 1 // .xy - normal, .z - roughness, .w - optional materialID #define NRD_FP16_MAX 65504.0 @@ -176,22 +183,19 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : // SETTINGS //================================================================================================================================= -// Used to convert viewZ from FP32 to FP16 -#define NRD_FP16_VIEWZ_SCALE 0.125 - // Must match encoding used for IN_NORMAL_ROUGHNESS #ifndef NRD_USE_SQRT_LINEAR_ROUGHNESS #define NRD_USE_SQRT_LINEAR_ROUGHNESS 0 #endif -// Must match encoding used for IN_NORMAL_ROUGHNESS -#ifndef NRD_USE_MATERIAL_ID_AWARE_FILTERING - #define NRD_USE_MATERIAL_ID_AWARE_FILTERING 1 +// Material ID support +#ifndef NRD_USE_MATERIAL_ID + #define NRD_USE_MATERIAL_ID 1 #endif // Must match encoding used for IN_NORMAL_ROUGHNESS #ifndef NRD_NORMAL_ENCODING - #define NRD_NORMAL_ENCODING NRD_NORMAL_ENCODING_OCT10 + #define NRD_NORMAL_ENCODING NRD_NORMAL_ENCODING_OCT #endif // [Optional] Color compression for spatial passes (can be NRD_RADIANCE_COMPRESSION_MODE_NONE if the signal is relatively clean) @@ -199,6 +203,9 @@ NOTE: if "roughness" is needed as an input parameter use is as "isDiffuse ? 1 : #define NRD_RADIANCE_COMPRESSION_MODE NRD_RADIANCE_COMPRESSION_MODE_BETTER_LOW_ROUGHNESS // 0-4 #endif +// [Optional] Used to convert viewZ from FP32 to FP16 +#define NRD_FP16_VIEWZ_SCALE 0.125 + //================================================================================================================================= // PRIVATE //================================================================================================================================= @@ -230,7 +237,7 @@ float _NRD_Luminance( float3 linearColor ) return dot( linearColor, float3( 0.2990, 0.5870, 0.1140 ) ); } -float _NRD_GetColorCompressionExposureForSpatialPasses( float linearRoughness ) +float _NRD_GetColorCompressionExposureForSpatialPasses( float roughness ) { // Prerequsites: // - to minimize biasing the results compression for high roughness should be avoided (diffuse signal compression can lead to darker image) @@ -240,16 +247,16 @@ float _NRD_GetColorCompressionExposureForSpatialPasses( float linearRoughness ) // Moderate compression #if( NRD_RADIANCE_COMPRESSION_MODE == NRD_RADIANCE_COMPRESSION_MODE_MODERATE ) - return 0.5 / ( 1.0 + 50.0 * linearRoughness ); + return 0.5 / ( 1.0 + 50.0 * roughness ); // Less compression for mid-high roughness #elif( NRD_RADIANCE_COMPRESSION_MODE == NRD_RADIANCE_COMPRESSION_MODE_LESS_MID_ROUGHNESS ) - return 0.5 * ( 1.0 - linearRoughness ) / ( 1.0 + 60.0 * linearRoughness ); + return 0.5 * ( 1.0 - roughness ) / ( 1.0 + 60.0 * roughness ); // Close to the previous one, but offers more compression for low roughness #elif( NRD_RADIANCE_COMPRESSION_MODE == NRD_RADIANCE_COMPRESSION_MODE_BETTER_LOW_ROUGHNESS ) - return 0.5 * ( 1.0 - linearRoughness ) / ( 1.0 + 1000.0 * linearRoughness * linearRoughness ) + ( 1.0 - sqrt( saturate( linearRoughness ) ) ) * 0.03; + return 0.5 * ( 1.0 - roughness ) / ( 1.0 + 1000.0 * roughness * roughness ) + ( 1.0 - sqrt( saturate( roughness ) ) ) * 0.03; // A modification of the preious one ( simpler ) #elif( NRD_RADIANCE_COMPRESSION_MODE == NRD_RADIANCE_COMPRESSION_MODE_SIMPLER_LOW_ROUGHNESS ) - return 0.6 * ( 1.0 - linearRoughness * linearRoughness ) / ( 1.0 + 400.0 * linearRoughness * linearRoughness ); + return 0.6 * ( 1.0 - roughness * roughness ) / ( 1.0 + 400.0 * roughness * roughness ); // No compression #else return 0; @@ -257,9 +264,9 @@ float _NRD_GetColorCompressionExposureForSpatialPasses( float linearRoughness ) } // Hit distance normalization -float _REBLUR_GetHitDistanceNormalization( float viewZ, float4 hitDistParams, float linearRoughness = 1.0 ) +float _REBLUR_GetHitDistanceNormalization( float viewZ, float4 hitDistParams, float roughness = 1.0 ) { - return ( hitDistParams.x + abs( viewZ ) * hitDistParams.y ) * lerp( 1.0, hitDistParams.z, saturate( exp2( hitDistParams.w * linearRoughness * linearRoughness ) ) ); + return ( hitDistParams.x + abs( viewZ ) * hitDistParams.y ) * lerp( 1.0, hitDistParams.z, saturate( exp2( hitDistParams.w * roughness * roughness ) ) ); } //================================================================================================================================= @@ -271,25 +278,23 @@ float _REBLUR_GetHitDistanceNormalization( float viewZ, float4 hitDistParams, fl //======== // This function is used in all denoisers to decode normal, roughness and optional materialID -float4 NRD_FrontEnd_UnpackNormalAndRoughness( float4 p, out uint materialID ) +float4 NRD_FrontEnd_UnpackNormalAndRoughness( float4 p, out float materialID ) { + materialID = 0; + float4 r; - #if( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_OCT10 ) + #if( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_OCT ) r.xyz = _NRD_DecodeUnitVector( p.xy, false, false ); r.w = p.z; + + #if( NRD_USE_MATERIAL_ID == 1 ) + materialID = p.w; + #endif #else r.xyz = p.xyz * 2.0 - 1.0; r.w = p.w; #endif - // By default NRD offers only this decoding variant. It can be changed to match a specific encoding method - #if( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_OCT10 && NRD_USE_MATERIAL_ID_AWARE_FILTERING == 1 ) - materialID = uint( p.w * 3.0 ); - #else - materialID = 0; - #endif - - // Normalization is very important due to potential octahedron encoding and potential "best fit" usage for simple "N * 0.5 + 0.5" method r.xyz = normalize( r.xyz ); #if( NRD_USE_SQRT_LINEAR_ROUGHNESS == 1 ) @@ -307,27 +312,24 @@ float4 NRD_FrontEnd_UnpackNormalAndRoughness( float4 p ) } // Not used in NRD -float4 NRD_FrontEnd_PackNormalAndRoughness( float3 N, float linearRoughness, float materialID = 0 ) +float4 NRD_FrontEnd_PackNormalAndRoughness( float3 N, float roughness, uint materialID = 0 ) { float4 p; #if( NRD_USE_SQRT_LINEAR_ROUGHNESS == 1 ) - linearRoughness = STL::Math::Sqrt01( linearRoughness ); + roughness = STL::Math::Sqrt01( roughness ); #endif - #if( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_OCT10 ) + #if( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_OCT ) p.xy = _NRD_EncodeUnitVector( N, false ); - p.z = linearRoughness; - p.w = saturate( materialID / 3.0 ); + p.z = roughness; + p.w = saturate( ( materialID + 0.5 ) / 3.0 ); #else - p.xyz = N; - // Best fit ( optional ) - float m = max( abs( N.x ), max( abs( N.y ), abs( N.z ) ) ); - p.xyz /= m; + N /= max( abs( N.x ), max( abs( N.y ), abs( N.z ) ) ); - p.xyz = p.xyz * 0.5 + 0.5; - p.w = linearRoughness; + p.xyz = N * 0.5 + 0.5; + p.w = roughness; #endif return p; @@ -336,11 +338,16 @@ float4 NRD_FrontEnd_PackNormalAndRoughness( float3 N, float linearRoughness, flo // Helper functions to pack / unpack ray direction and PDF ( can be averaged for some samples ) float4 NRD_FrontEnd_PackDirectionAndPdf( float3 direction, float pdf ) { + // PDF can be extremely large, but we need to fit into FP16 + pdf = sqrt( clamp( pdf, 0.0001, 10000.0 ) ); + return float4( direction, pdf ); } float4 NRD_FrontEnd_UnpackDirectionAndPdf( float4 directionAndPdf ) { + directionAndPdf.w *= directionAndPdf.w; + return directionAndPdf; } @@ -349,9 +356,9 @@ float4 NRD_FrontEnd_UnpackDirectionAndPdf( float4 directionAndPdf ) //======== // This function returns AO / SO which REBLUR can decode back to "hit distance" internally -float REBLUR_FrontEnd_GetNormHitDist( float hitDist, float viewZ, float4 hitDistParams, float linearRoughness = 1.0 ) +float REBLUR_FrontEnd_GetNormHitDist( float hitDist, float viewZ, float4 hitDistParams, float roughness = 1.0 ) { - float f = _REBLUR_GetHitDistanceNormalization( viewZ, hitDistParams, linearRoughness ); + float f = _REBLUR_GetHitDistanceNormalization( viewZ, hitDistParams, roughness ); return saturate( hitDist / f ); } @@ -500,26 +507,50 @@ float4 RELAX_BackEnd_UnpackRadianceAndHitDist( float4 color ) //================================================================================================================================= // MISC //================================================================================================================================= +/* +This function is WIP, but better use it for future compatibility. + +Good start: + Passing to NRD only hit distance for the first bounce is a good start. It works well for diffuse and + for diffuse-like surfaces in reflections ( even if roughness is low ): + + float accumulatedHitDist = 0; + + for( uint bounceIndex = 1; bounceIndex < bounceNum; bounceIndex++ ) + { + TracePath( ... ); + + accumulatedHitDist += bounceIndex == 1 ? currentHitDist : 0; + } + +But in general ( especially for pure specular paths ) the following solution is better: -// This can be a start, but works badly in many cases: -// hitDist = hitDist1 + hitDist2 + ... ; -// Proper solution: -// hitDist = NRD_GetCorrectedHitDist( hitDist1, 1, roughness0 ); -// hitDist += NRD_GetCorrectedHitDist( hitDist2, 2, roughness0, importance2 ); -// where "importance" shows how much energy a new hit brings compared with the previous state (see NRD sample for more details) -// Notes: -// 0 - primary hit -// 1+ - bounces + float accumulatedHitDist = 0; + float accumulatedRoughness = 0; + + for( uint bounceIndex = 1; bounceIndex < bounceNum; bounceIndex++ ) + { + TracePath( ... ); + + accumulatedHitDist += NRD_GetCorrectedHitDist( currentHitDist, bounceIndex, accumulatedRoughness, currentImportance ); + accumulatedRoughness += isNextEventDiffuse ? 1 : hitRoughness; + } + +where: + importance - shows how much energy a new hit brings compared with the previous state (see NRD sample for more details) + bounceIndex - 0 for primary hit, 1+ for bounces +*/ // TODO: local curvature is needed to adjust hit distance for 2nd+ bounces -float NRD_GetCorrectedHitDist( float hitDist, float bounceIndex, float roughness0 = 1.0, float importance = 1.0 ) +float NRD_GetCorrectedHitDist( float hitDist, float bounceIndex, float roughnessAccumulatedAlongPath, float importance = 1.0 ) { - bounceIndex -= 1.0; // 0-based starting from 1st bounce + // 0-based starting from 1st bounce ( even for direct lighting denoising pass bounceIndex = 1 ) + bounceIndex -= 1.0; - float m0 = roughness0 * roughness0; - float compression = 1.0 - exp( -m0 * bounceIndex ); + float m = roughnessAccumulatedAlongPath * roughnessAccumulatedAlongPath; + float compression = 1.0 - exp( -m * bounceIndex ); float compresedHitDist = hitDist / ( 1.0 + hitDist * compression ); - float contribution = 1.0 + bounceIndex * bounceIndex * m0; + float contribution = 1.0 + bounceIndex * bounceIndex * m; return compresedHitDist * importance / contribution; } @@ -552,3 +583,5 @@ float REBLUR_GetHitDist( float normHitDist, float viewZ, float4 hitDistParams, f return normHitDist * scale; } + +#endif diff --git a/Include/NRDDescs.h b/Include/NRDDescs.h index 9daa682..dfdd866 100644 --- a/Include/NRDDescs.h +++ b/Include/NRDDescs.h @@ -10,8 +10,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #pragma once -#define NRD_DESCS_VERSION_MAJOR 2 -#define NRD_DESCS_VERSION_MINOR 12 +#define NRD_DESCS_VERSION_MAJOR 3 +#define NRD_DESCS_VERSION_MINOR 0 static_assert (NRD_VERSION_MAJOR == NRD_DESCS_VERSION_MAJOR && NRD_VERSION_MINOR == NRD_DESCS_VERSION_MINOR, "Please, update all NRD SDK files"); @@ -99,10 +99,22 @@ namespace nrd // REFERENCE // ============================================================================================================================= - // INPUTS - IN_DIFF_RADIANCE_HITDIST - // OUTPUTS - OUT_DIFF_RADIANCE_HITDIST + // INPUTS - IN_RADIANCE + // OUTPUTS - OUT_RADIANCE REFERENCE, + // ============================================================================================================================= + // MOTION VECTORS + // ============================================================================================================================= + + // INPUTS - IN_MV, IN_NORMAL_ROUGHNESS, IN_VIEWZ, IN_SPEC_HITDIST + // OUTPUTS - OUT_SPEC_REFLECTION_MV + SPEC_REFLECTION_MV, + + // INPUTS - IN_MV, IN_DELTA_PRIMARY_POSW, IN_DELTA_SECONDARY_POSW + // OUTPUT - OUT_DELTA_MV + DELTA_OPTIMIZATION_MV, + MAX_NUM }; @@ -122,8 +134,12 @@ namespace nrd // Linear view depth for primary rays (R16f+) IN_VIEWZ, - // REBLUR: Data must be packed using "REBLUR_FrontEnd_PackRadianceAndHitDist" (and "REBLUR_FrontEnd_GetNormHitDist" for hit distance) (RGBA16f+) // RELAX: Data must be packed using "RELAX_FrontEnd_PackRadianceAndHitDist" + // REBLUR: Data must be packed using "REBLUR_FrontEnd_PackRadianceAndHitDist" (and "REBLUR_FrontEnd_GetNormHitDist" for hit distance) (RGBA16f+) + // Noisy and weighted sum of hit distances along a path (using NRD_GetCorrectedHitDist), excluding primary hit distance. + // REBLUR works with normalized hit distances. It's recommended to use REBLUR_FrontEnd_GetNormHitDist for hit distance normalization. + // Normalization parameters should be passed into NRD as HitDistanceParameters for diffuse and specular separately for internal + // hit distance denormalization. IN_DIFF_RADIANCE_HITDIST, IN_SPEC_RADIANCE_HITDIST, @@ -135,10 +151,13 @@ namespace nrd IN_DIFF_DIRECTION_HITDIST, // (Optional) Data must be packed using "NRD_FrontEnd_PackDirectionAndPdf" (RGBA8+) + // These inputs are needed only if PrePassMode::ADVANCED is used. The data can be averaged or weighted in case of many RPP. Encoding / decoding + // can be changed in "NRD_FrontEnd_PackDirectionAndPdf" and "NRD_FrontEnd_UnpackDirectionAndPdf" functions. IN_DIFF_DIRECTION_PDF, IN_SPEC_DIRECTION_PDF, // (Optional) User-provided history confidence in range 0-1, i.e. antilag (R8+) + // Used only if "CommonSettings::isHistoryConfidenceInputsAvailable = true". IN_DIFF_CONFIDENCE, IN_SPEC_CONFIDENCE, @@ -148,21 +167,23 @@ namespace nrd // SIGMA: Data must be packed using "SIGMA_FrontEnd_PackShadow" (5-args) (RGBA8+) IN_SHADOW_TRANSLUCENCY, + // REFERENCE: input + IN_RADIANCE, + + // DELTA_OPTIMIZATION_MV: input + IN_DELTA_PRIMARY_POSW, + IN_DELTA_SECONDARY_POSW, + //============================================================================================================================= // OUTPUTS //============================================================================================================================= // IMPORTANT: These textures can potentially be used as history buffers - // SIGMA: Data must be unpacked using "SIGMA_BackEnd_UnpackShadow" - // .x - shadow, .yzw - translucency (RGBA8+) - // .x - shadow (R8+) - OUT_SHADOW_TRANSLUCENCY, - // REBLUR: Data must be unpacked using "REBLUR_BackEnd_UnpackRadianceAndHitDist" - // .xyz - radiance, .w - normalized hit distance (RGBA16f+) + // .xyz - radiance, .w - normalized hit distance (RGBA16f+) // RELAX: Data must be unpacked using "RELAX_BackEnd_UnpackRadianceAndHitDist" - // .xyz - radiance (R11G11B10f+) + // .xyz - radiance (R11G11B10f+) OUT_DIFF_RADIANCE_HITDIST, OUT_SPEC_RADIANCE_HITDIST, @@ -173,6 +194,25 @@ namespace nrd // REBLUR: .xyz - direction, .w - normalized hit distance (RGBA8+) OUT_DIFF_DIRECTION_HITDIST, + // SIGMA: Data must be unpacked using "SIGMA_BackEnd_UnpackShadow" + // .x - shadow, .yzw - translucency (RGBA8+) + // .x - shadow (R8+) + // Usage: + // shadowData = SIGMA_BackEnd_UnpackShadow( shadowData ); + // float3 finalShadowCommon = lerp( shadowData.yzw, 1.0, shadowData.x ); // or + // float3 finalShadowExotic = shadowData.yzw * shadowData.x; // or + // float3 finalShadowMoreExotic = shadowData.yzw; + OUT_SHADOW_TRANSLUCENCY, + + // REFERENCE: output + OUT_RADIANCE, + + // SPEC_REFLECTION_MV: .xy - 2D screen space virtual motion (RG16f+), MV = previous - current + OUT_SPEC_REFLECTION_MV, + + // DELTA_OPTIMIZATION_MV: .xy - 2D screen space motion (RG16f+), MV = previous - current + OUT_DELTA_MV, + //============================================================================================================================= // POOLS //============================================================================================================================= @@ -305,17 +345,6 @@ namespace nrd bool enableValidation : 1; }; - /* - Texture description - - always texture-read and texture-storage access - - potential descriptors: - - shader read: - - a descriptor for all mips - - a descriptor for first mip only - - a descriptor for some mips with a specific offset - - shader write: - - a descriptor for each mip - */ struct TextureDesc { Format format; @@ -324,6 +353,15 @@ namespace nrd uint16_t mipNum; }; + /* + Requested descriptor variants: + - shader read: + - a descriptor for all mips + - a descriptor for first mip only + - a descriptor for some mips with a specific offset + - shader write: + - a descriptor for each mip + */ struct Resource { DescriptorType stateNeeded; @@ -357,7 +395,7 @@ namespace nrd ComputeShader computeShaderDXBC; ComputeShader computeShaderDXIL; ComputeShader computeShaderSPIRV; - const char* shaderFileName; + const char* shaderFileName; // optional, useful for white-box integration or shaders hot reloading const char* shaderEntryPointName; const DescriptorRangeDesc* descriptorRanges; uint32_t descriptorRangeNum; diff --git a/Include/NRDSettings.h b/Include/NRDSettings.h index 347efb3..6797378 100644 --- a/Include/NRDSettings.h +++ b/Include/NRDSettings.h @@ -10,8 +10,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #pragma once -#define NRD_SETTINGS_VERSION_MAJOR 2 -#define NRD_SETTINGS_VERSION_MINOR 12 +#define NRD_SETTINGS_VERSION_MAJOR 3 +#define NRD_SETTINGS_VERSION_MINOR 0 static_assert (NRD_VERSION_MAJOR == NRD_SETTINGS_VERSION_MAJOR && NRD_VERSION_MINOR == NRD_SETTINGS_VERSION_MINOR, "Please, update all NRD SDK files"); @@ -24,6 +24,7 @@ namespace nrd // BLACK and WHITE modes define cells with VALID data // Checkerboard can be only horizontal // Notes: + // - if checkerboarding is enabled, "mode" defines the orientation of even numbered frames // - all inputs have the same resolution - logical FULL resolution // - noisy input signals (IN_DIFF_XXX / IN_SPEC_XXX) are tightly packed to the LEFT HALF of the texture (the input pixel = 2x1 screen pixel) // - for others the input pixel = 1x1 screen pixel @@ -122,6 +123,10 @@ namespace nrd bool isHistoryConfidenceInputsAvailable = false; }; + // REBLUR + + const uint32_t REBLUR_MAX_HISTORY_FRAME_NUM = 63; + // "Normalized hit distance" = saturate( "hit distance" / f ), where: // f = ( A + viewZ * B ) * lerp( 1.0, C, exp2( D * roughness ^ 2 ) ), see "NRD.hlsl/REBLUR_FrontEnd_GetNormHitDist" struct HitDistanceParameters @@ -142,7 +147,7 @@ namespace nrd // Optional specular lobe trimming = A * smoothstep( B, C, roughness ) // Recommended settings if lobe trimming is needed = { 0.85f, 0.04f, 0.11f } - struct LobeTrimmingParameters + struct SpecularLobeTrimmingParameters { // [0; 1] - main level (0 - GGX dominant direction, 1 - full lobe) float A = 1.0f; @@ -195,44 +200,50 @@ namespace nrd bool enable = true; }; - // REBLUR_DIFFUSE, REBLUR_DIFFUSE_OCCLUSION and REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION - - const uint32_t REBLUR_MAX_HISTORY_FRAME_NUM = 63; - - struct ReblurDiffuseSettings + struct ReblurSettings { + SpecularLobeTrimmingParameters specularLobeTrimmingParameters = {}; HitDistanceParameters hitDistanceParameters = {}; AntilagIntensitySettings antilagIntensitySettings = {}; AntilagHitDistanceSettings antilagHitDistanceSettings = {}; - // Spatial passes do optional material index comparison as: ( material[ center ] & materialMask ) == ( material[ sample ] & materialMask ) - uint32_t materialMask = 0; - - // [0; REBLUR_MAX_HISTORY_FRAME_NUM] + // [0; REBLUR_MAX_HISTORY_FRAME_NUM] - maximum number of linearly accumulated frames ( = FPS * "time of accumulation") uint32_t maxAccumulatedFrameNum = 31; // (pixels) - base (worst case) denoising radius float blurRadius = 30.0f; - // [0; 10] - adaptive radius scale, comes into play if the algorithm detects boiling + // (normalized %) - defines base blur radius shrinking when number of accumulated frames increases + float minConvergedStateBaseRadiusScale = 0.25f; + + // [0; 10] - adaptive radius scale, comes into play if boiling is detected float maxAdaptiveRadiusScale = 5.0f; - // [0; 1] - smaller values make normal weight more strict - float normalWeightStrictness = 1.0f; + // (normalized %) - base fraction of diffuse or specular lobe angle used to drive normal based rejection + float lobeAngleFraction = 0.1f; + + // (normalized %) - base fraction of center roughness used to drive roughness based rejection + float roughnessFraction = 0.05f; - // [0; 1] - stabilizes output, more stabilization improves antilag (clean signals can use lower values) + // [0; 1] - if roughness < this, temporal accumulation becomes responsive and driven by roughness (useful for animated water) + float responsiveAccumulationRoughnessThreshold = 0.0f; + + // (normalized %) - stabilizes output, more stabilization improves antilag (clean signals can use lower values) float stabilizationStrength = 1.0f; - // [0; 1] - aggresiveness of history reconstruction in disoccluded regions (0 - no reconstruction) + // (normalized %) - aggresiveness of history reconstruction in disoccluded regions (0 - no reconstruction) float historyFixStrength = 1.0f; // (normalized %) - represents maximum allowed deviation from local tangent plane float planeDistanceSensitivity = 0.005f; + // (normalized %) - adds a portion of input to the output of spatial passes + float inputMix = 0.0f; + // [0.01; 0.1] - default is tuned for 0.5rpp for the worst case float residualNoiseLevel = 0.03f; - // If checkerboarding is enabled, defines the orientation of even numbered frames + // If not OFF and used for DIFFUSE_SPECULAR, defines diffuse orientation, specular orientation is the opposite CheckerboardMode checkerboardMode = CheckerboardMode::OFF; // Enables a spatial reuse pass before the accumulation pass @@ -241,52 +252,20 @@ namespace nrd // Adds bias in case of badly defined signals, but tries to fight with fireflies bool enableAntiFirefly = false; - // Turns off spatial filtering, more aggressive accumulation + // Turns off spatial filtering, does more aggressive accumulation bool enableReferenceAccumulation = false; - }; - // REBLUR_SPECULAR and REBLUR_SPECULAR_OCCLUSION + // Boosts performance by sacrificing IQ + bool enablePerformanceMode = false; - struct ReblurSpecularSettings - { - HitDistanceParameters hitDistanceParameters = {}; - LobeTrimmingParameters lobeTrimmingParameters = {}; - AntilagIntensitySettings antilagIntensitySettings = {}; - AntilagHitDistanceSettings antilagHitDistanceSettings = {}; - uint32_t materialMask = 0; - uint32_t maxAccumulatedFrameNum = 31; - float blurRadius = 30.0f; - float maxAdaptiveRadiusScale = 5.0f; - float normalWeightStrictness = 1.0f; - float stabilizationStrength = 1.0f; - float historyFixStrength = 1.0f; - float planeDistanceSensitivity = 0.005f; - float residualNoiseLevel = 0.03f; - CheckerboardMode checkerboardMode = CheckerboardMode::OFF; - PrePassMode prePassMode = PrePassMode::SIMPLE; - bool enableAntiFirefly = false; - bool enableReferenceAccumulation = false; + // Spatial passes do optional material index comparison as: ( materialEnabled ? material[ center ] == material[ sample ] : 1 ) + bool enableMaterialTestForDiffuse = false; + bool enableMaterialTestForSpecular = false; }; - // REBLUR_DIFFUSE_SPECULAR and REBLUR_DIFFUSE_SPECULAR_OCCLUSION + // SIGMA - struct ReblurDiffuseSpecularSettings - { - // normalWeightStrictness = min( diffuse, specular ) - // stabilizationStrength = min( diffuse, specular ) - // planeDistanceSensitivity = min( diffuse, specular ) - // residualNoiseLevel = min( diffuse, specular ) - // prePassMode = min( diffuse, specular ) - // enableAntiFirefly = min( diffuse, specular ) - // enableReferenceAccumulation = min( diffuse, specular ) - - ReblurDiffuseSettings diffuse; - ReblurSpecularSettings specular; - }; - - // SIGMA_SHADOW and SIGMA_SHADOW_TRANSLUCENCY - - struct SigmaShadowSettings + struct SigmaSettings { // (normalized %) - represents maximum allowed deviation from local tangent plane float planeDistanceSensitivity = 0.005f; @@ -301,31 +280,39 @@ namespace nrd struct RelaxDiffuseSpecularSettings { - // [0; 100] - radius in pixels (0 disables prepass) - float specularPrepassBlurRadius = 50.0f; - // [0; 100] - radius in pixels (0 disables prepass) float diffusePrepassBlurRadius = 0.0f; + float specularPrepassBlurRadius = 50.0f; - // [0; RELAX_MAX_HISTORY_FRAME_NUM] + // [0; RELAX_MAX_HISTORY_FRAME_NUM] - maximum number of linearly accumulated frames ( = FPS * "time of accumulation") + uint32_t diffuseMaxAccumulatedFrameNum = 31; uint32_t specularMaxAccumulatedFrameNum = 31; - // [0; RELAX_MAX_HISTORY_FRAME_NUM] + // [0; RELAX_MAX_HISTORY_FRAME_NUM] - maximum number of linearly accumulated frames in fast history + uint32_t diffuseMaxFastAccumulatedFrameNum = 8; uint32_t specularMaxFastAccumulatedFrameNum = 8; - // [0; RELAX_MAX_HISTORY_FRAME_NUM] - uint32_t diffuseMaxAccumulatedFrameNum = 31; + // A-trous edge stopping Luminance sensitivity + float diffusePhiLuminance = 2.0f; + float specularPhiLuminance = 1.0f; - // [0; RELAX_MAX_HISTORY_FRAME_NUM] - uint32_t diffuseMaxFastAccumulatedFrameNum = 8; + // (normalized %) - base fraction of diffuse or specular lobe angle used to drive normal based rejection + float diffuseLobeAngleFraction = 0.5f; + float specularLobeAngleFraction = 0.333f; + + // (normalized %) - base fraction of center roughness used to drive roughness based rejection + float roughnessFraction = 0.05f; - // How much variance we inject to specular if reprojection confidence is low + // [0; 1] - shorten diffuse history if "dot(N, Nprev)" is less than "1 - this" to maintain sharpness + float diffuseHistoryRejectionNormalThreshold = 0.0f; + + // (>= 0) - how much variance we inject to specular if reprojection confidence is low float specularVarianceBoost = 1.0f; - // [0; 1], shorten diffuse history if dot (N, previousN) is less than (1 - this value), this maintains sharpness - float rejectDiffuseHistoryNormalThreshold = 0.0f; + // (degrees) - slack for the specular lobe angle used in normal based rejection of specular during A-Trous passes + float specularLobeAngleSlack = 0.3f; - // Normal edge stopper for cross-bilateral sparse filter + // (> 0) - normal edge stopper for cross-bilateral sparse filter float disocclusionFixEdgeStoppingNormalPower = 8.0f; // Maximum radius for sparse bilateral filter, expressed in pixels @@ -337,47 +324,31 @@ namespace nrd // [1; 3] - standard deviation scale of color box for clamping main "slow" history to responsive "fast" history float historyClampingColorBoxSigmaScale = 2.0f; - // History length threshold below which spatial variance estimation will be executed + // (>= 0) - history length threshold below which spatial variance estimation will be executed uint32_t spatialVarianceEstimationHistoryThreshold = 3; // [2; 8] - number of iteration for A-Trous wavelet transform uint32_t atrousIterationNum = 5; - // A-trous edge stopping Luminance sensitivity - float specularPhiLuminance = 2.0f; - - // A-trous edge stopping Luminance sensitivity - float diffusePhiLuminance = 2.0f; - // [0; 1] - A-trous edge stopping Luminance weight minimum float minLuminanceWeight = 0.0f; - // A-trous edge stopping normal sensitivity for diffuse, spatial variance estimation normal sensitivity - float phiNormal = 64.0f; - - // A-trous edge stopping depth threshold + // (normalized %) - A-trous edge stopping depth threshold float depthThreshold = 0.01f; - // Base fraction of the specular lobe angle used in normal based rejection of specular during A-Trous passes; 0.333 works well perceptually - float specularLobeAngleFraction = 0.333f; - - // Slack (in degrees) for the specular lobe angle used in normal based rejection of specular during A-Trous passes - float specularLobeAngleSlack = 0.3f; - // How much we relax roughness based rejection in areas where specular reprojection is low - float roughnessEdgeStoppingRelaxation = 0.3f; - - // How much we relax normal based rejection in areas where specular reprojection is low + float luminanceEdgeStoppingRelaxation = 0.5f; float normalEdgeStoppingRelaxation = 0.3f; + float roughnessEdgeStoppingRelaxation = 0.3f; - // How much we relax luminance based rejection in areas where specular reprojection is low - float luminanceEdgeStoppingRelaxation = 1.0f; - - // If not OFF, diffuse mode equals checkerboard mode set here, and specular mode opposite: WHITE if diffuse is BLACK and vice versa + // If not OFF and used for DIFFUSE_SPECULAR, defines diffuse orientation, specular orientation is the opposite CheckerboardMode checkerboardMode = CheckerboardMode::OFF; + // Firefly suppression + bool enableAntiFirefly = false; + // Skip reprojection test when there is no motion, might improve quality along the edges for static camera with a jitter - bool enableSkipReprojectionTestWithoutMotion = false; + bool enableReprojectionTestSkippingWithoutMotion = false; // Clamp specular virtual history to the current frame neighborhood bool enableSpecularVirtualHistoryClamping = true; @@ -385,23 +356,23 @@ namespace nrd // Roughness based rejection bool enableRoughnessEdgeStopping = true; - // Firefly suppression - bool enableAntiFirefly = false; + // Spatial passes do optional material index comparison as: ( materialEnabled ? material[ center ] == material[ sample ] : 1 ) + bool enableMaterialTestForDiffuse = false; + bool enableMaterialTestForSpecular = false; }; // RELAX_DIFFUSE struct RelaxDiffuseSettings { - // [0; 100] - radius in pixels (0 disables prepass) float prepassBlurRadius = 0.0f; uint32_t diffuseMaxAccumulatedFrameNum = 31; uint32_t diffuseMaxFastAccumulatedFrameNum = 8; - // [0; 1], shorten diffuse history if dot (N, previousN) is less than (1 - this value), this maintains sharpness - float rejectDiffuseHistoryNormalThreshold = 0.0f; - + float diffusePhiLuminance = 2.0f; + float diffuseLobeAngleFraction = 0.5f; + float diffuseHistoryRejectionNormalThreshold = 0.0f; float disocclusionFixEdgeStoppingNormalPower = 8.0f; float disocclusionFixMaxRadius = 14.0f; @@ -411,14 +382,14 @@ namespace nrd uint32_t spatialVarianceEstimationHistoryThreshold = 3; uint32_t atrousIterationNum = 5; - float diffusePhiLuminance = 2.0f; float minLuminanceWeight = 0.0f; - float phiNormal = 64.0f; float depthThreshold = 0.01f; CheckerboardMode checkerboardMode = CheckerboardMode::OFF; - bool enableSkipReprojectionTestWithoutMotion = false; + bool enableAntiFirefly = false; + bool enableReprojectionTestSkippingWithoutMotion = false; + bool enableMaterialTest = false; }; // RELAX_SPECULAR @@ -429,7 +400,14 @@ namespace nrd uint32_t specularMaxAccumulatedFrameNum = 31; uint32_t specularMaxFastAccumulatedFrameNum = 8; + + float specularPhiLuminance = 1.0f; + float diffuseLobeAngleFraction = 0.5f; + float specularLobeAngleFraction = 0.333f; + float roughnessFraction = 0.05f; + float specularVarianceBoost = 1.0f; + float specularLobeAngleSlack = 0.3f; float disocclusionFixEdgeStoppingNormalPower = 8.0f; float disocclusionFixMaxRadius = 14.0f; @@ -439,28 +417,41 @@ namespace nrd uint32_t spatialVarianceEstimationHistoryThreshold = 3; uint32_t atrousIterationNum = 5; - float specularPhiLuminance = 2.0f; float minLuminanceWeight = 0.0f; - float phiNormal = 64.0f; float depthThreshold = 0.01f; - float specularLobeAngleFraction = 0.333f; - float specularLobeAngleSlack = 0.3f; - float roughnessEdgeStoppingRelaxation = 0.3f; + + float luminanceEdgeStoppingRelaxation = 0.5f; float normalEdgeStoppingRelaxation = 0.3f; - float luminanceEdgeStoppingRelaxation = 1.0f; + float roughnessEdgeStoppingRelaxation = 0.3f; CheckerboardMode checkerboardMode = CheckerboardMode::OFF; - bool enableSkipReprojectionTestWithoutMotion = false; + + bool enableAntiFirefly = false; + bool enableReprojectionTestSkippingWithoutMotion = false; bool enableSpecularVirtualHistoryClamping = true; bool enableRoughnessEdgeStopping = true; - bool enableAntiFirefly = false; + bool enableMaterialTest = false; }; // REFERENCE struct ReferenceSettings { - // (> 0) - Maximum number of linearly accumulated frames ( = FPS * "time of accumulation") + // (>= 0) - maximum number of linearly accumulated frames ( = FPS * "time of accumulation") uint32_t maxAccumulatedFrameNum = 3600; }; + + // SPEC_REFLECTION_MV + + struct SpecularReflectionMvSettings + { + float unused; + }; + + // DELTA_OPTIMIZATION_MV + + struct DeltaOptimizationMvSettings + { + float unused; + }; } diff --git a/Integration/NRDIntegration.h b/Integration/NRDIntegration.h index f6db3dc..031a438 100644 --- a/Integration/NRDIntegration.h +++ b/Integration/NRDIntegration.h @@ -20,9 +20,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include #define NRD_INTEGRATION 1 -#define NRD_INTEGRATION_MAJOR 1 -#define NRD_INTEGRATION_MINOR 2 -#define NRD_INTEGRATION_DATE "7 February 2022" +#define NRD_INTEGRATION_MAJOR 2 +#define NRD_INTEGRATION_MINOR 0 +#define NRD_INTEGRATION_DATE "21 March 2022" // Settings #ifndef NRD_INTEGRATION_ASSERT @@ -46,6 +46,14 @@ struct NrdIntegrationTexture constexpr uint32_t NRD_USER_POOL_SIZE = (uint32_t)nrd::ResourceType::MAX_NUM - 2; typedef std::array NrdUserPool; +inline void NrdIntegration_SetResource(NrdUserPool& pool, nrd::ResourceType slot, const NrdIntegrationTexture& texture) +{ + NRD_INTEGRATION_ASSERT( texture.subresourceStates->texture != nullptr, "Invalid texture!" ); + NRD_INTEGRATION_ASSERT( texture.format != nri::Format::UNKNOWN, "Invalid format!" ); + + pool[(size_t)slot] = texture; +} + class NrdIntegration { public: diff --git a/Integration/NRDIntegration.hpp b/Integration/NRDIntegration.hpp index 28f6ab1..4fe5321 100644 --- a/Integration/NRDIntegration.hpp +++ b/Integration/NRDIntegration.hpp @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRDIntegration.h" -static_assert(NRD_VERSION_MAJOR >= 2 && NRD_VERSION_MINOR >= 12, "Unsupported NRD version!"); +static_assert(NRD_VERSION_MAJOR >= 3 && NRD_VERSION_MINOR >= 0, "Unsupported NRD version!"); #if _WIN32 #define NRD_INTEGRATION_ALLOCA _alloca @@ -66,7 +66,7 @@ constexpr std::array g_NRD_NrdToNriFo nri::Format::R9_G9_B9_E5_UFLOAT, }; -constexpr std::array g_NRD_PermanentPoolNames = +constexpr const char* g_NRD_PermanentPoolNames[] = { "IN_MV ", "IN_NORMAL_ROUGHNESS ", @@ -82,14 +82,23 @@ constexpr std::array g_NRD_ "IN_SPEC_CONFIDENCE ", "IN_SHADOWDATA ", "IN_SHADOW_TRANSLUCENCY ", + "IN_RADIANCE ", + "IN_DELTA_PRIMARY_POSW ", + "IN_DELTA_SECONDARY_POSW ", - "OUT_SHADOW_TRANSLUCENCY ", "OUT_DIFF_RADIANCE_HITDIST ", "OUT_SPEC_RADIANCE_HITDIST ", "OUT_DIFF_HITDIST ", "OUT_SPEC_HITDIST ", + "OUT_DIFF_DIRECTION_HITDIST ", + "OUT_SHADOW_TRANSLUCENCY ", + "OUT_RADIANCE ", + "OUT_SPEC_REFLECTION_MV ", + "OUT_DELTA_MV " }; +static_assert( std::size(g_NRD_PermanentPoolNames) == ((size_t)nrd::ResourceType::MAX_NUM) - 2, "g_NRD_PermanentPoolNames is partially initialized!" ); + static inline nri::Format NRD_GetNriFormat(nrd::Format format) { return g_NRD_NrdToNriFormat[(uint32_t)format]; diff --git a/README.md b/README.md index b1bb4b4..99ade8f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# NVIDIA Real-time Denoisers v2.12.2 (NRD) +# NVIDIA Real-time Denoisers v3.0.0 (NRD) ## SAMPLE APP @@ -27,7 +27,7 @@ Supported signal types (modulated irradiance can be used instead of radiance): - Shadows from a local light source (omni, spot) - Shadows from multiple sources (experimental). -*NRD* is distributed as source as well with a “ready-to-use” library (if used in a precompiled form). It can be integrated into any DX12, VULKAN or DX11 engine using 2 methods: +*NRD* is distributed as a source as well with a “ready-to-use” library (if used in a precompiled form). It can be integrated into any DX12, VULKAN or DX11 engine using 2 methods: 1. Native implementation of the *NRD* API using engine capabilities 2. Integration via an abstraction layer. In this case, the engine should expose native Graphics API pointers for certain types of objects. The integration layer, provided as a part of SDK, can be used to simplify this kind of integration. @@ -35,12 +35,12 @@ Supported signal types (modulated irradiance can be used instead of radiance): - Install [*Cmake*](https://cmake.org/download/) 3.15+ - Install on - - Windows: *WindowsSDK*, *VulkanSDK* - - Linux (x86-64): *VulkanSDK* + - Windows: latest *WindowsSDK*, *VulkanSDK* + - Linux (x86-64): latest *VulkanSDK* - Linux (aarch64): find a precompiled binary for [*DXC*](https://github.com/microsoft/DirectXShaderCompiler) or disable shader compilation `NRD_DISABLE_SHADER_COMPILATION=OFF` - Build (variant 1) - using *Git* and *CMake* explicitly - Clone project and init submodules - - Generate and build project using *CMake* + - Generate and build the project using *CMake* - Build (variant 2) - by running scripts: - Run `1-Deploy` - Run `2-Build` @@ -64,7 +64,7 @@ Supported signal types (modulated irradiance can be used instead of radiance): - Compile the solution (*Debug* / *Release* or both, depending on what you want to get in *NRD* package) - Run `3-Prepare NRD SDK` -- Grab generated in the root directory `_NRD_SDK` and `_NRI_SDK` (if needed) folders and use it in your project +- Grab generated in the root directory `_NRD_SDK` and `_NRI_SDK` (if needed) folders and use them in your project ## INTEGRATION VARIANTS @@ -87,7 +87,7 @@ If Graphics API's native pointers are retrievable from the RHI, the standard *NR *NRI* and *NRD* are ready-to-use products. The application must expose native pointers only for Device, Resource and CommandList entities (no SRVs and UAVs - they are not needed, everything will be created internally). Native resource pointers are needed only for the denoiser inputs and outputs (all intermediate textures will be handled internally). Descriptor heap will be changed to an internal one, so the application needs to bind its original descriptor heap after invoking the denoiser. -In rare cases, when the integration via engine’s RHI is not possible and the integration using native pointers is complicated, a "DoDenoising" call can be added explicitly to the application-side RHI. It helps to avoid increasing code entropy. +In rare cases, when the integration via the engine’s RHI is not possible and the integration using native pointers is complicated, a "DoDenoising" call can be added explicitly to the application-side RHI. It helps to avoid increasing code entropy. The pseudo code below demonstrates how *NRD Integration* and *NRI* can be used to wrap native Graphics API pointers into NRI objects to establish connection between the application and NRD: @@ -261,79 +261,59 @@ NOTE: `XXX` below is a replacement for a denoiser you choose from *REBLUR*, *REL The following textures can be requested as inputs or outputs for a method. Required resources are specified near a method declaration in `Method`. -### NRD INPUTS +### NRD INPUTS & OUTPUTS -* **IN\_MV** - primary surface motion (a common part of the g-buffer). MVs must be non-jittered, `old = new + MV`. Supported motion: - - 3D world space motion (recommended). Camera motion should not be included (it's already in the matrices). In other words, if there are no moving objects all motion vectors = 0. The alpha channel is unused and can be used by the app - - 2D screen space motion -Motion vector scaling can be provided via `CommonSettings::motionVectorScale`. - -* **IN\_NORMAL\_ROUGHNESS** - `.xyz` - primary surface normal in world space, `.w` - and roughness. Normal and roughness encoding can be controlled by the following macros located in `NRD.hlsli`: - - _NRD\_USE\_SQRT\_LINEAR\_ROUGHNESS_ = 0 - roughness is `linearRoughness = sqrt( mathematicalRoughness )` - - _NRD\_USE\_SQRT\_LINEAR\_ROUGHNESS_ = 1 - roughness is `sqrt( linearRoughness )` - - _NRD\_NORMAL\_ENCODING = NRD\_NORMAL\_ENCODING\_UNORM8 or NRD\_NORMAL\_ENCODING\_UNORM16_ - normal unpacking is `normalize( .xyz * 2 - 1 )` - - _NRD\_NORMAL\_ENCODING = NRD\_NORMAL\_ENCODING\_OCT10_ - normals are packed using octahedron encoding. This variant allows to pass optional `materialID` - -NRD computes local curvature using provided normals. Less accurate normals can lead to banding in curvature and local flatness. RGBA8 normals is a good baseline, but R10G10B10A10 oct-packed normals improve curvature calculations and specular tracking in the result. - -Spatial filtering can be made `materialID` aware by enabling `NRD_USE_MATERIAL_ID_AWARE_FILTERING`. In this case material ID will be taken from `.w` channel by default. The decoding can be changed in `NRD_FrontEnd_UnpackNormalAndRoughness` function. - -* **IN\_VIEWZ** - `.x` - view-space Z coordinates of the primary surface (positive and negative values are supported). - -* **IN\_DIFF\_RADIANCE\_HITDIST** and **IN\_SPEC\_RADIANCE\_HITDIST** - noisy radiance and weighted sum (using `NRD_GetCorrectedHitDist`) of hit distances along a path, excluding primary hit distance. *REBLUR* works with normalized hit distances. It's recommended to use `REBLUR_FrontEnd_GetNormHitDist` for hit distance normalization. Normalization parameters should be passed into *NRD* as `HitDistanceParameters` for diffuse and specular separately for internal hit distance denormalization. - -* **IN\_DIFF\_DIRECTION\_HITDIST** - same as **IN\_DIFF\_RADIANCE\_HITDIST**, but with direction instead of radiance. - -* **IN\_DIFF\_HITDIST** and **IN\_SPEC\_HITDIST** - (for Ambient Occlusion and Specular Occlusion denoisers) same hit distance requirements as for the previous inputs. +Commons inputs: -* **IN\_DIFF\_DIRECTION\_PDF** and **IN\_SPEC\_DIRECTION\_PDF** - these inputs are needed only if `PrePassMode::ADVANCED` is used. `.xyz` - ray direction, `.w` - ray probability (PDF). The data can be averaged or weighted in case of many RPP. Encoding / decoding can be changed in `NRD_FrontEnd_PackDirectionAndPdf` / `NRD_FrontEnd_UnpackDirectionAndPdf` functions in `NRD.hlsli`. +* **IN\_MV** - non-jittered primary surface motion (`old = new + MV`) -* **IN\_DIFF\_CONFIDENCE** and **IN\_SPEC\_CONFIDENCE** - there inputs needed only if `CommonSettings::isHistoryConfidenceInputsAvailable = true`. `.x` - history confidence in range 0-1. - -* **IN\_SHADOWDATA** and **IN\_SHADOW\_TRANSLUCENCY** - *SIGMA* inputs, the latter is needed only for *SIGMA_SHADOW_TRANSLUCENCY* - -(See `NRDDescs.h` for more details) - -### NRD OUTPUTS + Supported variants: + - 3D world space motion (recommended) - camera motion should not be included (it's already in the matrices). In other words, if there are no moving objects all motion vectors = 0. The `.w` channel is unused and can be used by the app; + - 2D screen space motion -NOTE: In some denoisers these textures can potentially be used as history buffers! + Motion vector scaling can be provided via `CommonSettings::motionVectorScale`. -* **OUT\_DIFF\_RADIANCE\_HITDIST** - `.xyz` - denoised diffuse radiance, `.w` - denoised normalized hit distance, i.e. AO (*REBLUR* only) +* **IN\_NORMAL\_ROUGHNESS** - primary surface normal in world space and *linear* roughness -* **OUT\_SPEC\_RADIANCE\_HITDIST** - `.xyz` - denoised specular radiance, `.w` - denoised normalized hit distance, i.e. SO (*REBLUR* only) + Normal encoding can be controlled by the following macros located in `NRD.hlsli`: + - _NRD\_NORMAL\_ENCODING = NRD\_NORMAL\_ENCODING\_UNORM_ - `.xyz` - normal (decoding is `normalize( .xyz * 2 - 1 )`), `.w` - roughness + - _NRD\_NORMAL\_ENCODING = NRD\_NORMAL\_ENCODING\_OCT_ - `.xy` - normal (octahedron decoding). `.z` - roughness, `.w` - optional material ID (only 2 lower bits are used). -* **OUT\_DIFF\_HITDIST** - `.x` - denoised normalized hit distance, i.e. AO + Roughness encoding can be controlled by the following macros located in `NRD.hlsli`: + - _NRD\_USE\_SQRT\_LINEAR\_ROUGHNESS_ = 0 - roughness decoding is `m = alpha = roughness ^ 2` + - _NRD\_USE\_SQRT\_LINEAR\_ROUGHNESS_ = 1 - roughness decoding is `m = alpha = roughness ^ 4` + - _NRD\_NORMAL\_ENCODING = NRD\_NORMAL\_ENCODING\_UNORM_ - `.xyz` - normal (decoding is `normalize( .xyz * 2 - 1 )`), `.w` - roughness + - _NRD\_NORMAL\_ENCODING = NRD\_NORMAL\_ENCODING\_OCT_ - `.xy` - normal (octahedron decoding). `.z` - roughness, `.w` - optional material ID (only 2 lower bits are used). -* **OUT\_SPEC\_HITDIST** - `.x` - denoised normalized hit distance, i.e. SO + NRD computes local curvature using provided normals. Less accurate normals can lead to banding in curvature and local flatness. RGBA8 normals is a good baseline, but R10G10B10A10 oct-packed normals improve curvature calculations and specular tracking in the result. -* **OUT\_SHADOW\_TRANSLUCENCY** - `.x` - denoised shadow, `.yzw` - denoised translucency (for *SIGMA_SHADOW_TRANSCLUCENCY*) . Must be unpacked using `XXX_BackEnd_UnpackShadow` function from `NRD.hlsli`. Usage: + If `materialID` is provided, NRD diffuse and specular denoisers won't mix up surfaces with different material IDs. - ```cpp - shadowData = SIGMA_BackEnd_UnpackShadow( shadowData ); +* **IN\_VIEWZ** - `.x` - view-space Z coordinate of the primary surface - float3 finalShadowCommon = lerp( shadowData.yzw, 1.0, shadowData.x ); // or - float3 finalShadowExotic = shadowData.yzw * shadowData.x; // or - float3 finalShadowMoreExotic = shadowData.yzw; - ``` + Positive and negative values are supported. -(See `NRDDescs.h` for more details) +See `NRDDescs.h` for more details and descriptions of other inputs and outputs. ## INTERACTION WITH PATH TRACERS -Notes: -- read *INTEGRATION GUIDE, RECOMMENDATIONS AND GOOD PRACTICES* section (below) -- path length MUST be separated into diffuse path and specular path. To familiarize yourself with required data, run the NRD sample and look at ambient / specular occlusion outputs (it's denoised hit distance) -- do not pass *sum of lengths of all segments* as *hit distance*. Use `NRD_GetCorrectedHitDist` instead (a suitable baseline is to use hit distance of the first bounce only) -- hit distance (path length) MUST not include primary hit distance -- for *REBLUR* normalized hit distances should be averaged in case of many paths sampling (not real distances) -- noisy radiance inputs MUST not include material information at primary hits, use material de-modulation to solve this (see sample) -- Probabilistic sampling for 2nd+ bounces is absolutely acceptable, but when casting rays from the primary hit position it's better cast 2 paths - one for diffuse and another one for specular (it also solves the problem of hit distance separation) +- Path length must be separated into diffuse and specular paths +- Do not pass *sum of lengths of all segments* as `hitT`. Use `NRD_GetCorrectedHitDist` instead (a suitable baseline is to use hit distance for the first bounce only) +- `hitT`, passed to NRD, must not include primary hit distance +- Noisy radiance inputs must not include material information at primary hits, i.e. material de-modulation is needed +- Noise in provided hit distances must follow diffuse or specular lobe. It implies the following: + - `hitT` for `roughness = 0` must be clean + - Probability based diffuse / specular split at the origin of the path makes `hitT` barely usable for driving denoising in case of 1rpp for the following reasons: + - `hitT / pdf` leads to wrong values and, as the result, wrong specular tracking + - `hitT = 0` (if probability requirements are not met) breaks tracking and denoising guiding +- Probabilistic sampling for 2nd+ bounces is absolutely acceptable +- NRD sample is a good start to familiarize yourself with input requirements and best practices ## INTEGRATION GUIDE, RECOMMENDATIONS AND GOOD PRACTICES Denoising is not a panacea or miracle. Denoising works best with ray tracing results produced by a suitable form of importance sampling. Additionally, *NRD* has its own restrictions. The following suggestions should help to achieve best image quality: -**[NRD]** NRD API has been designed to support integration into native VULKAN apps. If the RHI, you work with, is DX11-like, not all provided data will be needed. +**[NRD]** The NRD API has been designed to support integration into native VULKAN apps. If the RHI you work with is DX11-like, not all provided data will be needed. **[NRD]** Read all comments in `NRDDescs.h`, `NRDSettings.h` and `NRD.hlsli`. @@ -341,7 +321,7 @@ Denoising is not a panacea or miracle. Denoising works best with ray tracing res **[NRD]** When upgrading to the latest version keep an eye on `ResourceType` enumeration. The order of the input slots can be changed or something can be added, you need to adjust the inputs accordingly to match the mapping. -**[NRD]** All pixels in floating point textures should be INF / NAN free to avoid propagation, because such values are used in weight calculations and accumulation of weigted sum. +**[NRD]** All pixels in floating point textures should be INF / NAN free to avoid propagation, because such values are used in weight calculations and accumulation of a weighted sum. **[NRD]** All NRD denoisers work with positive inputs. @@ -349,7 +329,7 @@ Denoising is not a panacea or miracle. Denoising works best with ray tracing res **[NRD]** *NRD* works with non-jittered matrices. -**[NRD]** The library doesn’t care about motion vectors much. For the first time pass all MVs set to 0 (you can use `CommonSettings::motionVectorScale = {0}` for this) and set `CommonSettings::isMotionVectorInWorldSpace = true`, *NRD* can track camera motion internally. Enable application provided MVs after getting denoising working on static objects. +**[NRD]** *NRD* can track camera motion internally. For the first time pass all MVs set to 0 (you can use `CommonSettings::motionVectorScale = {0}` for this) and set `CommonSettings::isMotionVectorInWorldSpace = true`, it will allow you to simplify the initial integration. Enable application provided MVs after getting denoising working on static objects. **[NRD]** Using of 2D MVs can lead to massive history reset on fast moving objects, because 2D motion provides information only about pixel screen position but not about real 3D world position. Consider using 3D MVs instead. @@ -360,7 +340,7 @@ Denoising is not a panacea or miracle. Denoising works best with ray tracing res **[NRD]** *NRD* has been designed to work with pure radiance coming from a particular direction. This means that data in the form "something / probability" should be avoided because overall entropy of the input signal will be increased (but it doesn't mean that denoising won't work). Additionally, it means that primary materials needs to be decoupled from the input signal, i.e. primary BRDF should be applied **after** denoising: // Diffuse - Denoising( diffuseRadiance * albedo ) → NRD( diffuseRadiance ) * albedo + Denoising( diffuseRadiance * albedo ) → NRD( diffuseRadiance / albedo ) * albedo // Specular float3 envBRDF = EnvBRDF( Rf0, N, V, roughness ); @@ -368,30 +348,32 @@ Denoising is not a panacea or miracle. Denoising works best with ray tracing res It's worth noting that *RELAX* has a better capability to preserve details in this case due to usage of A-trous filter with luminance stoppers. -**[NRD]** Denoising logic is driven by provided hit distances. For REBLUR diffuse-only denoiser only hit distance for the 1st bounce is needed. For specular denoisers just a length of the path can be used, excluding distance to the primary hit. But this solution is suboptimal, better use `NRD_GetCorrectedHitDist` from `NRD.hlsli`. +**[NRD]** Denoising logic is driven by provided hit distances. For indirect lighting denoising passing hit distance for the 1st bounce only is a good baseline. For direct lighting a distance to an occluder or a light source is needed. Primary hit distance must be excluded in any case. Read notes for the `NRD_GetCorrectedHitDist` function from `NRD.hlsli`. -**[NRD]** For better IQ HDR inputs need to be in a sane range (0 - 10 / 100). +**[NRD]** For better image quality HDR inputs need to be in a sane range (0 - 10 / 100). -**[NRD]** Denoisers (currently only *REBLUR*) can perform optional color compression in spatial filtering passes to improve overall IQ by sacrificing energy correctness a bit. Color compression mode is roughness based and can be tuned (or turned off) in `NRD.hlsli`. +**[NRD]** Denoisers can perform optional color compression in spatial filtering passes to improve overall IQ by sacrificing energy correctness a bit. Color compression mode is roughness-based and can be tuned (or turned off) in `NRD.hlsli`. -**[NRD]** Passing pre-exposured colors (i.e. `color * exposure`) is not recommended, because a significant momentary change in exposure is hard to react in this case. +**[NRD]** Passing pre-exposured colors (i.e. `color * exposure`) is not recommended, because a significant momentary change in exposure is hard to react to in this case. **[NRD]** Importance sampling is recommended to achieve good results in case of complex lighting environments. Consider using: - Cosine distribution for diffuse from non-local light sources; - VNDF sampling for specular; - Custom importance sampling for local light sources (*RTXDI*). -**[NRD]** Hit distances should come from an importance sampling method. But if in case of *REBLUR*, for example, denoising of AO and a custom direct / indirect lighting is needed, AO can come from cos-weighted sampling and radiance can be computed by a different method in a tradeoff of IQ. +**[NRD]** Hit distances should come from an importance sampling method. But if denoising of AO/SO is needed, AO/SO can come from cos-weighted sampling in a tradeoff of IQ. -**[NRD]** Low discrepancy sampling helps to have more stable output in 0.5-1 rpp mode. It's a must for REBLUR-based Ambient and Specular Occlusion denoisers and SIGMA. You can experiment with *Blue noise* setting in the sample. +**[NRD]** Low discrepancy sampling helps to have more stable output in 0.5-1 rpp mode. It's a must for REBLUR-based Ambient and Specular Occlusion denoisers and SIGMA. -**[NRD]** It's recommended to set `CommonSettings::accumulationMode` to `RESET` for a single frame, if history reset is needed. If history buffers are recreated or contain garbage, it's recommended to use `CLEAR_AND_RESET` for a single frame. `CLEAR_AND_RESET` is not free because clearing is done in a compute shader. Render target clears on the application side should be prioritized over this solution. +**[NRD]** It's recommended to set `CommonSettings::accumulationMode` to `RESET` for a single frame, if a history reset is needed. If history buffers are recreated or contain garbage, it's recommended to use `CLEAR_AND_RESET` for a single frame. `CLEAR_AND_RESET` is not free because clearing is done in a compute shader. Render target clears on the application side should be prioritized over this solution. **[NRD]** Functions `XXX_FrontEnd_PackRadianceAndHitDist` perform optional NAN / INF clearing of the input signal. There is a boolean to skip these checks. **[NRD]** If there are areas (besides sky), which don't require denoising (for example, casting a specular ray only if roughness is less than some threshold), providing `viewZ > CommonSettings::denoisingRange` in **IN\_VIEWZ** texture for such pixels will effectively skip denoising. Additionally, the data in such areas won't contribute to the final result. -**[NRD]** If a denoiser performs spatial filtering before accumulation, the behavior can be controlled via `PrePassMode` enumeration. `ADVANCED` mode offers better quality but requires valid data in `IN_DIFF_DIRECTION_PDF` and / or `IN_SPEC_DIRECTION_PDF` inputs (see sample for more details). +**[NRD]** If there are areas (besides sky), which don't require denoising (for example, skipped diffuse rays for true metals). `materialID` and `materialMask` can be used to drive spatial passes. + +**[NRD]** If a denoiser performs spatial filtering before accumulation, its behavior can be controlled via `PrePassMode` enumeration. `ADVANCED` mode offers better quality but requires valid data in `IN_DIFF_DIRECTION_PDF` and / or `IN_SPEC_DIRECTION_PDF` inputs (see sample for more details). **[NRD]** Maximum number of accumulated frames can be FPS dependent. The following formula can be used on the application side: ``` @@ -400,23 +382,27 @@ maxAccumulatedFrameNum = accumulationPeriodInSeconds * FPS **[NRD INTEGRATION]** Ensure that all slots in `NrdUserPool` are filled. Not referenced slots can be set to 0. -**[REBLUR]** In case of *REBLUR* ensure that `enableReferenceAccumulation = true` works properly first. It's not mandatory needed, but will help to simplify debugging of potential issues by implicitly disabling spatial filtering entirely. +**[REBLUR]** In case of *REBLUR* ensure that `enableReferenceAccumulation = true` works properly first. It's not mandatory, but will help to simplify debugging of potential issues by implicitly disabling spatial filtering entirely. + +**[REBLUR]** If more performance is needed, consider using `enablePerformanceMode = true`. -**[REBLUR]** For diffuse and specular *REBLUR* expects hit distance input in a normalized form. To avoid mismatching `REBLUR_FrontEnd_GetNormHitDist` should be used for normalization. Some tweaking can be needed here, but in most cases normalization to the default `HitDistanceParameters` works well. *REBLUR* outputs denoised normalized hit distance, which can be used by the application as ambient or specular occlusion (AO & SO) (see unpacking functions from `NRD.hlsli`). +**[REBLUR]** For diffuse and specular *REBLUR* expects hit distance input in a normalized form. To avoid mismatching, `REBLUR_FrontEnd_GetNormHitDist` should be used for normalization. Some tweaking can be needed here, but in most cases normalization to the default `HitDistanceParameters` works well. *REBLUR* outputs denoised normalized hit distance, which can be used by the application as ambient or specular occlusion (AO & SO) (see unpacking functions from `NRD.hlsli`). -**[REBLUR]** *REBLUR* handles specular lobe trimming, trying to reconstruct trimmed signal. Similarly to hit distance normalization, *REBLUR* needs to be aware about trimming parameters. If this feature is used in a ray tracer, `LobeTrimmingParameters` must be passed into *REBLUR*. To avoid code duplication `NRD_GetTrimmingFactor` can be used in a shader code on the application side. +**[REBLUR]** *REBLUR* handles specular lobe trimming, trying to reconstruct trimmed signals. Similarly to hit distance normalization, *REBLUR* needs to be aware about trimming parameters. If this feature is used in a ray tracer, `SpecularLobeTrimmingParameters` must be passed into *REBLUR*. To avoid code duplication, `NRD_GetTrimmingFactor` can be used in a shader code on the application side. **[REBLUR]** Intensity antilag parameters need to be carefully tuned. The defaults are good but `AntilagIntensitySettings::sensitivityToDarkness` needs to be tuned for a given HDR range. Initial integration should work with intensity antilag turned off. +**[REBLUR]** Even if antilag is off, it's recommended to tune `AntilagIntensitySettings::sensitivityToDarkness`, because it is used for error estimation. + **[REBLUR]** Using "blue" noise can help to minimize shimmering in the output of AO/SO-only denoisers. -**[RELAX]** *RELAX* works incredibly well with signals produced by *RTXDI* or very clean high RPP signals. The Sweet Home of *RELAX* is *RTXDI* sample. Please, consider getting familiar with this application. +**[RELAX]** *RELAX* works well with signals produced by *RTXDI* or very clean high RPP signals. The Sweet Home of *RELAX* is *RTXDI* sample. Please, consider getting familiar with this application. **[RELAX]** The number of accumulated frames in fast history needs to be carefully tuned to avoid introducing significant bias and dirt. Initial integration should be done by setting `maxFastAccumulatedFrameNum` to `maxAccumulatedFrameNum`. -**[SIGMA]** Using "blue" noise can help to avoid shadow shimmering, it works best if the pattern is static on the screen. Additionally, `blurRadiusScale` can be set to 2-4 to mitigate such problems in complicated cases. +**[SIGMA]** Using "blue" noise can help to avoid shadow shimmering, it works best if the pattern is static on the screen. Additionally, `blurRadiusScale` can be set to `2-4` to mitigate such problems in complicated cases. -**[SIGMA]** *SIGMA_TRANSLUCENT_SHADOW* can be used for denoising of shadows from multiple light sources: +**[SIGMA]** *SIGMA_TRANSLUCENT_SHADOW* can be used for shadow denoising from multiple light sources: *L[i]* - unshadowed analytical lighting from a single light source (**not noisy**)
*S[i]* - stochastically sampled light visibility for *L[i]* (**noisy**)
@@ -462,7 +448,7 @@ Is this a biased solution? If spatial filtering is off - no, because we just reo **This solution is limited** and hard to use: - obviously, can be used "as is" if shadows don't overlap (*weight* = 1) - if shadows overlap, a separate pass is needed to analyze noisy input and classify pixels as *umbra* - *penumbra* (and optionally *empty space*). Raster shadow maps can be used for this if available -- it is not recommended to mix 1 cd and 100000 cd lights, since FP32 texture will be needed for weighted sum. +- it is not recommended to mix 1 cd and 100000 cd lights, since FP32 texture will be needed for a weighted sum. In this case, it's better to process the sun and other bright light sources separately. ## HOW TO REPORT ISSUES @@ -472,7 +458,7 @@ NRD sample has *TESTS* section in the bottom of the UI (`--testMode` required), - if reproducible - add a test (by pressing `Add` button) - describe the issue and steps to reproduce - - attach depending on selected scene `.bin` file from `_Data\Tests` folder + - attach depending on the selected scene `.bin` file from the `_Data\Tests` folder - if not - verify the integration - If nothing helps diff --git a/Resources/Version.h b/Resources/Version.h index d054a41..1cb8f65 100644 --- a/Resources/Version.h +++ b/Resources/Version.h @@ -21,9 +21,9 @@ Versioning rules: - don't forget to update requirements in NRDIntegration */ -#define VERSION_MAJOR 2 -#define VERSION_MINOR 12 -#define VERSION_BUILD 2 +#define VERSION_MAJOR 3 +#define VERSION_MINOR 0 +#define VERSION_BUILD 0 #define VERSION_REVISION 0 #define VERSION_STRING STR(VERSION_MAJOR.VERSION_MINOR.VERSION_BUILD.VERSION_REVISION) diff --git a/ShaderCompilation.cmake b/ShaderCompilation.cmake index fccd812..9026be6 100644 --- a/ShaderCompilation.cmake +++ b/ShaderCompilation.cmake @@ -100,7 +100,7 @@ macro(list_hlsl_shaders NRD_HLSL_FILES NRD_HEADER_FILES NRD_SHADER_FILES) if (NOT "${FXC_PROFILE}" STREQUAL "" AND NOT "${NRD_FXC_PATH}" STREQUAL "") add_custom_command( OUTPUT ${OUTPUT_PATH_DXBC} ${OUTPUT_PATH_DXBC}.h - COMMAND ${NRD_FXC_PATH} /nologo /E main -DCOMPILER_FXC=1 /T ${FXC_PROFILE} + COMMAND ${NRD_FXC_PATH} /nologo /E main -DNRD_COMPILER_FXC=1 /T ${FXC_PROFILE} /I "${NRD_HEADER_INCLUDE_PATH}" /I "${NRD_SHADER_INCLUDE_PATH}" /I "${NRD_MATHLIB_INCLUDE_PATH}" /I "Include" ${FILE_NAME} /Vn g_${BYTECODE_ARRAY_NAME}_dxbc /Fh ${OUTPUT_PATH_DXBC}.h /Fo ${OUTPUT_PATH_DXBC} /WX /O3 /all_resources_bound @@ -115,7 +115,7 @@ macro(list_hlsl_shaders NRD_HLSL_FILES NRD_HEADER_FILES NRD_SHADER_FILES) if (NOT "${DXC_PROFILE}" STREQUAL "" AND NOT "${NRD_DXC_PATH}" STREQUAL "") add_custom_command( OUTPUT ${OUTPUT_PATH_DXIL} ${OUTPUT_PATH_DXIL}.h - COMMAND ${NRD_DXC_PATH} -E main -DCOMPILER_DXC=1 -T ${DXC_PROFILE} + COMMAND ${NRD_DXC_PATH} -E main -DNRD_COMPILER_DXC=1 -T ${DXC_PROFILE} -I "${NRD_HEADER_INCLUDE_PATH}" -I "${NRD_SHADER_INCLUDE_PATH}" -I "${NRD_MATHLIB_INCLUDE_PATH}" -I "Include" ${FILE_NAME} -Vn g_${BYTECODE_ARRAY_NAME}_dxil -Fh ${OUTPUT_PATH_DXIL}.h -Fo ${OUTPUT_PATH_DXIL} -WX -O3 -enable-16bit-types -all_resources_bound @@ -130,7 +130,7 @@ macro(list_hlsl_shaders NRD_HLSL_FILES NRD_HEADER_FILES NRD_SHADER_FILES) if (NOT "${DXC_PROFILE}" STREQUAL "" AND NOT "${NRD_DXC_SPIRV_PATH}" STREQUAL "") add_custom_command( OUTPUT ${OUTPUT_PATH_SPIRV} ${OUTPUT_PATH_SPIRV}.h - COMMAND ${NRD_DXC_SPIRV_PATH} -E main -DCOMPILER_DXC=1 -DVULKAN=1 -T ${DXC_PROFILE} + COMMAND ${NRD_DXC_SPIRV_PATH} -E main -DNRD_COMPILER_DXC=1 -DVULKAN=1 -T ${DXC_PROFILE} -I "${NRD_HEADER_INCLUDE_PATH}" -I "${NRD_SHADER_INCLUDE_PATH}" -I "${NRD_MATHLIB_INCLUDE_PATH}" -I "Include" ${FILE_NAME} -spirv -Vn g_${BYTECODE_ARRAY_NAME}_spirv -Fh ${OUTPUT_PATH_SPIRV}.h -Fo ${OUTPUT_PATH_SPIRV} ${NRD_DXC_VK_SHIFTS} -WX -O3 -enable-16bit-types -all_resources_bound diff --git a/Source/DenoiserImpl.cpp b/Source/DenoiserImpl.cpp index cdec949..0a0373b 100644 --- a/Source/DenoiserImpl.cpp +++ b/Source/DenoiserImpl.cpp @@ -131,47 +131,47 @@ nrd::Result nrd::DenoiserImpl::Create(const nrd::DenoiserCreationDesc& denoiserC if (methodDesc.method == Method::REBLUR_DIFFUSE) { - methodData.settings.diffuseReblur = ReblurDiffuseSettings(); + methodData.settings.reblur = ReblurSettings(); methodData.settingsSize = AddMethod_ReblurDiffuse(w, h); } else if (methodDesc.method == Method::REBLUR_DIFFUSE_OCCLUSION) { - methodData.settings.diffuseReblur = ReblurDiffuseSettings(); + methodData.settings.reblur = ReblurSettings(); methodData.settingsSize = AddMethod_ReblurDiffuseOcclusion(w, h); } else if (methodDesc.method == Method::REBLUR_SPECULAR) { - methodData.settings.specularReblur = ReblurSpecularSettings(); + methodData.settings.reblur = ReblurSettings(); methodData.settingsSize = AddMethod_ReblurSpecular(w, h); } else if (methodDesc.method == Method::REBLUR_SPECULAR_OCCLUSION) { - methodData.settings.specularReblur = ReblurSpecularSettings(); + methodData.settings.reblur = ReblurSettings(); methodData.settingsSize = AddMethod_ReblurSpecularOcclusion(w, h); } else if (methodDesc.method == Method::REBLUR_DIFFUSE_SPECULAR) { - methodData.settings.diffuseSpecularReblur = ReblurDiffuseSpecularSettings(); + methodData.settings.reblur = ReblurSettings(); methodData.settingsSize = AddMethod_ReblurDiffuseSpecular(w, h); } else if (methodDesc.method == Method::REBLUR_DIFFUSE_SPECULAR_OCCLUSION) { - methodData.settings.diffuseSpecularReblur = ReblurDiffuseSpecularSettings(); + methodData.settings.reblur = ReblurSettings(); methodData.settingsSize = AddMethod_ReblurDiffuseSpecularOcclusion(w, h); } else if (methodDesc.method == Method::REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION) { - methodData.settings.diffuseReblur = ReblurDiffuseSettings(); + methodData.settings.reblur = ReblurSettings(); methodData.settingsSize = AddMethod_ReblurDiffuseDirectionalOcclusion(w, h); } else if (methodDesc.method == Method::SIGMA_SHADOW) { - methodData.settings.shadowSigma = SigmaShadowSettings(); + methodData.settings.sigma = SigmaSettings(); methodData.settingsSize = AddMethod_SigmaShadow(w, h); } else if (methodDesc.method == Method::SIGMA_SHADOW_TRANSLUCENCY) { - methodData.settings.shadowSigma = SigmaShadowSettings(); + methodData.settings.sigma = SigmaSettings(); methodData.settingsSize = AddMethod_SigmaShadowTranslucency(w, h); } else if (methodDesc.method == Method::RELAX_DIFFUSE) @@ -194,6 +194,16 @@ nrd::Result nrd::DenoiserImpl::Create(const nrd::DenoiserCreationDesc& denoiserC methodData.settings.reference = ReferenceSettings(); methodData.settingsSize = AddMethod_Reference(w, h); } + else if (methodDesc.method == Method::SPEC_REFLECTION_MV) + { + methodData.settings.specularReflectionMv = SpecularReflectionMvSettings(); + methodData.settingsSize = AddMethod_SpecularReflectionMv(); + } + else if (methodDesc.method == Method::DELTA_OPTIMIZATION_MV) + { + methodData.settings.deltaOptimizationMv = DeltaOptimizationMvSettings(); + methodData.settingsSize = AddMethod_DeltaOptimizationMv(w, h); + } else return Result::INVALID_ARGUMENT; @@ -287,19 +297,19 @@ nrd::Result nrd::DenoiserImpl::GetComputeDispatches(const nrd::CommonSettings& c UpdatePingPong(methodData); if (methodData.desc.method == Method::REBLUR_DIFFUSE) - UpdateMethod_ReblurDiffuse(methodData); + UpdateMethod_Reblur(methodData); else if (methodData.desc.method == Method::REBLUR_DIFFUSE_OCCLUSION) - UpdateMethod_ReblurDiffuseOcclusion(methodData); + UpdateMethod_ReblurOcclusion(methodData); else if (methodData.desc.method == Method::REBLUR_SPECULAR) - UpdateMethod_ReblurSpecular(methodData); + UpdateMethod_Reblur(methodData); else if (methodData.desc.method == Method::REBLUR_SPECULAR_OCCLUSION) - UpdateMethod_ReblurSpecularOcclusion(methodData); + UpdateMethod_ReblurOcclusion(methodData); else if (methodData.desc.method == Method::REBLUR_DIFFUSE_SPECULAR) - UpdateMethod_ReblurDiffuseSpecular(methodData); + UpdateMethod_Reblur(methodData); else if (methodData.desc.method == Method::REBLUR_DIFFUSE_SPECULAR_OCCLUSION) - UpdateMethod_ReblurDiffuseSpecularOcclusion(methodData); + UpdateMethod_ReblurOcclusion(methodData); else if (methodData.desc.method == Method::REBLUR_DIFFUSE_DIRECTIONAL_OCCLUSION) - UpdateMethod_ReblurDiffuseDirectionalOcclusion(methodData); + UpdateMethod_Reblur(methodData); else if (methodData.desc.method == Method::SIGMA_SHADOW) UpdateMethod_SigmaShadow(methodData); else if (methodData.desc.method == Method::SIGMA_SHADOW_TRANSLUCENCY) @@ -312,6 +322,10 @@ nrd::Result nrd::DenoiserImpl::GetComputeDispatches(const nrd::CommonSettings& c UpdateMethod_RelaxDiffuseSpecular(methodData); else if (methodData.desc.method == Method::REFERENCE) UpdateMethod_Reference(methodData); + else if (methodData.desc.method == Method::SPEC_REFLECTION_MV) + UpdateMethod_SpecularReflectionMv(methodData); + else if (methodData.desc.method == Method::DELTA_OPTIMIZATION_MV) + UpdateMethod_DeltaOptimizationMv(methodData); } dispatchDescs = m_ActiveDispatches.data(); @@ -399,7 +413,18 @@ void nrd::DenoiserImpl::PrepareDesc() // Since now all std::vectors become "locked" (no reallocations) } -void nrd::DenoiserImpl::AddComputeDispatchDesc(uint8_t workgroupDimX, uint8_t workgroupDimY, uint16_t downsampleFactor, uint32_t constantBufferDataSize, uint32_t maxRepeatNum, const char* shaderFileName, const nrd::ComputeShader& dxbc, const nrd::ComputeShader& dxil, const nrd::ComputeShader& spirv) +void nrd::DenoiserImpl::AddComputeDispatchDesc +( + uint8_t workgroupDimX, + uint8_t workgroupDimY, + uint16_t downsampleFactor, + uint32_t constantBufferDataSize, + uint32_t maxRepeatNum, + const char* shaderFileName, + const nrd::ComputeShader& dxbc, + const nrd::ComputeShader& dxil, + const nrd::ComputeShader& spirv +) { // Pipeline size_t pipelineIndex = 0; @@ -679,6 +704,25 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_Diffuse_TemporalStabilization.cs.dxil.h" #include "REBLUR_Diffuse_SplitScreen.cs.dxbc.h" #include "REBLUR_Diffuse_SplitScreen.cs.dxil.h" + + #include "REBLUR_Perf_Diffuse_PreBlur.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_PreBlur.cs.dxil.h" + #include "REBLUR_Perf_Diffuse_PreBlurAdvanced.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_PreBlurAdvanced.cs.dxil.h" + #include "REBLUR_Perf_Diffuse_TemporalAccumulation.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_TemporalAccumulation.cs.dxil.h" + #include "REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence.cs.dxil.h" + #include "REBLUR_Perf_Diffuse_AntiFirefly.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_AntiFirefly.cs.dxil.h" + #include "REBLUR_Perf_Diffuse_HistoryFix.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_HistoryFix.cs.dxil.h" + #include "REBLUR_Perf_Diffuse_Blur.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_Blur.cs.dxil.h" + #include "REBLUR_Perf_Diffuse_PostBlur.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_PostBlur.cs.dxil.h" + #include "REBLUR_Perf_Diffuse_TemporalStabilization.cs.dxbc.h" + #include "REBLUR_Perf_Diffuse_TemporalStabilization.cs.dxil.h" #endif #include "REBLUR_Diffuse_PreBlur.cs.spirv.h" @@ -692,6 +736,16 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_Diffuse_PostBlur.cs.spirv.h" #include "REBLUR_Diffuse_SplitScreen.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_PreBlur.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_PreBlurAdvanced.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_TemporalAccumulation.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_AntiFirefly.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_HistoryFix.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_Blur.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_TemporalStabilization.cs.spirv.h" + #include "REBLUR_Perf_Diffuse_PostBlur.cs.spirv.h" + // REBLUR_DIFFUSE_OCCLUSION #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE #include "REBLUR_DiffuseOcclusion_TemporalAccumulation.cs.dxbc.h" @@ -706,6 +760,17 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_DiffuseOcclusion_PostBlur.cs.dxil.h" #include "REBLUR_DiffuseOcclusion_SplitScreen.cs.dxbc.h" #include "REBLUR_DiffuseOcclusion_SplitScreen.cs.dxil.h" + + #include "REBLUR_Perf_DiffuseOcclusion_TemporalAccumulation.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseOcclusion_TemporalAccumulation.cs.dxil.h" + #include "REBLUR_Perf_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.dxil.h" + #include "REBLUR_Perf_DiffuseOcclusion_HistoryFix.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseOcclusion_HistoryFix.cs.dxil.h" + #include "REBLUR_Perf_DiffuseOcclusion_Blur.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseOcclusion_Blur.cs.dxil.h" + #include "REBLUR_Perf_DiffuseOcclusion_PostBlur.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseOcclusion_PostBlur.cs.dxil.h" #endif #include "REBLUR_DiffuseOcclusion_TemporalAccumulation.cs.spirv.h" @@ -715,6 +780,12 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_DiffuseOcclusion_PostBlur.cs.spirv.h" #include "REBLUR_DiffuseOcclusion_SplitScreen.cs.spirv.h" + #include "REBLUR_Perf_DiffuseOcclusion_TemporalAccumulation.cs.spirv.h" + #include "REBLUR_Perf_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.spirv.h" + #include "REBLUR_Perf_DiffuseOcclusion_HistoryFix.cs.spirv.h" + #include "REBLUR_Perf_DiffuseOcclusion_Blur.cs.spirv.h" + #include "REBLUR_Perf_DiffuseOcclusion_PostBlur.cs.spirv.h" + // REBLUR_SPECULAR #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE #include "REBLUR_Specular_PreBlur.cs.dxbc.h" @@ -737,6 +808,25 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_Specular_TemporalStabilization.cs.dxil.h" #include "REBLUR_Specular_SplitScreen.cs.dxbc.h" #include "REBLUR_Specular_SplitScreen.cs.dxil.h" + + #include "REBLUR_Perf_Specular_PreBlur.cs.dxbc.h" + #include "REBLUR_Perf_Specular_PreBlur.cs.dxil.h" + #include "REBLUR_Perf_Specular_PreBlurAdvanced.cs.dxbc.h" + #include "REBLUR_Perf_Specular_PreBlurAdvanced.cs.dxil.h" + #include "REBLUR_Perf_Specular_TemporalAccumulation.cs.dxbc.h" + #include "REBLUR_Perf_Specular_TemporalAccumulation.cs.dxil.h" + #include "REBLUR_Perf_Specular_TemporalAccumulationWithConfidence.cs.dxbc.h" + #include "REBLUR_Perf_Specular_TemporalAccumulationWithConfidence.cs.dxil.h" + #include "REBLUR_Perf_Specular_AntiFirefly.cs.dxbc.h" + #include "REBLUR_Perf_Specular_AntiFirefly.cs.dxil.h" + #include "REBLUR_Perf_Specular_HistoryFix.cs.dxbc.h" + #include "REBLUR_Perf_Specular_HistoryFix.cs.dxil.h" + #include "REBLUR_Perf_Specular_Blur.cs.dxbc.h" + #include "REBLUR_Perf_Specular_Blur.cs.dxil.h" + #include "REBLUR_Perf_Specular_PostBlur.cs.dxbc.h" + #include "REBLUR_Perf_Specular_PostBlur.cs.dxil.h" + #include "REBLUR_Perf_Specular_TemporalStabilization.cs.dxbc.h" + #include "REBLUR_Perf_Specular_TemporalStabilization.cs.dxil.h" #endif #include "REBLUR_Specular_PreBlur.cs.spirv.h" @@ -750,6 +840,16 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_Specular_TemporalStabilization.cs.spirv.h" #include "REBLUR_Specular_SplitScreen.cs.spirv.h" + #include "REBLUR_Perf_Specular_PreBlur.cs.spirv.h" + #include "REBLUR_Perf_Specular_PreBlurAdvanced.cs.spirv.h" + #include "REBLUR_Perf_Specular_TemporalAccumulation.cs.spirv.h" + #include "REBLUR_Perf_Specular_TemporalAccumulationWithConfidence.cs.spirv.h" + #include "REBLUR_Perf_Specular_AntiFirefly.cs.spirv.h" + #include "REBLUR_Perf_Specular_HistoryFix.cs.spirv.h" + #include "REBLUR_Perf_Specular_Blur.cs.spirv.h" + #include "REBLUR_Perf_Specular_PostBlur.cs.spirv.h" + #include "REBLUR_Perf_Specular_TemporalStabilization.cs.spirv.h" + // REBLUR_SPECULAR_OCCLUSION #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE #include "REBLUR_SpecularOcclusion_TemporalAccumulation.cs.dxbc.h" @@ -764,6 +864,17 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_SpecularOcclusion_PostBlur.cs.dxil.h" #include "REBLUR_SpecularOcclusion_SplitScreen.cs.dxbc.h" #include "REBLUR_SpecularOcclusion_SplitScreen.cs.dxil.h" + + #include "REBLUR_Perf_SpecularOcclusion_TemporalAccumulation.cs.dxbc.h" + #include "REBLUR_Perf_SpecularOcclusion_TemporalAccumulation.cs.dxil.h" + #include "REBLUR_Perf_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.dxbc.h" + #include "REBLUR_Perf_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.dxil.h" + #include "REBLUR_Perf_SpecularOcclusion_HistoryFix.cs.dxbc.h" + #include "REBLUR_Perf_SpecularOcclusion_HistoryFix.cs.dxil.h" + #include "REBLUR_Perf_SpecularOcclusion_Blur.cs.dxbc.h" + #include "REBLUR_Perf_SpecularOcclusion_Blur.cs.dxil.h" + #include "REBLUR_Perf_SpecularOcclusion_PostBlur.cs.dxbc.h" + #include "REBLUR_Perf_SpecularOcclusion_PostBlur.cs.dxil.h" #endif #include "REBLUR_SpecularOcclusion_TemporalAccumulation.cs.spirv.h" @@ -773,6 +884,12 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_SpecularOcclusion_PostBlur.cs.spirv.h" #include "REBLUR_SpecularOcclusion_SplitScreen.cs.spirv.h" + #include "REBLUR_Perf_SpecularOcclusion_TemporalAccumulation.cs.spirv.h" + #include "REBLUR_Perf_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.spirv.h" + #include "REBLUR_Perf_SpecularOcclusion_HistoryFix.cs.spirv.h" + #include "REBLUR_Perf_SpecularOcclusion_Blur.cs.spirv.h" + #include "REBLUR_Perf_SpecularOcclusion_PostBlur.cs.spirv.h" + // REBLUR_DIFFUSE_SPECULAR #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE #include "REBLUR_DiffuseSpecular_PreBlur.cs.dxbc.h" @@ -795,6 +912,25 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_DiffuseSpecular_PostBlur.cs.dxil.h" #include "REBLUR_DiffuseSpecular_SplitScreen.cs.dxbc.h" #include "REBLUR_DiffuseSpecular_SplitScreen.cs.dxil.h" + + #include "REBLUR_Perf_DiffuseSpecular_PreBlur.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_PreBlur.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecular_PreBlurAdvanced.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_PreBlurAdvanced.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalAccumulation.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalAccumulation.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecular_AntiFirefly.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_AntiFirefly.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecular_HistoryFix.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_HistoryFix.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecular_Blur.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_Blur.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalStabilization.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalStabilization.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecular_PostBlur.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecular_PostBlur.cs.dxil.h" #endif #include "REBLUR_DiffuseSpecular_PreBlur.cs.spirv.h" @@ -808,6 +944,16 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_DiffuseSpecular_PostBlur.cs.spirv.h" #include "REBLUR_DiffuseSpecular_SplitScreen.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_PreBlur.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_PreBlurAdvanced.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalAccumulation.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_AntiFirefly.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_HistoryFix.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_Blur.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_TemporalStabilization.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecular_PostBlur.cs.spirv.h" + // REBLUR_DIFFUSE_SPECULAR_OCCLUSION #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE #include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.cs.dxbc.h" @@ -822,6 +968,17 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_DiffuseSpecularOcclusion_PostBlur.cs.dxil.h" #include "REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.dxbc.h" #include "REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.dxil.h" + + #include "REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulation.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulation.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_HistoryFix.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_HistoryFix.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_Blur.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_Blur.cs.dxil.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_PostBlur.cs.dxbc.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_PostBlur.cs.dxil.h" #endif #include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.cs.spirv.h" @@ -831,6 +988,12 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REBLUR_DiffuseSpecularOcclusion_PostBlur.cs.spirv.h" #include "REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulation.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_HistoryFix.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_Blur.cs.spirv.h" + #include "REBLUR_Perf_DiffuseSpecularOcclusion_PostBlur.cs.spirv.h" + // SIGMA_SHADOW #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE #include "SIGMA_Shadow_ClassifyTiles.cs.dxbc.h" @@ -886,8 +1049,6 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "RELAX_Diffuse_HistoryClamping.cs.dxil.h" #include "RELAX_Diffuse_Firefly.cs.dxbc.h" #include "RELAX_Diffuse_Firefly.cs.dxil.h" - #include "RELAX_Diffuse_SpatialVarianceEstimation.cs.dxbc.h" - #include "RELAX_Diffuse_SpatialVarianceEstimation.cs.dxil.h" #include "RELAX_Diffuse_ATrousShmem.cs.dxbc.h" #include "RELAX_Diffuse_ATrousShmem.cs.dxil.h" #include "RELAX_Diffuse_ATrousStandard.cs.dxbc.h" @@ -901,7 +1062,6 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "RELAX_Diffuse_DisocclusionFix.cs.spirv.h" #include "RELAX_Diffuse_HistoryClamping.cs.spirv.h" #include "RELAX_Diffuse_Firefly.cs.spirv.h" - #include "RELAX_Diffuse_SpatialVarianceEstimation.cs.spirv.h" #include "RELAX_Diffuse_ATrousShmem.cs.spirv.h" #include "RELAX_Diffuse_ATrousStandard.cs.spirv.h" #include "RELAX_Diffuse_SplitScreen.cs.spirv.h" @@ -918,8 +1078,6 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "RELAX_Specular_HistoryClamping.cs.dxil.h" #include "RELAX_Specular_Firefly.cs.dxbc.h" #include "RELAX_Specular_Firefly.cs.dxil.h" - #include "RELAX_Specular_SpatialVarianceEstimation.cs.dxbc.h" - #include "RELAX_Specular_SpatialVarianceEstimation.cs.dxil.h" #include "RELAX_Specular_ATrousShmem.cs.dxbc.h" #include "RELAX_Specular_ATrousShmem.cs.dxil.h" #include "RELAX_Specular_ATrousStandard.cs.dxbc.h" @@ -933,7 +1091,6 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "RELAX_Specular_DisocclusionFix.cs.spirv.h" #include "RELAX_Specular_HistoryClamping.cs.spirv.h" #include "RELAX_Specular_Firefly.cs.spirv.h" - #include "RELAX_Specular_SpatialVarianceEstimation.cs.spirv.h" #include "RELAX_Specular_ATrousShmem.cs.spirv.h" #include "RELAX_Specular_ATrousStandard.cs.spirv.h" #include "RELAX_Specular_SplitScreen.cs.spirv.h" @@ -950,8 +1107,6 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "RELAX_DiffuseSpecular_HistoryClamping.cs.dxil.h" #include "RELAX_DiffuseSpecular_Firefly.cs.dxbc.h" #include "RELAX_DiffuseSpecular_Firefly.cs.dxil.h" - #include "RELAX_DiffuseSpecular_SpatialVarianceEstimation.cs.dxbc.h" - #include "RELAX_DiffuseSpecular_SpatialVarianceEstimation.cs.dxil.h" #include "RELAX_DiffuseSpecular_ATrousShmem.cs.dxbc.h" #include "RELAX_DiffuseSpecular_ATrousShmem.cs.dxil.h" #include "RELAX_DiffuseSpecular_ATrousStandard.cs.dxbc.h" @@ -965,7 +1120,6 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "RELAX_DiffuseSpecular_DisocclusionFix.cs.spirv.h" #include "RELAX_DiffuseSpecular_HistoryClamping.cs.spirv.h" #include "RELAX_DiffuseSpecular_Firefly.cs.spirv.h" - #include "RELAX_DiffuseSpecular_SpatialVarianceEstimation.cs.spirv.h" #include "RELAX_DiffuseSpecular_ATrousShmem.cs.spirv.h" #include "RELAX_DiffuseSpecular_ATrousStandard.cs.spirv.h" #include "RELAX_DiffuseSpecular_SplitScreen.cs.spirv.h" @@ -980,6 +1134,23 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "REFERENCE_Accumulate.cs.spirv.h" #include "REFERENCE_SplitScreen.cs.spirv.h" + + // SPEC_REFLECTION_MV + #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE + #include "SpecularReflectionMv_Compute.cs.dxbc.h" + #include "SpecularReflectionMv_Compute.cs.dxil.h" + #endif + + #include "SpecularReflectionMv_Compute.cs.spirv.h" + + + // DELTA_OPTIMIZATION_MV + #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE + #include "DeltaOptimizationMv_Compute.cs.dxbc.h" + #include "DeltaOptimizationMv_Compute.cs.dxil.h" + #endif + + #include "DeltaOptimizationMv_Compute.cs.spirv.h" #endif // METHODS ================================================================================= @@ -997,3 +1168,5 @@ void nrd::DenoiserImpl::UpdateCommonSettings(const nrd::CommonSettings& commonSe #include "Methods/Relax_Specular.hpp" #include "Methods/Relax_DiffuseSpecular.hpp" #include "Methods/Reference.hpp" +#include "Methods/SpecularReflectionMv.hpp" +#include "Methods/DeltaOptimizationMv.hpp" diff --git a/Source/DenoiserImpl.h b/Source/DenoiserImpl.h index 023047f..16e004f 100644 --- a/Source/DenoiserImpl.h +++ b/Source/DenoiserImpl.h @@ -23,19 +23,22 @@ typedef nrd::MemoryAllocatorInterface MemoryAllocatorInterface; #include "Timer.h" +#define _NRD_STRINGIFY(s) #s +#define NRD_STRINGIFY(s) _NRD_STRINGIFY(s) + #ifdef NRD_USE_PRECOMPILED_SHADERS #if !NRD_ONLY_SPIRV_SHADERS_AVAILABLE #define AddDispatch(shaderName, constantNum, workgroupDim, downsampleFactor) \ - AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, 1, #shaderName ".cs", {g_##shaderName##_cs_dxbc, GetCountOf(g_ ## shaderName ## _cs_dxbc)}, {g_##shaderName##_cs_dxil, GetCountOf(g_ ## shaderName ## _cs_dxil)}, {g_##shaderName##_cs_spirv, GetCountOf(g_ ## shaderName ## _cs_spirv)}) + AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, 1, #shaderName ".cs", {g_##shaderName##_cs_dxbc, GetCountOf(g_##shaderName##_cs_dxbc)}, {g_##shaderName##_cs_dxil, GetCountOf(g_## shaderName##_cs_dxil)}, {g_##shaderName##_cs_spirv, GetCountOf(g_##shaderName##_cs_spirv)}) #define AddDispatchRepeated(shaderName, constantNum, workgroupDim, downsampleFactor, repeatNum) \ - AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, repeatNum, #shaderName ".cs", {g_##shaderName##_cs_dxbc, GetCountOf(g_ ## shaderName ## _cs_dxbc)}, {g_##shaderName##_cs_dxil, GetCountOf(g_ ## shaderName ## _cs_dxil)}, {g_##shaderName##_cs_spirv, GetCountOf(g_ ## shaderName ## _cs_spirv)}) + AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, repeatNum, #shaderName ".cs", {g_##shaderName##_cs_dxbc, GetCountOf(g_##shaderName##_cs_dxbc)}, {g_##shaderName##_cs_dxil, GetCountOf(g_##shaderName##_cs_dxil)}, {g_##shaderName##_cs_spirv, GetCountOf(g_##shaderName##_cs_spirv)}) #else #define AddDispatch(shaderName, constantNum, workgroupDim, downsampleFactor) \ - AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, 1, #shaderName ".cs", {}, {}, {g_##shaderName##_cs_spirv, GetCountOf(g_ ## shaderName ## _cs_spirv)}) + AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, 1, #shaderName ".cs", {}, {}, {g_##shaderName##_cs_spirv, GetCountOf(g_##shaderName##_cs_spirv)}) #define AddDispatchRepeated(shaderName, constantNum, workgroupDim, downsampleFactor, repeatNum) \ - AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, repeatNum, #shaderName ".cs", {}, {}, {g_##shaderName##_cs_spirv, GetCountOf(g_ ## shaderName ## _cs_spirv)}) + AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, repeatNum, #shaderName ".cs", {}, {}, {g_##shaderName##_cs_spirv, GetCountOf(g_##shaderName##_cs_spirv)}) #endif #else #define AddDispatch(shaderName, constantNum, workgroupDim, downsampleFactor) \ @@ -45,7 +48,7 @@ typedef nrd::MemoryAllocatorInterface MemoryAllocatorInterface; AddComputeDispatchDesc(workgroupDim, workgroupDim, downsampleFactor, constantNum, repeatNum, #shaderName ".cs", {}, {}, {}) #endif -#define PushPass(passName) _PushPass(DENOISER_NAME " - " passName) +#define PushPass(passName) _PushPass(NRD_STRINGIFY(METHOD_NAME) " - " passName) // TODO: rework is needed, but still better than copy-pasting #define NRD_DECLARE_DIMS \ @@ -78,14 +81,14 @@ namespace nrd union Settings { // Add settings here - ReblurDiffuseSettings diffuseReblur; - ReblurSpecularSettings specularReblur; - ReblurDiffuseSpecularSettings diffuseSpecularReblur; - SigmaShadowSettings shadowSigma; + ReblurSettings reblur; + SigmaSettings sigma; RelaxDiffuseSettings diffuseRelax; RelaxSpecularSettings specularRelax; RelaxDiffuseSpecularSettings diffuseSpecularRelax; ReferenceSettings reference; + SpecularReflectionMvSettings specularReflectionMv; + DeltaOptimizationMvSettings deltaOptimizationMv; }; struct MethodData @@ -123,38 +126,30 @@ namespace nrd { // Add methods here public: + // Reblur size_t AddMethod_ReblurDiffuse(uint16_t w, uint16_t h); - void UpdateMethod_ReblurDiffuse(const MethodData& methodData); - void AddSharedConstants_ReblurDiffuse(const MethodData& methodData, const ReblurDiffuseSettings& settings, Constant*& data); - size_t AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t h); - void UpdateMethod_ReblurDiffuseOcclusion(const MethodData& methodData); - size_t AddMethod_ReblurSpecular(uint16_t w, uint16_t h); - void UpdateMethod_ReblurSpecular(const MethodData& methodData); - void AddSharedConstants_ReblurSpecular(const MethodData& methodData, const ReblurSpecularSettings& settings, Constant*& data); - size_t AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t h); - void UpdateMethod_ReblurSpecularOcclusion(const MethodData& methodData); - size_t AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h); - void UpdateMethod_ReblurDiffuseSpecular(const MethodData& methodData); - void AddSharedConstants_ReblurDiffuseSpecular(const MethodData& methodData, const ReblurDiffuseSpecularSettings& settings, Constant*& data); - size_t AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, uint16_t h); - void UpdateMethod_ReblurDiffuseSpecularOcclusion(const MethodData& methodData); - size_t AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w, uint16_t h); - void UpdateMethod_ReblurDiffuseDirectionalOcclusion(const MethodData& methodData); + void UpdateMethod_Reblur(const MethodData& methodData); + void UpdateMethod_ReblurOcclusion(const MethodData& methodData); + + void AddSharedConstants_Reblur(const MethodData& methodData, const ReblurSettings& settings, Constant*& data); + + // Sigma size_t AddMethod_SigmaShadow(uint16_t w, uint16_t h); void UpdateMethod_SigmaShadow(const MethodData& methodData); - void AddSharedConstants_SigmaShadow(const MethodData& methodData, const SigmaShadowSettings& settings, Constant*& data); + void AddSharedConstants_Sigma(const MethodData& methodData, const SigmaSettings& settings, Constant*& data); size_t AddMethod_SigmaShadowTranslucency(uint16_t w, uint16_t h); void UpdateMethod_SigmaShadowTranslucency(const MethodData& methodData); - void AddSharedConstants_Relax(const MethodData& methodData, Constant*& data); + // Relax + void AddSharedConstants_Relax(const MethodData& methodData, Constant*& data, nrd::Method method); size_t AddMethod_RelaxDiffuse(uint16_t w, uint16_t h); void UpdateMethod_RelaxDiffuse(const MethodData& methodData); @@ -168,6 +163,12 @@ namespace nrd size_t AddMethod_Reference(uint16_t w, uint16_t h); void UpdateMethod_Reference(const MethodData& methodData); + size_t AddMethod_SpecularReflectionMv(); + void UpdateMethod_SpecularReflectionMv(const MethodData& methodData); + + size_t AddMethod_DeltaOptimizationMv(uint16_t w, uint16_t h); + void UpdateMethod_DeltaOptimizationMv(const MethodData& methodData); + // Internal public: inline DenoiserImpl(const StdAllocator& stdAllocator) : @@ -287,14 +288,6 @@ namespace nrd assert( bytes == dispatchDesc.constantBufferDataSize ); } - inline float GetMinResolutionScale() const - { - float a = ml::Min(m_ResolutionScalePrev.x, m_ResolutionScalePrev.y); - float b = ml::Min(m_CommonSettings.resolutionScale[0], m_CommonSettings.resolutionScale[1]); - - return ml::Min(a, b); - } - private: StdAllocator m_StdAllocator; Vector m_MethodData; diff --git a/Source/Methods/DeltaOptimizationMv.hpp b/Source/Methods/DeltaOptimizationMv.hpp new file mode 100644 index 0000000..ce8b71b --- /dev/null +++ b/Source/Methods/DeltaOptimizationMv.hpp @@ -0,0 +1,62 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +size_t nrd::DenoiserImpl::AddMethod_DeltaOptimizationMv(uint16_t w, uint16_t h) +{ + #define METHOD_NAME DeltaOptimizationMv + + enum class Permanent + { + DELTA_SECONDARY_POSW_CURR = PERMANENT_POOL_START, + DELTA_SECONDARY_POSW_PREV + }; + + m_PermanentPool.push_back( {Format::RGBA32_SFLOAT, w, h, 1} ); + m_PermanentPool.push_back( {Format::RGBA32_SFLOAT, w, h, 1} ); + + SetSharedConstants(0, 0, 0, 0); + + PushPass("Compute"); + { + PushInput( AsUint(ResourceType::IN_MV) ); + PushInput( AsUint(ResourceType::IN_DELTA_PRIMARY_POSW) ); + PushInput( AsUint(ResourceType::IN_DELTA_SECONDARY_POSW) ); + PushInput( AsUint(Permanent::DELTA_SECONDARY_POSW_PREV), 0, 1, AsUint(Permanent::DELTA_SECONDARY_POSW_CURR) ); + + PushOutput( AsUint(ResourceType::OUT_DELTA_MV) ); + PushOutput( AsUint(Permanent::DELTA_SECONDARY_POSW_CURR), 0, 1, AsUint(Permanent::DELTA_SECONDARY_POSW_PREV) ); + + AddDispatch( DeltaOptimizationMv_Compute, SumConstants(1, 0, 4, 1), 16, 1 ); + } + + #undef METHOD_NAME + + return sizeof(DeltaOptimizationMvSettings); +} + +void nrd::DenoiserImpl::UpdateMethod_DeltaOptimizationMv(const MethodData& methodData) +{ + enum class Dispatch + { + COMPUTE, + }; + + NRD_DECLARE_DIMS; + + // COMPUTE + Constant* data = PushDispatch(methodData, AsUint(Dispatch::COMPUTE)); + AddFloat4x4(data, m_WorldToClipPrev); + AddUint2(data, rectW, rectH); + AddFloat2(data, 1.0f / float(rectW), 1.0f / float(rectH)); + AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); + AddUint2(data, m_CommonSettings.inputSubrectOrigin[0], m_CommonSettings.inputSubrectOrigin[1]); + AddUint(data, m_CommonSettings.isMotionVectorInWorldSpace ? 1 : 0); + ValidateConstants(data); +} diff --git a/Source/Methods/Reblur_Diffuse.hpp b/Source/Methods/Reblur_Diffuse.hpp index 3cca369..e03c7c6 100644 --- a/Source/Methods/Reblur_Diffuse.hpp +++ b/Source/Methods/Reblur_Diffuse.hpp @@ -8,20 +8,24 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ +#define REBLUR_DECLARE_SHARED_CONSTANT_NUM SetSharedConstants(1, 3, 9, 22) +#define REBLUR_MIP_NUM 4 + size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) { - #define DENOISER_NAME "REBLUR::Diffuse" - #define MIP_NUM 5 + #define METHOD_NAME REBLUR_Diffuse #define DIFF_TEMP1 AsUint(Transient::DIFF_HISTORY_STABILIZED) // valid before HistoryFix #define DIFF_TEMP2 AsUint(ResourceType::OUT_DIFF_RADIANCE_HITDIST) // valid after HistoryFix enum class Permanent { - PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS = PERMANENT_POOL_START, + PREV_VIEWZ_DIFFACCUMSPEED = PERMANENT_POOL_START, + PREV_NORMAL_SPECACCUMSPEED, DIFF_HISTORY, }; - m_PermanentPool.push_back( {Format::RG32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); enum class Transient @@ -35,11 +39,11 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); m_TransientPool.push_back( {Format::R8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, MIP_NUM} ); - m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, MIP_NUM} ); + m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, REBLUR_MIP_NUM} ); + m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, REBLUR_MIP_NUM} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - SetSharedConstants(1, 3, 8, 16); + REBLUR_DECLARE_SHARED_CONSTANT_NUM; PushPass("Pre-blur"); { @@ -49,7 +53,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( DIFF_TEMP1 ); - AddDispatch( REBLUR_Diffuse_PreBlur, SumConstants(1, 1, 0, 3), 16, 1 ); + AddDispatch( REBLUR_Diffuse_PreBlur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_PreBlur, SumConstants(1, 2, 0, 2), 16, 1 ); } PushPass("Pre-blur (advanced)"); @@ -61,7 +66,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( DIFF_TEMP1 ); - AddDispatch( REBLUR_Diffuse_PreBlurAdvanced, SumConstants(1, 1, 0, 3), 16, 1 ); + AddDispatch( REBLUR_Diffuse_PreBlurAdvanced, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_PreBlurAdvanced, SumConstants(1, 2, 0, 2), 16, 1 ); } PushPass("Temporal accumulation"); @@ -69,7 +75,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( AsUint(ResourceType::IN_DIFF_RADIANCE_HITDIST) ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); @@ -78,7 +85,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_TemporalAccumulation, SumConstants(3, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalAccumulation, SumConstants(4, 2, 1, 5), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalAccumulation, SumConstants(4, 2, 1, 5), 16, 1 ); } PushPass("Temporal accumulation"); // after Pre-blur @@ -86,7 +94,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( DIFF_TEMP1 ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); @@ -95,7 +104,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_TemporalAccumulation, SumConstants(3, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalAccumulation, SumConstants(4, 2, 1, 5), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalAccumulation, SumConstants(4, 2, 1, 5), 16, 1 ); } PushPass("Temporal accumulation"); // with confidence @@ -103,7 +113,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( AsUint(ResourceType::IN_DIFF_RADIANCE_HITDIST) ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); PushInput( AsUint(ResourceType::IN_DIFF_CONFIDENCE) ); @@ -113,7 +124,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_TemporalAccumulationWithConfidence, SumConstants(3, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 16, 1 ); } PushPass("Temporal accumulation"); // with confidence, after Pre-blur @@ -121,7 +133,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( DIFF_TEMP1 ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); PushInput( AsUint(ResourceType::IN_DIFF_CONFIDENCE) ); @@ -131,7 +144,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_TemporalAccumulationWithConfidence, SumConstants(3, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 16, 1 ); } PushPass("Mip generation"); @@ -139,7 +153,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushInput( AsUint(Transient::DIFF_ACCUMULATED) ); PushInput( AsUint(Transient::SCALED_VIEWZ) ); - for( uint16_t i = 1; i < MIP_NUM; i++ ) + for( uint16_t i = 1; i < REBLUR_MIP_NUM; i++ ) { PushOutput( AsUint(Transient::DIFF_ACCUMULATED), i, 1 ); PushOutput( AsUint(Transient::SCALED_VIEWZ), i, 1 ); @@ -151,14 +165,15 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushPass("History fix"); { PushInput( AsUint(Transient::INTERNAL_DATA) ); - PushInput( AsUint(Transient::SCALED_VIEWZ), 0, MIP_NUM ); - PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, MIP_NUM - 1 ); + PushInput( AsUint(Transient::SCALED_VIEWZ), 0, REBLUR_MIP_NUM ); + PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); PushInput( AsUint(ResourceType::OUT_DIFF_RADIANCE_HITDIST) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED), 0, 1 ); PushOutput( AsUint(Transient::DIFF_HISTORY_STABILIZED) ); AddDispatch( REBLUR_Diffuse_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Blur"); @@ -171,7 +186,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( DIFF_TEMP2 ); - AddDispatch( REBLUR_Diffuse_Blur, SumConstants(1, 1, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Diffuse_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); @@ -184,7 +200,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Permanent::DIFF_HISTORY) ); - AddDispatch( REBLUR_Diffuse_PostBlur, SumConstants(1, 1, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Diffuse_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); // before Anti-Firefly @@ -197,7 +214,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_PostBlur, SumConstants(1, 1, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Diffuse_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Anti-firefly"); @@ -209,6 +227,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::DIFF_HISTORY) ); AddDispatch( REBLUR_Diffuse_AntiFirefly, SumConstants(0, 0, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_AntiFirefly, SumConstants(0, 0, 0, 0), 16, 1 ); } PushPass("Temporal stabilization"); @@ -221,10 +240,12 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushInput( AsUint(Transient::DIFF_HISTORY_STABILIZED) ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); - PushOutput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushOutput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushOutput( AsUint(ResourceType::OUT_DIFF_RADIANCE_HITDIST) ); - AddDispatch( REBLUR_Diffuse_TemporalStabilization, SumConstants(2, 3, 1, 1), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalStabilization, SumConstants(2, 2, 2, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalStabilization, SumConstants(2, 2, 2, 1), 16, 1 ); } PushPass("Split screen"); @@ -234,56 +255,80 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(ResourceType::OUT_DIFF_RADIANCE_HITDIST) ); - AddDispatch( REBLUR_Diffuse_SplitScreen, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Diffuse_SplitScreen, SumConstants(0, 0, 0, 3), 16, 1 ); } - #undef DENOISER_NAME - #undef MIP_NUM + #undef METHOD_NAME #undef DIFF_TEMP1 #undef DIFF_TEMP2 - return sizeof(ReblurDiffuseSettings); + return sizeof(ReblurSettings); } -void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuse(const MethodData& methodData) +void nrd::DenoiserImpl::UpdateMethod_Reblur(const MethodData& methodData) { enum class Dispatch { PRE_BLUR, + PERF_PRE_BLUR, PRE_BLUR_ADVANCED, + PERF_PRE_BLUR_ADVANCED, TEMPORAL_ACCUMULATION, + PERF_TEMPORAL_ACCUMULATION, TEMPORAL_ACCUMULATION_AFTER_PRE_BLUR, + PERF_TEMPORAL_ACCUMULATION_AFTER_PRE_BLUR, TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, + PERF_TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, TEMPORAL_ACCUMULATION_WITH_CONFIDENCE_AFTER_PRE_BLUR, + PERF_TEMPORAL_ACCUMULATION_WITH_CONFIDENCE_AFTER_PRE_BLUR, MIP_GENERATION, HISTORY_FIX, + PERF_HISTORY_FIX, BLUR, + PERF_BLUR, POST_BLUR, + PERF_POST_BLUR, POST_BLUR_BEFORE_ANTI_FIRELY, + PERF_POST_BLUR_BEFORE_ANTI_FIRELY, ANTI_FIREFLY, + PERF_ANTI_FIREFLY, TEMPORAL_STABILIZATION, + PERF_TEMPORAL_STABILIZATION, SPLIT_SCREEN, }; - const ReblurDiffuseSettings& settings = methodData.settings.diffuseReblur; + const ReblurSettings& settings = methodData.settings.reblur; bool skipPrePass = settings.prePassMode == PrePassMode::OFF && settings.checkerboardMode == CheckerboardMode::OFF; - float normalWeightStrictness = ml::Lerp( 0.1f, 1.0f, settings.normalWeightStrictness ); - - uint32_t diffCheckerboard = ((uint32_t)settings.checkerboardMode + 2) % 3; - ml::float4 diffAntilag1 = ml::float4(settings.antilagIntensitySettings.sigmaScale / GetMinResolutionScale(), settings.antilagHitDistanceSettings.sigmaScale / GetMinResolutionScale(), settings.antilagIntensitySettings.sensitivityToDarkness, settings.antilagHitDistanceSettings.sensitivityToDarkness); - ml::float4 diffAntilag2 = ml::float4(settings.antilagIntensitySettings.thresholdMin / GetMinResolutionScale(), settings.antilagHitDistanceSettings.thresholdMin / GetMinResolutionScale(), settings.antilagIntensitySettings.thresholdMax, settings.antilagHitDistanceSettings.thresholdMax); + ml::float4 antilagMinMaxThreshold = ml::float4(settings.antilagIntensitySettings.thresholdMin, settings.antilagHitDistanceSettings.thresholdMin, settings.antilagIntensitySettings.thresholdMax, settings.antilagHitDistanceSettings.thresholdMax); if (!settings.antilagIntensitySettings.enable || settings.enableReferenceAccumulation) { - diffAntilag2.x = 99998.0f; - diffAntilag2.z = 99999.0f; + antilagMinMaxThreshold.x = 99998.0f; + antilagMinMaxThreshold.z = 99999.0f; } if (!settings.antilagHitDistanceSettings.enable || settings.enableReferenceAccumulation) { - diffAntilag2.y = 99998.0f; - diffAntilag2.w = 99999.0f; + antilagMinMaxThreshold.y = 99998.0f; + antilagMinMaxThreshold.w = 99999.0f; + } + + uint32_t specCheckerboard = 2; + uint32_t diffCheckerboard = 2; + + switch (settings.checkerboardMode) + { + case nrd::CheckerboardMode::BLACK: + diffCheckerboard = 0; + specCheckerboard = 1; + break; + case nrd::CheckerboardMode::WHITE: + diffCheckerboard = 1; + specCheckerboard = 0; + break; + default: + break; } NRD_DECLARE_DIMS; @@ -292,9 +337,10 @@ void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuse(const MethodData& methodData) if (m_CommonSettings.splitScreen >= 1.0f) { Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddUint(data, diffCheckerboard); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat(data, m_CommonSettings.splitScreen); + AddUint(data, diffCheckerboard); + AddUint(data, specCheckerboard); ValidateConstants(data); return; @@ -303,29 +349,32 @@ void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuse(const MethodData& methodData) // PRE_BLUR if (!skipPrePass) { - uint32_t preBlurPass = AsUint(Dispatch::PRE_BLUR) + ml::Max((int32_t)settings.prePassMode - 1, 0); - Constant* data = PushDispatch(methodData, preBlurPass); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + uint32_t passIndex = AsUint(Dispatch::PRE_BLUR) + ml::Max((int32_t)settings.prePassMode - 1, 0) * 2 + (settings.enablePerformanceMode ? 1 : 0); + Constant* data = PushDispatch(methodData, passIndex); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[0]); + AddFloat4(data, ml::float4(settings.specularLobeTrimmingParameters.A, settings.specularLobeTrimmingParameters.B, settings.specularLobeTrimmingParameters.C, settings.prePassMode == PrePassMode::OFF ? 0.0f : 1.0f)); AddUint(data, diffCheckerboard); - AddUint(data, settings.prePassMode == PrePassMode::OFF ? 0 : 1); - AddFloat(data, normalWeightStrictness); + AddUint(data, specCheckerboard); ValidateConstants(data); } // TEMPORAL_ACCUMULATION - Constant* data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_ACCUMULATION) + (m_CommonSettings.isHistoryConfidenceInputsAvailable ? 2 : 0) + (skipPrePass ? 0 : 1)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + uint32_t passIndex = AsUint(Dispatch::TEMPORAL_ACCUMULATION) + ((m_CommonSettings.isHistoryConfidenceInputsAvailable ? 2 : 0) + (skipPrePass ? 0 : 1)) * 2 + (settings.enablePerformanceMode ? 1 : 0); + Constant* data = PushDispatch(methodData, passIndex); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat4x4(data, m_WorldToViewPrev); AddFloat4x4(data, m_WorldToClipPrev); AddFloat4x4(data, m_ViewToWorld); + AddFloat4x4(data, m_WorldToClip); AddFloat4(data, m_FrustumPrev); AddFloat4(data, m_CameraDelta); AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); AddFloat(data, m_CheckerboardResolveAccumSpeed); AddFloat(data, settings.enableReferenceAccumulation ? 0.005f : m_CommonSettings.disocclusionThreshold ); AddUint(data, diffCheckerboard); + AddUint(data, specCheckerboard); AddUint(data, skipPrePass ? 0 : 1); ValidateConstants(data); @@ -337,45 +386,46 @@ void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuse(const MethodData& methodData) ValidateConstants(data); // HISTORY_FIX - data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_FIX)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + data = PushDispatch(methodData, AsUint( settings.enablePerformanceMode ? Dispatch::PERF_HISTORY_FIX : Dispatch::HISTORY_FIX )); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat(data, settings.historyFixStrength); ValidateConstants(data); // BLUR - data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + data = PushDispatch(methodData, AsUint( settings.enablePerformanceMode ? Dispatch::PERF_BLUR : Dispatch::BLUR )); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[1]); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); + AddFloat4(data, ml::float4(settings.specularLobeTrimmingParameters.A, settings.specularLobeTrimmingParameters.B, settings.specularLobeTrimmingParameters.C, settings.maxAdaptiveRadiusScale)); ValidateConstants(data); // POST_BLUR - data = PushDispatch(methodData, AsUint( settings.enableAntiFirefly ? Dispatch::POST_BLUR_BEFORE_ANTI_FIRELY : Dispatch::POST_BLUR)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + uint32_t postBlur = AsUint( settings.enableAntiFirefly ? + ( settings.enablePerformanceMode ? Dispatch::PERF_POST_BLUR_BEFORE_ANTI_FIRELY : Dispatch::POST_BLUR_BEFORE_ANTI_FIRELY ) : + ( settings.enablePerformanceMode ? Dispatch::PERF_POST_BLUR : Dispatch::POST_BLUR )); + data = PushDispatch(methodData, postBlur); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[2]); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); + AddFloat4(data, ml::float4(settings.specularLobeTrimmingParameters.A, settings.specularLobeTrimmingParameters.B, settings.specularLobeTrimmingParameters.C, settings.maxAdaptiveRadiusScale)); ValidateConstants(data); // ANTI_FIREFLY if (settings.enableAntiFirefly) { - data = PushDispatch(methodData, AsUint(Dispatch::ANTI_FIREFLY)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + data = PushDispatch(methodData, AsUint( settings.enablePerformanceMode ? Dispatch::PERF_ANTI_FIREFLY : Dispatch::ANTI_FIREFLY )); + AddSharedConstants_Reblur(methodData, settings, data); ValidateConstants(data); } // TEMPORAL_STABILIZATION - data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_STABILIZATION)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + data = PushDispatch(methodData, AsUint( settings.enablePerformanceMode ? Dispatch::PERF_TEMPORAL_STABILIZATION : Dispatch::TEMPORAL_STABILIZATION )); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat4x4(data, m_WorldToClipPrev); AddFloat4x4(data, m_ViewToWorld); AddFloat4(data, m_CameraDelta); - AddFloat4(data, diffAntilag1 ); - AddFloat4(data, diffAntilag2 ); + AddFloat4(data, antilagMinMaxThreshold ); + AddFloat2(data, settings.antilagIntensitySettings.sigmaScale, settings.antilagHitDistanceSettings.sigmaScale ); AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); AddFloat(data, settings.stabilizationStrength); ValidateConstants(data); @@ -384,20 +434,21 @@ void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuse(const MethodData& methodData) if (m_CommonSettings.splitScreen > 0.0f) { data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddUint(data, diffCheckerboard); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat(data, m_CommonSettings.splitScreen); + AddUint(data, diffCheckerboard); + AddUint(data, specCheckerboard); ValidateConstants(data); } } -void nrd::DenoiserImpl::AddSharedConstants_ReblurDiffuse(const MethodData& methodData, const ReblurDiffuseSettings& settings, Constant*& data) +void nrd::DenoiserImpl::AddSharedConstants_Reblur(const MethodData& methodData, const ReblurSettings& settings, Constant*& data) { NRD_DECLARE_DIMS; uint32_t maxAccumulatedFrameNum = ml::Min(settings.maxAccumulatedFrameNum, REBLUR_MAX_HISTORY_FRAME_NUM); - float blurRadius = settings.enableReferenceAccumulation ? 0.0f : (settings.blurRadius * GetMinResolutionScale()); - ml::float4 diffHitDistParams = ml::float4(settings.hitDistanceParameters.A, settings.hitDistanceParameters.B, settings.hitDistanceParameters.C, settings.hitDistanceParameters.D); + float blurRadius = settings.enableReferenceAccumulation ? 0.0f : settings.blurRadius; + ml::float4 hitDistParams = ml::float4(settings.hitDistanceParameters.A, settings.hitDistanceParameters.B, settings.hitDistanceParameters.C, settings.hitDistanceParameters.D); // DRS will increase reprojected values, needed for stability, compensated by blur radius adjustment float unproject = 1.0f / (0.5f * rectH * m_ProjectY); @@ -405,7 +456,7 @@ void nrd::DenoiserImpl::AddSharedConstants_ReblurDiffuse(const MethodData& metho AddFloat4x4(data, m_ViewToClip); AddFloat4(data, m_Frustum); - AddFloat4(data, diffHitDistParams); + AddFloat4(data, hitDistParams); AddFloat4(data, ml::float4(m_ViewDirection.x, m_ViewDirection.y, m_ViewDirection.z, 0.0f)); AddFloat2(data, 1.0f / float(screenW), 1.0f / float(screenH)); @@ -418,25 +469,34 @@ void nrd::DenoiserImpl::AddSharedConstants_ReblurDiffuse(const MethodData& metho AddFloat2(data, float(rectW) / float(screenW), float(rectH) / float(screenH)); AddFloat2(data, float(m_CommonSettings.inputSubrectOrigin[0]) / float(screenW), float(m_CommonSettings.inputSubrectOrigin[1]) / float(screenH)); - AddUint2(data, m_CommonSettings.inputSubrectOrigin[0], m_CommonSettings.inputSubrectOrigin[1]); + AddFloat2(data, settings.antilagIntensitySettings.sensitivityToDarkness, settings.antilagHitDistanceSettings.sensitivityToDarkness); + AddUint2(data, m_CommonSettings.inputSubrectOrigin[0], m_CommonSettings.inputSubrectOrigin[1]); AddFloat(data, settings.enableReferenceAccumulation ? 1.0f : 0.0f); AddFloat(data, m_IsOrtho); + AddFloat(data, unproject); AddFloat(data, m_CommonSettings.debug); - AddFloat(data, m_CommonSettings.denoisingRange); AddFloat(data, settings.planeDistanceSensitivity); + AddFloat(data, m_FrameRateScale); AddFloat(data, blurRadius); - AddFloat(data, float( settings.enableReferenceAccumulation ? REBLUR_MAX_HISTORY_FRAME_NUM : maxAccumulatedFrameNum )); AddFloat(data, settings.residualNoiseLevel); + AddFloat(data, m_JitterDelta); - AddFloat(data, 0.0f); + AddFloat(data, settings.inputMix); + AddFloat(data, settings.minConvergedStateBaseRadiusScale); + AddFloat(data, settings.lobeAngleFraction); + AddFloat(data, settings.roughnessFraction); + AddFloat(data, settings.responsiveAccumulationRoughnessThreshold); AddUint(data, m_CommonSettings.isMotionVectorInWorldSpace ? 1 : 0); AddUint(data, m_CommonSettings.frameIndex); + AddUint(data, m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE ? 1 : 0); - AddUint(data, settings.materialMask); + AddUint(data, settings.enableMaterialTestForDiffuse ? 1 : 0); + AddUint(data, settings.enableMaterialTestForSpecular ? 1 : 0); + AddUint(data, 0); } diff --git a/Source/Methods/Reblur_DiffuseDirectionalOcclusion.hpp b/Source/Methods/Reblur_DiffuseDirectionalOcclusion.hpp index a2aa883..b58b801 100644 --- a/Source/Methods/Reblur_DiffuseDirectionalOcclusion.hpp +++ b/Source/Methods/Reblur_DiffuseDirectionalOcclusion.hpp @@ -10,18 +10,19 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w, uint16_t h) { - #define DENOISER_NAME "REBLUR::DirectionalOcclusion" - #define MIP_NUM 5 + #define METHOD_NAME REBLUR_DirectionalOcclusion #define DIFF_TEMP1 AsUint(Transient::DIFF_HISTORY_STABILIZED) // valid before HistoryFix #define DIFF_TEMP2 AsUint(ResourceType::OUT_DIFF_DIRECTION_HITDIST) // valid after HistoryFix enum class Permanent { - PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS = PERMANENT_POOL_START, + PREV_VIEWZ_DIFFACCUMSPEED = PERMANENT_POOL_START, + PREV_NORMAL_SPECACCUMSPEED, DIFF_HISTORY, }; - m_PermanentPool.push_back( {Format::RG32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); enum class Transient @@ -35,11 +36,11 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); m_TransientPool.push_back( {Format::R8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, MIP_NUM} ); - m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, MIP_NUM} ); + m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, REBLUR_MIP_NUM} ); + m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, REBLUR_MIP_NUM} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - SetSharedConstants(1, 3, 8, 16); + REBLUR_DECLARE_SHARED_CONSTANT_NUM; PushPass("Pre-blur"); { @@ -49,7 +50,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( DIFF_TEMP1 ); - AddDispatch( REBLUR_Diffuse_PreBlur, SumConstants(1, 1, 0, 3), 16, 1 ); + AddDispatch( REBLUR_Diffuse_PreBlur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_PreBlur, SumConstants(1, 2, 0, 2), 16, 1 ); } PushPass("Pre-blur (advanced)"); @@ -61,7 +63,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( DIFF_TEMP1 ); - AddDispatch( REBLUR_Diffuse_PreBlurAdvanced, SumConstants(1, 1, 0, 3), 16, 1 ); + AddDispatch( REBLUR_Diffuse_PreBlurAdvanced, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_PreBlurAdvanced, SumConstants(1, 2, 0, 2), 16, 1 ); } PushPass("Temporal accumulation"); @@ -69,7 +72,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( AsUint(ResourceType::IN_DIFF_DIRECTION_HITDIST) ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); @@ -78,7 +82,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_TemporalAccumulation, SumConstants(3, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalAccumulation, SumConstants(4, 2, 1, 5), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalAccumulation, SumConstants(4, 2, 1, 5), 16, 1 ); } PushPass("Temporal accumulation"); // after Pre-blur @@ -86,7 +91,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( DIFF_TEMP1 ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); @@ -95,7 +101,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_TemporalAccumulation, SumConstants(3, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalAccumulation, SumConstants(4, 2, 1, 5), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalAccumulation, SumConstants(4, 2, 1, 5), 16, 1 ); } PushPass("Temporal accumulation"); // with confidence @@ -103,7 +110,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( AsUint(ResourceType::IN_DIFF_DIRECTION_HITDIST) ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); PushInput( AsUint(ResourceType::IN_DIFF_CONFIDENCE) ); @@ -113,7 +121,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_TemporalAccumulationWithConfidence, SumConstants(3, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 16, 1 ); } PushPass("Temporal accumulation"); // with confidence, after Pre-blur @@ -121,7 +130,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( DIFF_TEMP1 ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); PushInput( AsUint(ResourceType::IN_DIFF_CONFIDENCE) ); @@ -131,7 +141,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_TemporalAccumulationWithConfidence, SumConstants(3, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 16, 1 ); } PushPass("Mip generation"); @@ -139,7 +150,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushInput( AsUint(Transient::DIFF_ACCUMULATED) ); PushInput( AsUint(Transient::SCALED_VIEWZ) ); - for( uint16_t i = 1; i < MIP_NUM; i++ ) + for( uint16_t i = 1; i < REBLUR_MIP_NUM; i++ ) { PushOutput( AsUint(Transient::DIFF_ACCUMULATED), i, 1 ); PushOutput( AsUint(Transient::SCALED_VIEWZ), i, 1 ); @@ -151,14 +162,15 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushPass("History fix"); { PushInput( AsUint(Transient::INTERNAL_DATA) ); - PushInput( AsUint(Transient::SCALED_VIEWZ), 0, MIP_NUM ); - PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, MIP_NUM - 1 ); + PushInput( AsUint(Transient::SCALED_VIEWZ), 0, REBLUR_MIP_NUM ); + PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); PushInput( AsUint(ResourceType::OUT_DIFF_DIRECTION_HITDIST) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED), 0, 1 ); PushOutput( AsUint(Transient::DIFF_HISTORY_STABILIZED) ); AddDispatch( REBLUR_Diffuse_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Blur"); @@ -171,7 +183,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( DIFF_TEMP2 ); - AddDispatch( REBLUR_Diffuse_Blur, SumConstants(1, 1, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Diffuse_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); @@ -184,7 +197,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Permanent::DIFF_HISTORY) ); - AddDispatch( REBLUR_Diffuse_PostBlur, SumConstants(1, 1, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Diffuse_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); // before Anti-Firefly @@ -197,7 +211,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_Diffuse_PostBlur, SumConstants(1, 1, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Diffuse_PostBlur, SumConstants(1, 1, 0, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_PostBlur, SumConstants(1, 1, 0, 1), 16, 1 ); } PushPass("Anti-firefly"); @@ -209,6 +224,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(Permanent::DIFF_HISTORY) ); AddDispatch( REBLUR_Diffuse_AntiFirefly, SumConstants(0, 0, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_AntiFirefly, SumConstants(0, 0, 0, 0), 16, 1 ); } PushPass("Temporal stabilization"); @@ -221,10 +237,12 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushInput( AsUint(Transient::DIFF_HISTORY_STABILIZED) ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); - PushOutput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushOutput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushOutput( AsUint(ResourceType::OUT_DIFF_DIRECTION_HITDIST) ); - AddDispatch( REBLUR_Diffuse_TemporalStabilization, SumConstants(2, 3, 1, 1), 16, 1 ); + AddDispatch( REBLUR_Diffuse_TemporalStabilization, SumConstants(2, 2, 2, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_Diffuse_TemporalStabilization, SumConstants(2, 2, 2, 1), 16, 1 ); } PushPass("Split screen"); @@ -234,159 +252,12 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseDirectionalOcclusion(uint16_t w PushOutput( AsUint(ResourceType::OUT_DIFF_DIRECTION_HITDIST) ); - AddDispatch( REBLUR_Diffuse_SplitScreen, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Diffuse_SplitScreen, SumConstants(0, 0, 0, 3), 16, 1 ); } - #undef DENOISER_NAME - #undef MIP_NUM + #undef METHOD_NAME #undef DIFF_TEMP1 #undef DIFF_TEMP2 - return sizeof(ReblurDiffuseSettings); -} - -void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuseDirectionalOcclusion(const MethodData& methodData) -{ - enum class Dispatch - { - PRE_BLUR, - PRE_BLUR_ADVANCED, - TEMPORAL_ACCUMULATION, - TEMPORAL_ACCUMULATION_AFTER_PRE_BLUR, - TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, - TEMPORAL_ACCUMULATION_WITH_CONFIDENCE_AFTER_PRE_BLUR, - MIP_GENERATION, - HISTORY_FIX, - BLUR, - POST_BLUR, - POST_BLUR_BEFORE_ANTI_FIRELY, - ANTI_FIREFLY, - TEMPORAL_STABILIZATION, - SPLIT_SCREEN, - }; - - const ReblurDiffuseSettings& settings = methodData.settings.diffuseReblur; - - bool skipPrePass = settings.prePassMode == PrePassMode::OFF && settings.checkerboardMode == CheckerboardMode::OFF; - float normalWeightStrictness = ml::Lerp( 0.1f, 1.0f, settings.normalWeightStrictness ); - - uint32_t diffCheckerboard = ((uint32_t)settings.checkerboardMode + 2) % 3; - ml::float4 diffAntilag1 = ml::float4(settings.antilagIntensitySettings.sigmaScale / GetMinResolutionScale(), settings.antilagHitDistanceSettings.sigmaScale / GetMinResolutionScale(), settings.antilagIntensitySettings.sensitivityToDarkness, settings.antilagHitDistanceSettings.sensitivityToDarkness); - ml::float4 diffAntilag2 = ml::float4(settings.antilagIntensitySettings.thresholdMin / GetMinResolutionScale(), settings.antilagHitDistanceSettings.thresholdMin / GetMinResolutionScale(), settings.antilagIntensitySettings.thresholdMax, settings.antilagHitDistanceSettings.thresholdMax); - - if (!settings.antilagIntensitySettings.enable || settings.enableReferenceAccumulation) - { - diffAntilag2.x = 99998.0f; - diffAntilag2.z = 99999.0f; - } - - if (!settings.antilagHitDistanceSettings.enable || settings.enableReferenceAccumulation) - { - diffAntilag2.y = 99998.0f; - diffAntilag2.w = 99999.0f; - } - - NRD_DECLARE_DIMS; - - // SPLIT_SCREEN (passthrough) - if (m_CommonSettings.splitScreen >= 1.0f) - { - Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddUint(data, diffCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - - return; - } - - // PRE_BLUR - if (!skipPrePass) - { - uint32_t preBlurPass = AsUint(Dispatch::PRE_BLUR) + ml::Max((int32_t)settings.prePassMode - 1, 0); - Constant* data = PushDispatch(methodData, preBlurPass); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[0]); - AddUint(data, diffCheckerboard); - AddUint(data, settings.prePassMode == PrePassMode::OFF ? 0 : 1); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - } - - // TEMPORAL_ACCUMULATION - Constant* data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_ACCUMULATION) + (m_CommonSettings.isHistoryConfidenceInputsAvailable ? 2 : 0) + (skipPrePass ? 0 : 1)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddFloat4x4(data, m_WorldToViewPrev); - AddFloat4x4(data, m_WorldToClipPrev); - AddFloat4x4(data, m_ViewToWorld); - AddFloat4(data, m_FrustumPrev); - AddFloat4(data, m_CameraDelta); - AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); - AddFloat(data, m_CheckerboardResolveAccumSpeed); - AddFloat(data, settings.enableReferenceAccumulation ? 0.005f : m_CommonSettings.disocclusionThreshold ); - AddUint(data, diffCheckerboard); - AddUint(data, skipPrePass ? 0 : 1); - ValidateConstants(data); - - // MIP_GENERATION - data = PushDispatch(methodData, AsUint(Dispatch::MIP_GENERATION)); - AddUint2(data, rectW, rectH); - AddFloat(data, m_CommonSettings.denoisingRange); - AddFloat(data, m_CommonSettings.debug); - ValidateConstants(data); - - // HISTORY_FIX - data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_FIX)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddFloat(data, settings.historyFixStrength); - ValidateConstants(data); - - // BLUR - data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[1]); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // POST_BLUR - data = PushDispatch(methodData, AsUint( settings.enableAntiFirefly ? Dispatch::POST_BLUR_BEFORE_ANTI_FIRELY : Dispatch::POST_BLUR)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[2]); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // ANTI_FIREFLY - if (settings.enableAntiFirefly) - { - data = PushDispatch(methodData, AsUint(Dispatch::ANTI_FIREFLY)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - ValidateConstants(data); - } - - // TEMPORAL_STABILIZATION - data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_STABILIZATION)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddFloat4x4(data, m_WorldToClipPrev); - AddFloat4x4(data, m_ViewToWorld); - AddFloat4(data, m_CameraDelta); - AddFloat4(data, diffAntilag1 ); - AddFloat4(data, diffAntilag2 ); - AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); - AddFloat(data, settings.stabilizationStrength); - ValidateConstants(data); - - // SPLIT_SCREEN - if (m_CommonSettings.splitScreen > 0.0f) - { - data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddUint(data, diffCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - } + return sizeof(ReblurSettings); } diff --git a/Source/Methods/Reblur_DiffuseOcclusion.hpp b/Source/Methods/Reblur_DiffuseOcclusion.hpp index 0056739..7e35d9f 100644 --- a/Source/Methods/Reblur_DiffuseOcclusion.hpp +++ b/Source/Methods/Reblur_DiffuseOcclusion.hpp @@ -10,15 +10,16 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t h) { - #define DENOISER_NAME "REBLUR::DiffuseOcclusion" - #define MIP_NUM 5 + #define METHOD_NAME REBLUR_DiffuseOcclusion enum class Permanent { - PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS = PERMANENT_POOL_START, + PREV_VIEWZ_DIFFACCUMSPEED = PERMANENT_POOL_START, + PREV_NORMAL_SPECACCUMSPEED, }; - m_PermanentPool.push_back( {Format::RG32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); enum class Transient { @@ -30,17 +31,18 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t m_TransientPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); m_TransientPool.push_back( {Format::RG8_UNORM, w, h, 1} ); - m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, MIP_NUM} ); + m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, REBLUR_MIP_NUM} ); m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, 1} ); - SetSharedConstants(1, 3, 8, 16); + REBLUR_DECLARE_SHARED_CONSTANT_NUM; PushPass("Temporal accumulation"); { PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( AsUint(ResourceType::IN_DIFF_HITDIST) ); PushInput( AsUint(ResourceType::OUT_DIFF_HITDIST) ); @@ -48,7 +50,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseOcclusion_TemporalAccumulation, SumConstants(3, 2, 1, 3), 16, 1 ); + AddDispatch( REBLUR_DiffuseOcclusion_TemporalAccumulation, SumConstants(4, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseOcclusion_TemporalAccumulation, SumConstants(4, 2, 1, 4), 16, 1 ); } PushPass("Temporal accumulation"); @@ -56,7 +59,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushInput( AsUint(ResourceType::IN_DIFF_HITDIST) ); PushInput( AsUint(ResourceType::OUT_DIFF_HITDIST) ); PushInput( AsUint(ResourceType::IN_DIFF_CONFIDENCE) ); @@ -65,14 +69,15 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseOcclusion_TemporalAccumulationWithConfidence, SumConstants(3, 2, 1, 3), 16, 1 ); + AddDispatch( REBLUR_DiffuseOcclusion_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 4), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseOcclusion_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 4), 16, 1 ); } PushPass("Mip generation"); { PushInput( AsUint(Transient::DIFF_ACCUMULATED) ); - for( uint16_t i = 1; i < MIP_NUM; i++ ) + for( uint16_t i = 1; i < REBLUR_MIP_NUM; i++ ) PushOutput( AsUint(Transient::DIFF_ACCUMULATED), i, 1 ); AddDispatch( NRD_MipGeneration_Float2, SumConstants(0, 0, 1, 2, false), 16, 2 ); @@ -81,11 +86,12 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t PushPass("History fix"); { PushInput( AsUint(Transient::INTERNAL_DATA) ); - PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, MIP_NUM - 1 ); + PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED), 0, 1 ); AddDispatch( REBLUR_DiffuseOcclusion_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseOcclusion_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Blur"); @@ -97,7 +103,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::DIFF_TEMP) ); - AddDispatch( REBLUR_DiffuseOcclusion_Blur, SumConstants(1, 1, 0, 2), 16, 1 ); + AddDispatch( REBLUR_DiffuseOcclusion_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseOcclusion_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); @@ -107,10 +114,12 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t PushInput( AsUint(Transient::DIFF_TEMP) ); PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); - PushOutput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushOutput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); PushOutput( AsUint(ResourceType::OUT_DIFF_HITDIST) ); - AddDispatch( REBLUR_DiffuseOcclusion_PostBlur, SumConstants(1, 1, 0, 2), 16, 1 ); + AddDispatch( REBLUR_DiffuseOcclusion_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseOcclusion_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Split screen"); @@ -120,33 +129,50 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseOcclusion(uint16_t w, uint16_t PushOutput( AsUint(ResourceType::OUT_DIFF_HITDIST) ); - AddDispatch( REBLUR_DiffuseOcclusion_SplitScreen, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( REBLUR_DiffuseOcclusion_SplitScreen, SumConstants(0, 0, 0, 3), 16, 1 ); } - #undef DENOISER_NAME - #undef MIP_NUM + #undef METHOD_NAME - return sizeof(ReblurDiffuseSettings); + return sizeof(ReblurSettings); } -void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuseOcclusion(const MethodData& methodData) +void nrd::DenoiserImpl::UpdateMethod_ReblurOcclusion(const MethodData& methodData) { enum class Dispatch { TEMPORAL_ACCUMULATION, + PERF_TEMPORAL_ACCUMULATION, TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, + PERF_TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, MIP_GENERATION, HISTORY_FIX, + PERF_HISTORY_FIX, BLUR, + PERF_BLUR, POST_BLUR, + PERF_POST_BLUR, SPLIT_SCREEN, }; - const ReblurDiffuseSettings& settings = methodData.settings.diffuseReblur; + const ReblurSettings& settings = methodData.settings.reblur; - float normalWeightStrictness = ml::Lerp( 0.1f, 1.0f, settings.normalWeightStrictness ); + uint32_t specCheckerboard = 2; + uint32_t diffCheckerboard = 2; - uint32_t diffCheckerboard = ((uint32_t)settings.checkerboardMode + 2) % 3; + switch (settings.checkerboardMode) + { + case nrd::CheckerboardMode::BLACK: + diffCheckerboard = 0; + specCheckerboard = 1; + break; + case nrd::CheckerboardMode::WHITE: + diffCheckerboard = 1; + specCheckerboard = 0; + break; + default: + break; + } NRD_DECLARE_DIMS; @@ -154,26 +180,30 @@ void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuseOcclusion(const MethodData& me if (m_CommonSettings.splitScreen >= 1.0f) { Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddUint(data, diffCheckerboard); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat(data, m_CommonSettings.splitScreen); + AddUint(data, diffCheckerboard); + AddUint(data, specCheckerboard); ValidateConstants(data); return; } // TEMPORAL_ACCUMULATION - Constant* data = PushDispatch(methodData, AsUint( m_CommonSettings.isHistoryConfidenceInputsAvailable ? Dispatch::TEMPORAL_ACCUMULATION_WITH_CONFIDENCE : Dispatch::TEMPORAL_ACCUMULATION )); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + uint32_t passIndex = AsUint(Dispatch::TEMPORAL_ACCUMULATION) + (m_CommonSettings.isHistoryConfidenceInputsAvailable ? 1 : 0) * 2 + (settings.enablePerformanceMode ? 1 : 0); + Constant* data = PushDispatch(methodData, passIndex); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat4x4(data, m_WorldToViewPrev); AddFloat4x4(data, m_WorldToClipPrev); AddFloat4x4(data, m_ViewToWorld); + AddFloat4x4(data, m_WorldToClip); AddFloat4(data, m_FrustumPrev); AddFloat4(data, m_CameraDelta); AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); AddFloat(data, m_CheckerboardResolveAccumSpeed); AddFloat(data, settings.enableReferenceAccumulation ? 0.005f : m_CommonSettings.disocclusionThreshold ); AddUint(data, diffCheckerboard); + AddUint(data, specCheckerboard); ValidateConstants(data); // MIP_GENERATION @@ -184,36 +214,35 @@ void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuseOcclusion(const MethodData& me ValidateConstants(data); // HISTORY_FIX - data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_FIX)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + data = PushDispatch(methodData, AsUint( settings.enablePerformanceMode ? Dispatch::PERF_HISTORY_FIX : Dispatch::HISTORY_FIX )); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat(data, settings.historyFixStrength); ValidateConstants(data); // BLUR - data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + data = PushDispatch(methodData, AsUint( settings.enablePerformanceMode ? Dispatch::PERF_BLUR : Dispatch::BLUR )); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[1]); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); + AddFloat4(data, ml::float4(settings.specularLobeTrimmingParameters.A, settings.specularLobeTrimmingParameters.B, settings.specularLobeTrimmingParameters.C, settings.maxAdaptiveRadiusScale)); ValidateConstants(data); // POST_BLUR - data = PushDispatch(methodData, AsUint(Dispatch::POST_BLUR)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); + data = PushDispatch(methodData, AsUint( settings.enablePerformanceMode ? Dispatch::PERF_POST_BLUR : Dispatch::POST_BLUR )); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[2]); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); + AddFloat4(data, ml::float4(settings.specularLobeTrimmingParameters.A, settings.specularLobeTrimmingParameters.B, settings.specularLobeTrimmingParameters.C, settings.maxAdaptiveRadiusScale)); ValidateConstants(data); // SPLIT_SCREEN if (m_CommonSettings.splitScreen > 0.0f) { data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuse(methodData, settings, data); - AddUint(data, diffCheckerboard); + AddSharedConstants_Reblur(methodData, settings, data); AddFloat(data, m_CommonSettings.splitScreen); + AddUint(data, diffCheckerboard); + AddUint(data, specCheckerboard); ValidateConstants(data); } } diff --git a/Source/Methods/Reblur_DiffuseSpecular.hpp b/Source/Methods/Reblur_DiffuseSpecular.hpp index 0173496..249ec13 100644 --- a/Source/Methods/Reblur_DiffuseSpecular.hpp +++ b/Source/Methods/Reblur_DiffuseSpecular.hpp @@ -10,8 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h) { - #define DENOISER_NAME "REBLUR::DiffuseSpecular" - #define MIP_NUM 5 + #define METHOD_NAME REBLUR_DiffuseSpecular #define DIFF_TEMP1 AsUint(Transient::DIFF_HISTORY_STABILIZED) // valid before HistoryFix #define SPEC_TEMP1 AsUint(Transient::SPEC_HISTORY_STABILIZED) // valid before HistoryFix #define DIFF_TEMP2 AsUint(ResourceType::OUT_DIFF_RADIANCE_HITDIST) // valid after HistoryFix @@ -19,12 +18,16 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h enum class Permanent { - PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS = PERMANENT_POOL_START, + PREV_VIEWZ_DIFFACCUMSPEED = PERMANENT_POOL_START, + PREV_NORMAL_SPECACCUMSPEED, + PREV_ROUGHNESS, DIFF_HISTORY, SPEC_HISTORY, }; - m_PermanentPool.push_back( {Format::RG32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); @@ -41,13 +44,13 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h 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::R16_SFLOAT, w, h, MIP_NUM} ); - m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, MIP_NUM} ); + m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, REBLUR_MIP_NUM} ); + m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, REBLUR_MIP_NUM} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, MIP_NUM} ); + m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, REBLUR_MIP_NUM} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - SetSharedConstants(1, 4, 8, 16); + REBLUR_DECLARE_SHARED_CONSTANT_NUM; PushPass("Pre-blur"); { @@ -59,7 +62,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( DIFF_TEMP1 ); PushOutput( SPEC_TEMP1 ); - AddDispatch( REBLUR_DiffuseSpecular_PreBlur, SumConstants(1, 2, 0, 5), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_PreBlur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_PreBlur, SumConstants(1, 2, 0, 2), 16, 1 ); } PushPass("Pre-blur (advanced)"); @@ -74,7 +78,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( DIFF_TEMP1 ); PushOutput( SPEC_TEMP1 ); - AddDispatch( REBLUR_DiffuseSpecular_PreBlurAdvanced, SumConstants(1, 2, 0, 5), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_PreBlurAdvanced, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_PreBlurAdvanced, SumConstants(1, 2, 0, 2), 16, 1 ); } PushPass("Temporal accumulation"); @@ -82,7 +87,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_DIFF_RADIANCE_HITDIST) ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); PushInput( AsUint(ResourceType::IN_SPEC_RADIANCE_HITDIST) ); @@ -94,7 +101,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseSpecular_TemporalAccumulation, SumConstants(4, 2, 1, 6), 8, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); } PushPass("Temporal accumulation"); // after Pre-blur @@ -102,7 +110,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( DIFF_TEMP1 ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); PushInput( SPEC_TEMP1 ); @@ -114,7 +124,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseSpecular_TemporalAccumulation, SumConstants(4, 2, 1, 6), 8, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); } PushPass("Temporal accumulation"); // with confidence @@ -122,7 +133,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_DIFF_RADIANCE_HITDIST) ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); PushInput( AsUint(ResourceType::IN_SPEC_RADIANCE_HITDIST) ); @@ -136,7 +149,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 6), 8, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); } PushPass("Temporal accumulation"); // with confidence, after Pre-blur @@ -144,7 +158,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( DIFF_TEMP1 ); PushInput( AsUint(Permanent::DIFF_HISTORY) ); PushInput( SPEC_TEMP1 ); @@ -158,7 +174,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 6), 8, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); } PushPass("Mip generation"); @@ -167,7 +184,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushInput( AsUint(Transient::SPEC_ACCUMULATED) ); PushInput( AsUint(Transient::SCALED_VIEWZ) ); - for( uint16_t i = 1; i < MIP_NUM; i++ ) + for( uint16_t i = 1; i < REBLUR_MIP_NUM; i++ ) { PushOutput( AsUint(Transient::DIFF_ACCUMULATED), i, 1 ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED), i, 1 ); @@ -180,10 +197,10 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushPass("History fix"); { PushInput( AsUint(Transient::INTERNAL_DATA) ); - PushInput( AsUint(Transient::SCALED_VIEWZ), 0, MIP_NUM ); - PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, MIP_NUM - 1 ); + PushInput( AsUint(Transient::SCALED_VIEWZ), 0, REBLUR_MIP_NUM ); + PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); PushInput( AsUint(ResourceType::OUT_DIFF_RADIANCE_HITDIST) ); - PushInput( AsUint(Transient::SPEC_ACCUMULATED), 1, MIP_NUM - 1 ); + PushInput( AsUint(Transient::SPEC_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); PushInput( AsUint(ResourceType::OUT_SPEC_RADIANCE_HITDIST) ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED), 0, 1 ); @@ -191,7 +208,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( AsUint(Transient::SPEC_ACCUMULATED), 0, 1 ); PushOutput( AsUint(Transient::SPEC_HISTORY_STABILIZED) ); - AddDispatch( REBLUR_DiffuseSpecular_HistoryFix, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Blur"); @@ -206,7 +224,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( DIFF_TEMP2 ); PushOutput( SPEC_TEMP2 ); - AddDispatch( REBLUR_DiffuseSpecular_Blur, SumConstants(1, 2, 0, 4), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); @@ -221,7 +240,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( AsUint(Permanent::DIFF_HISTORY) ); PushOutput( AsUint(Permanent::SPEC_HISTORY) ); - AddDispatch( REBLUR_DiffuseSpecular_PostBlur, SumConstants(1, 2, 0, 4), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); // before Anti-Firefly @@ -236,7 +256,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseSpecular_PostBlur, SumConstants(1, 2, 0, 4), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Anti-firefly"); @@ -250,6 +271,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushOutput( AsUint(Permanent::SPEC_HISTORY) ); AddDispatch( REBLUR_DiffuseSpecular_AntiFirefly, SumConstants(0, 0, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_AntiFirefly, SumConstants(0, 0, 0, 0), 16, 1 ); } PushPass("Temporal stabilization"); @@ -264,11 +286,14 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h PushInput( AsUint(Transient::SPEC_HISTORY_STABILIZED) ); PushInput( AsUint(Permanent::SPEC_HISTORY) ); - PushOutput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushOutput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_ROUGHNESS) ); PushOutput( AsUint(ResourceType::OUT_DIFF_RADIANCE_HITDIST) ); PushOutput( AsUint(ResourceType::OUT_SPEC_RADIANCE_HITDIST) ); - AddDispatch( REBLUR_DiffuseSpecular_TemporalStabilization, SumConstants(2, 5, 1, 2), 8, 1 ); + AddDispatch( REBLUR_DiffuseSpecular_TemporalStabilization, SumConstants(2, 2, 2, 1), 8, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecular_TemporalStabilization, SumConstants(2, 2, 2, 1), 8, 1 ); } PushPass("Split screen"); @@ -283,254 +308,11 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecular(uint16_t w, uint16_t h AddDispatch( REBLUR_DiffuseSpecular_SplitScreen, SumConstants(0, 0, 0, 3), 16, 1 ); } - #undef DENOISER_NAME - #undef MIP_NUM + #undef METHOD_NAME #undef DIFF_TEMP1 #undef SPEC_TEMP1 #undef DIFF_TEMP2 #undef SPEC_TEMP2 - return sizeof(ReblurDiffuseSpecularSettings); -} - -void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuseSpecular(const MethodData& methodData) -{ - enum class Dispatch - { - PRE_BLUR, - PRE_BLUR_ADVANCED, - TEMPORAL_ACCUMULATION, - TEMPORAL_ACCUMULATION_AFTER_PRE_BLUR, - TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, - TEMPORAL_ACCUMULATION_WITH_CONFIDENCE_AFTER_PRE_BLUR, - MIP_GENERATION, - HISTORY_FIX, - BLUR, - POST_BLUR, - POST_BLUR_BEFORE_ANTI_FIRELY, - ANTI_FIREFLY, - TEMPORAL_STABILIZATION, - SPLIT_SCREEN, - }; - - const ReblurDiffuseSpecularSettings& settings = methodData.settings.diffuseSpecularReblur; - const ReblurDiffuseSettings& diffSettings = settings.diffuse; - const ReblurSpecularSettings& specSettings = settings.specular; - - bool enableReferenceAccumulation = diffSettings.enableReferenceAccumulation && specSettings.enableReferenceAccumulation; - bool enablePrePass = diffSettings.prePassMode != PrePassMode::OFF && specSettings.prePassMode != PrePassMode::OFF; - bool skipPrePass = !enablePrePass && diffSettings.checkerboardMode == CheckerboardMode::OFF && specSettings.checkerboardMode == CheckerboardMode::OFF; - bool enableAntiFirefly = diffSettings.enableAntiFirefly && specSettings.enableAntiFirefly; - float normalWeightStrictness = ml::Lerp( 0.1f, 1.0f, ml::Min( diffSettings.normalWeightStrictness, specSettings.normalWeightStrictness ) ); - - uint32_t diffCheckerboard = ((uint32_t)diffSettings.checkerboardMode + 2) % 3; - ml::float4 diffAntilag1 = ml::float4(diffSettings.antilagIntensitySettings.sigmaScale / GetMinResolutionScale(), diffSettings.antilagHitDistanceSettings.sigmaScale / GetMinResolutionScale(), diffSettings.antilagIntensitySettings.sensitivityToDarkness, diffSettings.antilagHitDistanceSettings.sensitivityToDarkness); - ml::float4 diffAntilag2 = ml::float4(diffSettings.antilagIntensitySettings.thresholdMin / GetMinResolutionScale(), diffSettings.antilagHitDistanceSettings.thresholdMin / GetMinResolutionScale(), diffSettings.antilagIntensitySettings.thresholdMax, diffSettings.antilagHitDistanceSettings.thresholdMax); - float diffBlurRadius = enableReferenceAccumulation ? 0.0f : (diffSettings.blurRadius * GetMinResolutionScale()); - - if (!diffSettings.antilagIntensitySettings.enable || enableReferenceAccumulation) - { - diffAntilag2.x = 99998.0f; - diffAntilag2.z = 99999.0f; - } - - if (!diffSettings.antilagHitDistanceSettings.enable || enableReferenceAccumulation) - { - diffAntilag2.y = 99998.0f; - diffAntilag2.w = 99999.0f; - } - - uint32_t specCheckerboard = ((uint32_t)specSettings.checkerboardMode + 2) % 3; - ml::float4 specTrimmingParams_and_specBlurRadius = ml::float4(specSettings.lobeTrimmingParameters.A, specSettings.lobeTrimmingParameters.B, specSettings.lobeTrimmingParameters.C, enableReferenceAccumulation ? 0.0f : (specSettings.blurRadius * GetMinResolutionScale())); - ml::float4 specAntilag1 = ml::float4(specSettings.antilagIntensitySettings.sigmaScale / GetMinResolutionScale(), specSettings.antilagHitDistanceSettings.sigmaScale / GetMinResolutionScale(), specSettings.antilagIntensitySettings.sensitivityToDarkness, specSettings.antilagHitDistanceSettings.sensitivityToDarkness); - ml::float4 specAntilag2 = ml::float4(specSettings.antilagIntensitySettings.thresholdMin / GetMinResolutionScale(), specSettings.antilagHitDistanceSettings.thresholdMin / GetMinResolutionScale(), specSettings.antilagIntensitySettings.thresholdMax, specSettings.antilagHitDistanceSettings.thresholdMax); - - if (!specSettings.antilagIntensitySettings.enable || enableReferenceAccumulation) - { - specAntilag2.x = 99998.0f; - specAntilag2.z = 99999.0f; - } - - if (!specSettings.antilagHitDistanceSettings.enable || enableReferenceAccumulation) - { - specAntilag2.y = 99998.0f; - specAntilag2.w = 99999.0f; - } - - NRD_DECLARE_DIMS; - - // SPLIT_SCREEN (passthrough) - if (m_CommonSettings.splitScreen >= 1.0f) - { - Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddUint(data, diffCheckerboard); - AddUint(data, specCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - - return; - } - - // PRE_BLUR - if (!skipPrePass) - { - uint32_t preBlurPass = AsUint(Dispatch::PRE_BLUR) + ml::Max(ml::Min((int32_t)diffSettings.prePassMode, (int32_t)specSettings.prePassMode) - 1, 0); - Constant* data = PushDispatch(methodData, preBlurPass); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[0]); - AddFloat4(data, specTrimmingParams_and_specBlurRadius); - AddUint(data, specCheckerboard); - AddFloat(data, diffBlurRadius); - AddUint(data, diffCheckerboard); - AddUint(data, enablePrePass ? 1 : 0); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - } - - // TEMPORAL_ACCUMULATION - Constant* data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_ACCUMULATION) + (m_CommonSettings.isHistoryConfidenceInputsAvailable ? 2 : 0) + (skipPrePass ? 0 : 1)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToViewPrev); - AddFloat4x4(data, m_WorldToClipPrev); - AddFloat4x4(data, m_ViewToWorld); - AddFloat4x4(data, m_WorldToClip); - AddFloat4(data, m_FrustumPrev); - AddFloat4(data, m_CameraDelta); - AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); - AddFloat(data, m_CheckerboardResolveAccumSpeed); - AddFloat(data, enableReferenceAccumulation ? 0.005f : m_CommonSettings.disocclusionThreshold); - AddFloat(data, m_JitterDelta); - AddUint(data, diffCheckerboard); - AddUint(data, specCheckerboard); - AddUint(data, skipPrePass ? 0 : 1); - ValidateConstants(data); - - // MIP_GENERATION - data = PushDispatch(methodData, AsUint(Dispatch::MIP_GENERATION)); - AddUint2(data, rectW, rectH); - AddFloat(data, m_CommonSettings.denoisingRange); - AddFloat(data, m_CommonSettings.debug); - ValidateConstants(data); - - // HISTORY_FIX - data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_FIX)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat(data, diffSettings.historyFixStrength); - AddFloat(data, specSettings.historyFixStrength); - ValidateConstants(data); - - // BLUR - data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[1]); - AddFloat4(data, specTrimmingParams_and_specBlurRadius); - AddFloat(data, specSettings.maxAdaptiveRadiusScale); - AddFloat(data, diffBlurRadius); - AddFloat(data, diffSettings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // POST_BLUR - data = PushDispatch(methodData, AsUint( enableAntiFirefly ? Dispatch::POST_BLUR_BEFORE_ANTI_FIRELY : Dispatch::POST_BLUR)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[2]); - AddFloat4(data, specTrimmingParams_and_specBlurRadius); - AddFloat(data, specSettings.maxAdaptiveRadiusScale); - AddFloat(data, diffBlurRadius); - AddFloat(data, diffSettings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // ANTI_FIREFLY - if (enableAntiFirefly) - { - data = PushDispatch(methodData, AsUint(Dispatch::ANTI_FIREFLY)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - ValidateConstants(data); - } - - // TEMPORAL_STABILIZATION - data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_STABILIZATION)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToClipPrev); - AddFloat4x4(data, m_ViewToWorld); - AddFloat4(data, m_CameraDelta); - AddFloat4(data, diffAntilag1 ); - AddFloat4(data, diffAntilag2 ); - AddFloat4(data, specAntilag1 ); - AddFloat4(data, specAntilag2 ); - AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); - AddFloat(data, settings.diffuse.stabilizationStrength); - AddFloat(data, settings.specular.stabilizationStrength); - ValidateConstants(data); - - // SPLIT_SCREEN - if (m_CommonSettings.splitScreen > 0.0f) - { - data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddUint(data, diffCheckerboard); - AddUint(data, specCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - } -} - -void nrd::DenoiserImpl::AddSharedConstants_ReblurDiffuseSpecular(const MethodData& methodData, const ReblurDiffuseSpecularSettings& settings, Constant*& data) -{ - NRD_DECLARE_DIMS; - - bool enableReferenceAccumulation = settings.diffuse.enableReferenceAccumulation && settings.specular.enableReferenceAccumulation; - uint32_t diffMaxAccumulatedFrameNum = ml::Min(settings.diffuse.maxAccumulatedFrameNum, REBLUR_MAX_HISTORY_FRAME_NUM); - uint32_t specMaxAccumulatedFrameNum = ml::Min(settings.specular.maxAccumulatedFrameNum, REBLUR_MAX_HISTORY_FRAME_NUM); - float planeDistanceSensitivity = ml::Min( settings.diffuse.planeDistanceSensitivity, settings.specular.planeDistanceSensitivity ); - float residualNoiseLevel = ml::Min( settings.diffuse.residualNoiseLevel, settings.specular.residualNoiseLevel ); - ml::float4 diffHitDistParams = ml::float4(settings.diffuse.hitDistanceParameters.A, settings.diffuse.hitDistanceParameters.B, settings.diffuse.hitDistanceParameters.C, settings.diffuse.hitDistanceParameters.D); - ml::float4 specHitDistParams = ml::float4(settings.specular.hitDistanceParameters.A, settings.specular.hitDistanceParameters.B, settings.specular.hitDistanceParameters.C, settings.specular.hitDistanceParameters.D); - - // DRS will increase reprojected values, needed for stability, compensated by blur radius adjustment - float unproject = 1.0f / (0.5f * rectH * m_ProjectY); - - AddFloat4x4(data, m_ViewToClip); - - AddFloat4(data, m_Frustum); - AddFloat4(data, diffHitDistParams); - AddFloat4(data, specHitDistParams); - AddFloat4(data, ml::float4(m_ViewDirection.x, m_ViewDirection.y, m_ViewDirection.z, 0.0f)); - - AddFloat2(data, 1.0f / float(screenW), 1.0f / float(screenH)); - AddFloat2(data, float(screenW), float(screenH)); - - AddFloat2(data, 1.0f / float(rectW), 1.0f / float(rectH)); - AddFloat2(data, float(rectW), float(rectH)); - - AddFloat2(data, float(rectWprev), float(rectHprev)); - AddFloat2(data, float(rectW) / float(screenW), float(rectH) / float(screenH)); - - AddFloat2(data, float(m_CommonSettings.inputSubrectOrigin[0]) / float(screenW), float(m_CommonSettings.inputSubrectOrigin[1]) / float(screenH)); - AddUint2(data, m_CommonSettings.inputSubrectOrigin[0], m_CommonSettings.inputSubrectOrigin[1]); - - AddFloat(data, enableReferenceAccumulation ? 1.0f : 0.0f); - AddFloat(data, m_IsOrtho); - AddFloat(data, unproject); - AddFloat(data, m_CommonSettings.debug); - - AddFloat(data, m_CommonSettings.denoisingRange); - AddFloat(data, planeDistanceSensitivity); - AddFloat(data, m_FrameRateScale); - AddFloat(data, residualNoiseLevel); - - AddFloat(data, float( enableReferenceAccumulation ? REBLUR_MAX_HISTORY_FRAME_NUM : diffMaxAccumulatedFrameNum ) ); - AddFloat(data, float( enableReferenceAccumulation ? REBLUR_MAX_HISTORY_FRAME_NUM : specMaxAccumulatedFrameNum) ); - AddFloat(data, 0.0f); - AddUint(data, m_CommonSettings.isMotionVectorInWorldSpace ? 1 : 0); - - AddUint(data, m_CommonSettings.frameIndex); - AddUint(data, m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE ? 1 : 0); - AddUint(data, settings.diffuse.materialMask); - AddUint(data, settings.specular.materialMask); + return sizeof(ReblurSettings); } diff --git a/Source/Methods/Reblur_DiffuseSpecularOcclusion.hpp b/Source/Methods/Reblur_DiffuseSpecularOcclusion.hpp index 2cfd64f..77aa431 100644 --- a/Source/Methods/Reblur_DiffuseSpecularOcclusion.hpp +++ b/Source/Methods/Reblur_DiffuseSpecularOcclusion.hpp @@ -10,15 +10,18 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, uint16_t h) { - #define DENOISER_NAME "REBLUR::DiffuseSpecularOcclusion" - #define MIP_NUM 5 + #define METHOD_NAME REBLUR_DiffuseSpecularOcclusion enum class Permanent { - PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS = PERMANENT_POOL_START, + PREV_VIEWZ_DIFFACCUMSPEED = PERMANENT_POOL_START, + PREV_NORMAL_SPECACCUMSPEED, + PREV_ROUGHNESS, }; - m_PermanentPool.push_back( {Format::RG32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); enum class Transient { @@ -32,19 +35,21 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u 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::RG16_SFLOAT, w, h, MIP_NUM} ); - m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, MIP_NUM} ); + m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, REBLUR_MIP_NUM} ); + m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, REBLUR_MIP_NUM} ); m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, 1} ); m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, 1} ); - SetSharedConstants(1, 4, 8, 16); + REBLUR_DECLARE_SHARED_CONSTANT_NUM; PushPass("Temporal accumulation"); { PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_DIFF_HITDIST) ); PushInput( AsUint(ResourceType::OUT_DIFF_HITDIST) ); PushInput( AsUint(ResourceType::IN_SPEC_HITDIST) ); @@ -55,7 +60,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation, SumConstants(4, 2, 1, 4), 8, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulation, SumConstants(4, 2, 1, 4), 8, 1 ); } PushPass("Temporal accumulation"); // with confidence @@ -63,7 +69,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_DIFF_HITDIST) ); PushInput( AsUint(ResourceType::OUT_DIFF_HITDIST) ); PushInput( AsUint(ResourceType::IN_SPEC_HITDIST) ); @@ -76,7 +84,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u PushOutput( AsUint(Transient::DIFF_ACCUMULATED) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 4), 8, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 4), 8, 1 ); } PushPass("Mip generation"); @@ -84,7 +93,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u PushInput( AsUint(Transient::DIFF_ACCUMULATED) ); PushInput( AsUint(Transient::SPEC_ACCUMULATED) ); - for( uint16_t i = 1; i < MIP_NUM; i++ ) + for( uint16_t i = 1; i < REBLUR_MIP_NUM; i++ ) { PushOutput( AsUint(Transient::DIFF_ACCUMULATED), i, 1 ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED), i, 1 ); @@ -96,13 +105,14 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u PushPass("History fix"); { PushInput( AsUint(Transient::INTERNAL_DATA) ); - PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, MIP_NUM - 1 ); - PushInput( AsUint(Transient::SPEC_ACCUMULATED), 1, MIP_NUM - 1 ); + PushInput( AsUint(Transient::DIFF_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); + PushInput( AsUint(Transient::SPEC_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); PushOutput( AsUint(Transient::DIFF_ACCUMULATED), 0, 1 ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED), 0, 1 ); - AddDispatch( REBLUR_DiffuseSpecularOcclusion_HistoryFix, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecularOcclusion_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecularOcclusion_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Blur"); @@ -116,7 +126,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u PushOutput( AsUint(Transient::DIFF_TEMP) ); PushOutput( AsUint(Transient::SPEC_TEMP) ); - AddDispatch( REBLUR_DiffuseSpecularOcclusion_Blur, SumConstants(1, 2, 0, 4), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecularOcclusion_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecularOcclusion_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); @@ -127,11 +138,14 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u PushInput( AsUint(Transient::SPEC_TEMP) ); PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); - PushOutput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushOutput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_ROUGHNESS) ); PushOutput( AsUint(ResourceType::OUT_DIFF_HITDIST) ); PushOutput( AsUint(ResourceType::OUT_SPEC_HITDIST) ); - AddDispatch( REBLUR_DiffuseSpecularOcclusion_PostBlur, SumConstants(1, 2, 0, 4), 16, 1 ); + AddDispatch( REBLUR_DiffuseSpecularOcclusion_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_DiffuseSpecularOcclusion_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Split screen"); @@ -146,116 +160,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurDiffuseSpecularOcclusion(uint16_t w, u AddDispatch( REBLUR_DiffuseSpecularOcclusion_SplitScreen, SumConstants(0, 0, 0, 3), 16, 1 ); } - #undef DENOISER_NAME - #undef MIP_NUM + #undef METHOD_NAME - return sizeof(ReblurDiffuseSpecularSettings); -} - -void nrd::DenoiserImpl::UpdateMethod_ReblurDiffuseSpecularOcclusion(const MethodData& methodData) -{ - enum class Dispatch - { - TEMPORAL_ACCUMULATION, - TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, - MIP_GENERATION, - HISTORY_FIX, - BLUR, - POST_BLUR, - SPLIT_SCREEN, - }; - - const ReblurDiffuseSpecularSettings& settings = methodData.settings.diffuseSpecularReblur; - const ReblurDiffuseSettings& diffSettings = settings.diffuse; - const ReblurSpecularSettings& specSettings = settings.specular; - - bool enableReferenceAccumulation = diffSettings.enableReferenceAccumulation && specSettings.enableReferenceAccumulation; - float normalWeightStrictness = ml::Lerp( 0.1f, 1.0f, ml::Max( diffSettings.normalWeightStrictness, specSettings.normalWeightStrictness ) ); - - uint32_t diffCheckerboard = ((uint32_t)diffSettings.checkerboardMode + 2) % 3; - float diffBlurRadius = enableReferenceAccumulation ? 0.0f : (diffSettings.blurRadius * GetMinResolutionScale()); - - uint32_t specCheckerboard = ((uint32_t)specSettings.checkerboardMode + 2) % 3; - ml::float4 specTrimmingParams_and_specBlurRadius = ml::float4(specSettings.lobeTrimmingParameters.A, specSettings.lobeTrimmingParameters.B, specSettings.lobeTrimmingParameters.C, enableReferenceAccumulation ? 0.0f : (specSettings.blurRadius * GetMinResolutionScale())); - - NRD_DECLARE_DIMS; - - // SPLIT_SCREEN (passthrough) - if (m_CommonSettings.splitScreen >= 1.0f) - { - Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddUint(data, diffCheckerboard); - AddUint(data, specCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - - return; - } - - // TEMPORAL_ACCUMULATION - Constant* data = PushDispatch(methodData, AsUint( m_CommonSettings.isHistoryConfidenceInputsAvailable ? Dispatch::TEMPORAL_ACCUMULATION_WITH_CONFIDENCE : Dispatch::TEMPORAL_ACCUMULATION )); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToViewPrev); - AddFloat4x4(data, m_WorldToClipPrev); - AddFloat4x4(data, m_ViewToWorld); - AddFloat4x4(data, m_WorldToClip); - AddFloat4(data, m_FrustumPrev); - AddFloat4(data, m_CameraDelta); - AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); - AddFloat(data, m_CheckerboardResolveAccumSpeed); - AddFloat(data, enableReferenceAccumulation ? 0.005f : m_CommonSettings.disocclusionThreshold); - AddFloat(data, m_JitterDelta); - AddUint(data, diffCheckerboard); - AddUint(data, specCheckerboard); - ValidateConstants(data); - - // MIP_GENERATION - data = PushDispatch(methodData, AsUint(Dispatch::MIP_GENERATION)); - AddUint2(data, rectW, rectH); - AddFloat(data, m_CommonSettings.denoisingRange); - AddFloat(data, m_CommonSettings.debug); - ValidateConstants(data); - - // HISTORY_FIX - data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_FIX)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat(data, diffSettings.historyFixStrength); - AddFloat(data, specSettings.historyFixStrength); - ValidateConstants(data); - - // BLUR - data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[1]); - AddFloat4(data, specTrimmingParams_and_specBlurRadius); - AddFloat(data, specSettings.maxAdaptiveRadiusScale); - AddFloat(data, diffBlurRadius); - AddFloat(data, diffSettings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // POST_BLUR - data = PushDispatch(methodData, AsUint(Dispatch::POST_BLUR)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[2]); - AddFloat4(data, specTrimmingParams_and_specBlurRadius); - AddFloat(data, specSettings.maxAdaptiveRadiusScale); - AddFloat(data, diffBlurRadius); - AddFloat(data, diffSettings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // SPLIT_SCREEN - if (m_CommonSettings.splitScreen > 0.0f) - { - data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurDiffuseSpecular(methodData, settings, data); - AddUint(data, diffCheckerboard); - AddUint(data, specCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - } + return sizeof(ReblurSettings); } diff --git a/Source/Methods/Reblur_Specular.hpp b/Source/Methods/Reblur_Specular.hpp index ae75f15..71a441d 100644 --- a/Source/Methods/Reblur_Specular.hpp +++ b/Source/Methods/Reblur_Specular.hpp @@ -10,18 +10,21 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) { - #define DENOISER_NAME "REBLUR::Specular" - #define MIP_NUM 5 + #define METHOD_NAME REBLUR_Specular #define SPEC_TEMP1 AsUint(Transient::SPEC_HISTORY_STABILIZED) // valid before HistoryFix #define SPEC_TEMP2 AsUint(ResourceType::OUT_SPEC_RADIANCE_HITDIST) // valid after HistoryFix enum class Permanent { - PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS = PERMANENT_POOL_START, + PREV_VIEWZ_DIFFACCUMSPEED = PERMANENT_POOL_START, + PREV_NORMAL_SPECACCUMSPEED, + PREV_ROUGHNESS, SPEC_HISTORY, }; - m_PermanentPool.push_back( {Format::RG32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); enum class Transient @@ -35,11 +38,11 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) 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::R16_SFLOAT, w, h, MIP_NUM} ); - m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, MIP_NUM} ); + m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, REBLUR_MIP_NUM} ); + m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, REBLUR_MIP_NUM} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - SetSharedConstants(1, 3, 8, 16); + REBLUR_DECLARE_SHARED_CONSTANT_NUM; PushPass("Pre-blur"); { @@ -49,7 +52,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( SPEC_TEMP1 ); - AddDispatch( REBLUR_Specular_PreBlur, SumConstants(1, 2, 0, 3), 16, 1 ); + AddDispatch( REBLUR_Specular_PreBlur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Perf_Specular_PreBlur, SumConstants(1, 2, 0, 2), 16, 1 ); } PushPass("Pre-blur (advanced)"); @@ -61,7 +65,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( SPEC_TEMP1 ); - AddDispatch( REBLUR_Specular_PreBlurAdvanced, SumConstants(1, 2, 0, 3), 16, 1 ); + AddDispatch( REBLUR_Specular_PreBlurAdvanced, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Perf_Specular_PreBlurAdvanced, SumConstants(1, 2, 0, 2), 16, 1 ); } PushPass("Temporal accumulation"); @@ -69,7 +74,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_SPEC_RADIANCE_HITDIST) ); PushInput( AsUint(Permanent::SPEC_HISTORY) ); @@ -78,7 +85,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_Specular_TemporalAccumulation, SumConstants(4, 2, 1, 4), 8, 1 ); + AddDispatch( REBLUR_Specular_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_Perf_Specular_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); } PushPass("Temporal accumulation"); // after Pre-blur @@ -86,7 +94,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( SPEC_TEMP1 ); PushInput( AsUint(Permanent::SPEC_HISTORY) ); @@ -95,7 +105,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_Specular_TemporalAccumulation, SumConstants(4, 2, 1, 4), 8, 1 ); + AddDispatch( REBLUR_Specular_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_Perf_Specular_TemporalAccumulation, SumConstants(4, 2, 1, 5), 8, 1 ); } PushPass("Temporal accumulation"); // with confidence @@ -103,7 +114,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_SPEC_RADIANCE_HITDIST) ); PushInput( AsUint(Permanent::SPEC_HISTORY) ); PushInput( AsUint(ResourceType::IN_SPEC_CONFIDENCE) ); @@ -113,7 +126,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_Specular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 4), 8, 1 ); + AddDispatch( REBLUR_Specular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_Perf_Specular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); } PushPass("Temporal accumulation"); // with confidence, after Pre-blur @@ -121,7 +135,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( SPEC_TEMP1 ); PushInput( AsUint(Permanent::SPEC_HISTORY) ); PushInput( AsUint(ResourceType::IN_SPEC_CONFIDENCE) ); @@ -131,7 +147,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_Specular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 4), 8, 1 ); + AddDispatch( REBLUR_Specular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); + AddDispatch( REBLUR_Perf_Specular_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 5), 8, 1 ); } PushPass("Mip generation"); @@ -139,7 +156,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushInput( AsUint(Transient::SPEC_ACCUMULATED) ); PushInput( AsUint(Transient::SCALED_VIEWZ) ); - for( uint16_t i = 1; i < MIP_NUM; i++ ) + for( uint16_t i = 1; i < REBLUR_MIP_NUM; i++ ) { PushOutput( AsUint(Transient::SPEC_ACCUMULATED), i, 1 ); PushOutput( AsUint(Transient::SCALED_VIEWZ), i, 1 ); @@ -151,14 +168,15 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushPass("History fix"); { PushInput( AsUint(Transient::INTERNAL_DATA) ); - PushInput( AsUint(Transient::SCALED_VIEWZ), 0, MIP_NUM ); - PushInput( AsUint(Transient::SPEC_ACCUMULATED), 1, MIP_NUM - 1 ); + PushInput( AsUint(Transient::SCALED_VIEWZ), 0, REBLUR_MIP_NUM ); + PushInput( AsUint(Transient::SPEC_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); PushInput( AsUint(ResourceType::OUT_SPEC_RADIANCE_HITDIST) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED), 0, 1 ); PushOutput( AsUint(Transient::SPEC_HISTORY_STABILIZED) ); AddDispatch( REBLUR_Specular_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_Specular_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Blur"); @@ -171,7 +189,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( SPEC_TEMP2 ); - AddDispatch( REBLUR_Specular_Blur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Specular_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Specular_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); @@ -184,7 +203,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Permanent::SPEC_HISTORY) ); - AddDispatch( REBLUR_Specular_PostBlur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Specular_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Specular_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); // before Anti-Firefly @@ -197,7 +217,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_Specular_PostBlur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Specular_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Specular_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Anti-firefly"); @@ -209,6 +230,7 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::SPEC_HISTORY) ); AddDispatch( REBLUR_Specular_AntiFirefly, SumConstants(0, 0, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_Specular_AntiFirefly, SumConstants(0, 0, 0, 0), 16, 1 ); } PushPass("Temporal stabilization"); @@ -221,10 +243,13 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushInput( AsUint(Transient::SPEC_HISTORY_STABILIZED) ); PushInput( AsUint(Permanent::SPEC_HISTORY) ); - PushOutput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushOutput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_ROUGHNESS) ); PushOutput( AsUint(ResourceType::OUT_SPEC_RADIANCE_HITDIST) ); - AddDispatch( REBLUR_Specular_TemporalStabilization, SumConstants(2, 3, 1, 1), 16, 1 ); + AddDispatch( REBLUR_Specular_TemporalStabilization, SumConstants(2, 2, 2, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_Specular_TemporalStabilization, SumConstants(2, 2, 2, 1), 16, 1 ); } PushPass("Split screen"); @@ -234,214 +259,12 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(ResourceType::OUT_SPEC_RADIANCE_HITDIST) ); - AddDispatch( REBLUR_Specular_SplitScreen, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( REBLUR_Specular_SplitScreen, SumConstants(0, 0, 0, 3), 16, 1 ); } - #undef DENOISER_NAME - #undef MIP_NUM + #undef METHOD_NAME #undef SPEC_TEMP1 #undef SPEC_TEMP2 - return sizeof(ReblurSpecularSettings); -} - -void nrd::DenoiserImpl::UpdateMethod_ReblurSpecular(const MethodData& methodData) -{ - enum class Dispatch - { - PRE_BLUR, - PRE_BLUR_ADVANCED, - TEMPORAL_ACCUMULATION, - TEMPORAL_ACCUMULATION_AFTER_PRE_BLUR, - TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, - TEMPORAL_ACCUMULATION_WITH_CONFIDENCE_AFTER_PRE_BLUR, - MIP_GENERATION, - HISTORY_FIX, - BLUR, - POST_BLUR, - POST_BLUR_BEFORE_ANTI_FIRELY, - ANTI_FIREFLY, - TEMPORAL_STABILIZATION, - SPLIT_SCREEN, - }; - - const ReblurSpecularSettings& settings = methodData.settings.specularReblur; - - bool skipPrePass = settings.prePassMode == PrePassMode::OFF && settings.checkerboardMode == CheckerboardMode::OFF; - float normalWeightStrictness = ml::Lerp( 0.1f, 1.0f, settings.normalWeightStrictness ); - - uint32_t specCheckerboard = ((uint32_t)settings.checkerboardMode + 2) % 3; - ml::float4 specTrimmingParams = ml::float4(settings.lobeTrimmingParameters.A, settings.lobeTrimmingParameters.B, settings.lobeTrimmingParameters.C, 0.0f); - ml::float4 specAntilag1 = ml::float4(settings.antilagIntensitySettings.sigmaScale / GetMinResolutionScale(), settings.antilagHitDistanceSettings.sigmaScale / GetMinResolutionScale(), settings.antilagIntensitySettings.sensitivityToDarkness, settings.antilagHitDistanceSettings.sensitivityToDarkness); - ml::float4 specAntilag2 = ml::float4(settings.antilagIntensitySettings.thresholdMin / GetMinResolutionScale(), settings.antilagHitDistanceSettings.thresholdMin / GetMinResolutionScale(), settings.antilagIntensitySettings.thresholdMax, settings.antilagHitDistanceSettings.thresholdMax); - - if (!settings.antilagIntensitySettings.enable || settings.enableReferenceAccumulation) - { - specAntilag2.x = 99998.0f; - specAntilag2.z = 99999.0f; - } - - if (!settings.antilagHitDistanceSettings.enable || settings.enableReferenceAccumulation) - { - specAntilag2.y = 99998.0f; - specAntilag2.w = 99999.0f; - } - - NRD_DECLARE_DIMS; - - // SPLIT_SCREEN (passthrough) - if (m_CommonSettings.splitScreen >= 1.0f) - { - Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddUint(data, specCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - - return; - } - - // PRE_BLUR - if (!skipPrePass) - { - uint32_t preBlurPass = AsUint(Dispatch::PRE_BLUR) + ml::Max((int32_t)settings.prePassMode - 1, 0); - Constant* data = PushDispatch(methodData, preBlurPass); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[0]); - AddFloat4(data, specTrimmingParams); - AddUint(data, specCheckerboard); - AddUint(data, settings.prePassMode == PrePassMode::OFF ? 0 : 1); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - } - - // TEMPORAL_ACCUMULATION - Constant* data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_ACCUMULATION) + (m_CommonSettings.isHistoryConfidenceInputsAvailable ? 2 : 0) + (skipPrePass ? 0 : 1)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToViewPrev); - AddFloat4x4(data, m_WorldToClipPrev); - AddFloat4x4(data, m_ViewToWorld); - AddFloat4x4(data, m_WorldToClip); - AddFloat4(data, m_FrustumPrev); - AddFloat4(data, m_CameraDelta); - AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); - AddFloat(data, m_CheckerboardResolveAccumSpeed); - AddFloat(data, settings.enableReferenceAccumulation ? 0.005f : m_CommonSettings.disocclusionThreshold); - AddUint(data, specCheckerboard); - AddUint(data, skipPrePass ? 0 : 1); - ValidateConstants(data); - - // MIP_GENERATION - data = PushDispatch(methodData, AsUint(Dispatch::MIP_GENERATION)); - AddUint2(data, rectW, rectH); - AddFloat(data, m_CommonSettings.denoisingRange); - AddFloat(data, m_CommonSettings.debug); - ValidateConstants(data); - - // HISTORY_FIX - data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_FIX)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat(data, settings.historyFixStrength); - ValidateConstants(data); - - // BLUR - data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[1]); - AddFloat4(data, specTrimmingParams); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // POST_BLUR - data = PushDispatch(methodData, AsUint( settings.enableAntiFirefly ? Dispatch::POST_BLUR_BEFORE_ANTI_FIRELY : Dispatch::POST_BLUR)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[2]); - AddFloat4(data, specTrimmingParams); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // ANTI_FIREFLY - if (settings.enableAntiFirefly) - { - data = PushDispatch(methodData, AsUint(Dispatch::ANTI_FIREFLY)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - ValidateConstants(data); - } - - // TEMPORAL_STABILIZATION - data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_STABILIZATION)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToClipPrev); - AddFloat4x4(data, m_ViewToWorld); - AddFloat4(data, m_CameraDelta); - AddFloat4(data, specAntilag1 ); - AddFloat4(data, specAntilag2 ); - AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); - AddFloat(data, settings.stabilizationStrength); - ValidateConstants(data); - - // SPLIT_SCREEN - if (m_CommonSettings.splitScreen > 0.0f) - { - data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddUint(data, specCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - } -} - -void nrd::DenoiserImpl::AddSharedConstants_ReblurSpecular(const MethodData& methodData, const ReblurSpecularSettings& settings, Constant*& data) -{ - NRD_DECLARE_DIMS; - - uint32_t maxAccumulatedFrameNum = ml::Min(settings.maxAccumulatedFrameNum, REBLUR_MAX_HISTORY_FRAME_NUM); - float blurRadius = settings.enableReferenceAccumulation ? 0.0f : (settings.blurRadius * GetMinResolutionScale()); - ml::float4 specHitDistParams = ml::float4(settings.hitDistanceParameters.A, settings.hitDistanceParameters.B, settings.hitDistanceParameters.C, settings.hitDistanceParameters.D); - - // DRS will increase reprojected values, needed for stability, compensated by blur radius adjustment - float unproject = 1.0f / (0.5f * rectH * m_ProjectY); - - AddFloat4x4(data, m_ViewToClip); - - AddFloat4(data, m_Frustum); - AddFloat4(data, specHitDistParams); - AddFloat4(data, ml::float4(m_ViewDirection.x, m_ViewDirection.y, m_ViewDirection.z, 0.0f)); - - AddFloat2(data, 1.0f / float(screenW), 1.0f / float(screenH)); - AddFloat2(data, float(screenW), float(screenH)); - - AddFloat2(data, 1.0f / float(rectW), 1.0f / float(rectH)); - AddFloat2(data, float(rectW), float(rectH)); - - AddFloat2(data, float(rectWprev), float(rectHprev)); - AddFloat2(data, float(rectW) / float(screenW), float(rectH) / float(screenH)); - - AddFloat2(data, float(m_CommonSettings.inputSubrectOrigin[0]) / float(screenW), float(m_CommonSettings.inputSubrectOrigin[1]) / float(screenH)); - AddUint2(data, m_CommonSettings.inputSubrectOrigin[0], m_CommonSettings.inputSubrectOrigin[1]); - - AddFloat(data, settings.enableReferenceAccumulation ? 1.0f : 0.0f); - AddFloat(data, m_IsOrtho); - AddFloat(data, unproject); - AddFloat(data, m_CommonSettings.debug); - - AddFloat(data, m_CommonSettings.denoisingRange); - AddFloat(data, settings.planeDistanceSensitivity); - AddFloat(data, m_FrameRateScale); - AddFloat(data, settings.residualNoiseLevel); - - AddFloat(data, m_JitterDelta); - AddFloat(data, blurRadius); - AddFloat(data, float( settings.enableReferenceAccumulation ? REBLUR_MAX_HISTORY_FRAME_NUM : maxAccumulatedFrameNum )); - AddFloat(data, settings.stabilizationStrength); - - AddUint(data, m_CommonSettings.isMotionVectorInWorldSpace ? 1 : 0); - AddUint(data, m_CommonSettings.frameIndex); - AddUint(data, m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE ? 1 : 0); - AddUint(data, settings.materialMask); + return sizeof(ReblurSettings); } diff --git a/Source/Methods/Reblur_SpecularOcclusion.hpp b/Source/Methods/Reblur_SpecularOcclusion.hpp index f619404..3550763 100644 --- a/Source/Methods/Reblur_SpecularOcclusion.hpp +++ b/Source/Methods/Reblur_SpecularOcclusion.hpp @@ -10,15 +10,18 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t h) { - #define DENOISER_NAME "REBLUR::SpecularOcclusion" - #define MIP_NUM 5 + #define METHOD_NAME REBLUR_SpecularOcclusion enum class Permanent { - PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS = PERMANENT_POOL_START, + PREV_VIEWZ_DIFFACCUMSPEED = PERMANENT_POOL_START, + PREV_NORMAL_SPECACCUMSPEED, + PREV_ROUGHNESS, }; - m_PermanentPool.push_back( {Format::RG32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_UINT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); enum class Transient { @@ -30,17 +33,19 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t 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::RG16_SFLOAT, w, h, MIP_NUM} ); + m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, REBLUR_MIP_NUM} ); m_TransientPool.push_back( {Format::RG16_SFLOAT, w, h, 1} ); - SetSharedConstants(1, 3, 8, 16); + REBLUR_DECLARE_SHARED_CONSTANT_NUM; PushPass("Temporal accumulation"); { PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_SPEC_HITDIST) ); PushInput( AsUint(ResourceType::OUT_SPEC_HITDIST) ); @@ -48,7 +53,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_SpecularOcclusion_TemporalAccumulation, SumConstants(4, 2, 1, 3), 8, 1 ); + AddDispatch( REBLUR_SpecularOcclusion_TemporalAccumulation, SumConstants(4, 2, 1, 4), 8, 1 ); + AddDispatch( REBLUR_Perf_SpecularOcclusion_TemporalAccumulation, SumConstants(4, 2, 1, 4), 8, 1 ); } PushPass("Temporal accumulation"); // with confidence @@ -56,7 +62,9 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_VIEWZ) ); PushInput( AsUint(ResourceType::IN_MV) ); - PushInput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushInput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushInput( AsUint(Permanent::PREV_ROUGHNESS) ); PushInput( AsUint(ResourceType::IN_SPEC_HITDIST) ); PushInput( AsUint(ResourceType::OUT_SPEC_HITDIST) ); PushInput( AsUint(ResourceType::IN_SPEC_CONFIDENCE) ); @@ -65,14 +73,15 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED) ); - AddDispatch( REBLUR_SpecularOcclusion_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 3), 8, 1 ); + AddDispatch( REBLUR_SpecularOcclusion_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 4), 8, 1 ); + AddDispatch( REBLUR_Perf_SpecularOcclusion_TemporalAccumulationWithConfidence, SumConstants(4, 2, 1, 4), 8, 1 ); } PushPass("Mip generation"); { PushInput( AsUint(Transient::SPEC_ACCUMULATED) ); - for( uint16_t i = 1; i < MIP_NUM; i++ ) + for( uint16_t i = 1; i < REBLUR_MIP_NUM; i++ ) PushOutput( AsUint(Transient::SPEC_ACCUMULATED), i, 1 ); AddDispatch( NRD_MipGeneration_Float2, SumConstants(0, 0, 1, 2, false), 16, 2 ); @@ -81,11 +90,12 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t PushPass("History fix"); { PushInput( AsUint(Transient::INTERNAL_DATA) ); - PushInput( AsUint(Transient::SPEC_ACCUMULATED), 1, MIP_NUM - 1 ); + PushInput( AsUint(Transient::SPEC_ACCUMULATED), 1, REBLUR_MIP_NUM - 1 ); PushOutput( AsUint(Transient::SPEC_ACCUMULATED), 0, 1 ); AddDispatch( REBLUR_SpecularOcclusion_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); + AddDispatch( REBLUR_Perf_SpecularOcclusion_HistoryFix, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Blur"); @@ -97,7 +107,8 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); PushOutput( AsUint(Transient::SPEC_TEMP) ); - AddDispatch( REBLUR_SpecularOcclusion_Blur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_SpecularOcclusion_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_SpecularOcclusion_Blur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Post-blur"); @@ -107,10 +118,13 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t PushInput( AsUint(Transient::SPEC_TEMP) ); PushOutput( AsUint(Transient::ESTIMATED_ERROR) ); - PushOutput( AsUint(Permanent::PREV_VIEWZ_NORMAL_ROUGHNESS_ACCUMSPEEDS) ); + PushOutput( AsUint(Permanent::PREV_VIEWZ_DIFFACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_NORMAL_SPECACCUMSPEED) ); + PushOutput( AsUint(Permanent::PREV_ROUGHNESS) ); PushOutput( AsUint(ResourceType::OUT_SPEC_HITDIST) ); - AddDispatch( REBLUR_SpecularOcclusion_PostBlur, SumConstants(1, 2, 0, 2), 16, 1 ); + AddDispatch( REBLUR_SpecularOcclusion_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); + AddDispatch( REBLUR_Perf_SpecularOcclusion_PostBlur, SumConstants(1, 2, 0, 0), 16, 1 ); } PushPass("Split screen"); @@ -120,104 +134,10 @@ size_t nrd::DenoiserImpl::AddMethod_ReblurSpecularOcclusion(uint16_t w, uint16_t PushOutput( AsUint(ResourceType::OUT_SPEC_HITDIST) ); - AddDispatch( REBLUR_SpecularOcclusion_SplitScreen, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( REBLUR_SpecularOcclusion_SplitScreen, SumConstants(0, 0, 0, 3), 16, 1 ); } - #undef DENOISER_NAME - #undef MIP_NUM + #undef METHOD_NAME - return sizeof(ReblurSpecularSettings); -} - -void nrd::DenoiserImpl::UpdateMethod_ReblurSpecularOcclusion(const MethodData& methodData) -{ - enum class Dispatch - { - TEMPORAL_ACCUMULATION, - TEMPORAL_ACCUMULATION_WITH_CONFIDENCE, - MIP_GENERATION, - HISTORY_FIX, - BLUR, - POST_BLUR, - SPLIT_SCREEN, - }; - - const ReblurSpecularSettings& settings = methodData.settings.specularReblur; - - float normalWeightStrictness = ml::Lerp( 0.1f, 1.0f, settings.normalWeightStrictness ); - - uint32_t specCheckerboard = ((uint32_t)settings.checkerboardMode + 2) % 3; - ml::float4 specTrimmingParams = ml::float4(settings.lobeTrimmingParameters.A, settings.lobeTrimmingParameters.B, settings.lobeTrimmingParameters.C, 0.0f); - - NRD_DECLARE_DIMS; - - // SPLIT_SCREEN (passthrough) - if (m_CommonSettings.splitScreen >= 1.0f) - { - Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddUint(data, specCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - - return; - } - - // TEMPORAL_ACCUMULATION - Constant* data = PushDispatch(methodData, AsUint( m_CommonSettings.isHistoryConfidenceInputsAvailable ? Dispatch::TEMPORAL_ACCUMULATION_WITH_CONFIDENCE : Dispatch::TEMPORAL_ACCUMULATION )); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToViewPrev); - AddFloat4x4(data, m_WorldToClipPrev); - AddFloat4x4(data, m_ViewToWorld); - AddFloat4x4(data, m_WorldToClip); - AddFloat4(data, m_FrustumPrev); - AddFloat4(data, m_CameraDelta); - AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); - AddFloat(data, m_CheckerboardResolveAccumSpeed); - AddFloat(data, settings.enableReferenceAccumulation ? 0.005f : m_CommonSettings.disocclusionThreshold); - AddUint(data, specCheckerboard); - ValidateConstants(data); - - // MIP_GENERATION - data = PushDispatch(methodData, AsUint(Dispatch::MIP_GENERATION)); - AddUint2(data, rectW, rectH); - AddFloat(data, m_CommonSettings.denoisingRange); - AddFloat(data, m_CommonSettings.debug); - ValidateConstants(data); - - // HISTORY_FIX - data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_FIX)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat(data, settings.historyFixStrength); - ValidateConstants(data); - - // BLUR - data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[1]); - AddFloat4(data, specTrimmingParams); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // POST_BLUR - data = PushDispatch(methodData, AsUint(Dispatch::POST_BLUR)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddFloat4x4(data, m_WorldToView); - AddFloat4(data, m_Rotator[2]); - AddFloat4(data, specTrimmingParams); - AddFloat(data, settings.maxAdaptiveRadiusScale); - AddFloat(data, normalWeightStrictness); - ValidateConstants(data); - - // SPLIT_SCREEN - if (m_CommonSettings.splitScreen > 0.0f) - { - data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_ReblurSpecular(methodData, settings, data); - AddUint(data, specCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); - ValidateConstants(data); - } + return sizeof(ReblurSettings); } diff --git a/Source/Methods/Reference.hpp b/Source/Methods/Reference.hpp index b5bc9fa..9af0513 100644 --- a/Source/Methods/Reference.hpp +++ b/Source/Methods/Reference.hpp @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_Reference(uint16_t w, uint16_t h) { - #define DENOISER_NAME "REFERENCE" + #define METHOD_NAME Reference enum class Permanent { @@ -23,7 +23,7 @@ size_t nrd::DenoiserImpl::AddMethod_Reference(uint16_t w, uint16_t h) PushPass("Accumulate"); { - PushInput( AsUint(ResourceType::IN_DIFF_RADIANCE_HITDIST) ); + PushInput( AsUint(ResourceType::IN_RADIANCE) ); PushOutput( AsUint(Permanent::HISTORY) ); @@ -34,12 +34,12 @@ size_t nrd::DenoiserImpl::AddMethod_Reference(uint16_t w, uint16_t h) { PushInput( AsUint(Permanent::HISTORY) ); - PushOutput( AsUint(ResourceType::OUT_DIFF_RADIANCE_HITDIST) ); + PushOutput( AsUint(ResourceType::OUT_RADIANCE) ); AddDispatch( REFERENCE_SplitScreen, SumConstants(0, 0, 0, 0), 16, 1 ); } - #undef DENOISER_NAME + #undef METHOD_NAME return sizeof(ReferenceSettings); } diff --git a/Source/Methods/Relax_Diffuse.hpp b/Source/Methods/Relax_Diffuse.hpp index b3f7898..7a680c5 100644 --- a/Source/Methods/Relax_Diffuse.hpp +++ b/Source/Methods/Relax_Diffuse.hpp @@ -9,6 +9,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. */ constexpr uint32_t RELAX_MAX_ATROUS_PASS_NUM = 8; +#define RELAX_DECLARE_SHARED_CONSTANT_NUM SetSharedConstants(2, 7, 8, 12) + inline ml::float3 RELAX_GetFrustumForward(const ml::float4x4& viewToWorld, const ml::float4& frustum) { // Note: this vector is not normalized for non-symmetric projections but that's correct. @@ -28,7 +30,7 @@ inline bool RELAX_IsCameraStatic return ml::Length(cameraDelta) < eps && ml::Length(frustumRight - prevFrustumRight) < eps && ml::Length(frustumUp - prevFrustumUp) < eps && ml::Length(frustumForward - prevFrustumForward) < eps; } -void nrd::DenoiserImpl::AddSharedConstants_Relax(const MethodData& methodData, Constant*& data) +void nrd::DenoiserImpl::AddSharedConstants_Relax(const MethodData& methodData, Constant*& data, nrd::Method method) { NRD_DECLARE_DIMS; @@ -48,34 +50,64 @@ void nrd::DenoiserImpl::AddSharedConstants_Relax(const MethodData& methodData, C AddFloat4x4(data, m_WorldToClipPrev); AddFloat4x4(data, m_WorldToClip); + AddFloat4(data, ml::float4(frustumRight.x, frustumRight.y, frustumRight.z, 0)); AddFloat4(data, ml::float4(frustumUp.x, frustumUp.y, frustumUp.z, 0)); AddFloat4(data, ml::float4(frustumForward.x, frustumForward.y, frustumForward.z, 0)); AddFloat4(data, ml::float4(prevFrustumRight.x, prevFrustumRight.y, prevFrustumRight.z, 0)); AddFloat4(data, ml::float4(prevFrustumUp.x, prevFrustumUp.y, prevFrustumUp.z, 0)); AddFloat4(data, ml::float4(prevFrustumForward.x, prevFrustumForward.y, prevFrustumForward.z, 0)); - AddFloat4(data, ml::float4(m_CameraDelta.x, m_CameraDelta.y, m_CameraDelta.z, m_JitterDelta)); + AddFloat4(data, m_CameraDelta); + AddFloat2(data, float(rectW) / float(screenW), float(rectH) / float(screenH)); AddUint2(data, m_CommonSettings.inputSubrectOrigin[0], m_CommonSettings.inputSubrectOrigin[1]); + AddFloat2(data, float(m_CommonSettings.inputSubrectOrigin[0]) / float(screenW), float(m_CommonSettings.inputSubrectOrigin[1]) / float(screenH)); AddUint2(data, rectW, rectH); + AddFloat2(data, 1.0f / screenW, 1.0f / screenH); AddFloat2(data, 1.0f / rectW, 1.0f / rectH); + AddFloat2(data, float(rectWprev), float(rectHprev)); AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); + AddUint(data, m_CommonSettings.isMotionVectorInWorldSpace ? 1 : 0); - AddUint(data, (uint32_t)RELAX_IsCameraStatic(ml::float3(m_CameraDelta.x, m_CameraDelta.y, m_CameraDelta.z), frustumRight, frustumUp, frustumForward, prevFrustumRight, prevFrustumUp, prevFrustumForward)); + AddFloat(data, m_CommonSettings.debug); AddFloat(data, m_IsOrtho); AddFloat(data, 1.0f / (0.5f * rectH * m_ProjectY)); + AddUint(data, m_CommonSettings.frameIndex); AddFloat(data, m_CommonSettings.denoisingRange); AddFloat(data, ml::Clamp(16.66f / m_TimeDelta, 0.25f, 4.0f)); // Normalizing to 60 FPS AddFloat(data, m_CheckerboardResolveAccumSpeed); + + AddFloat(data, m_JitterDelta); + switch (method) + { + case nrd::Method::RELAX_DIFFUSE: + AddUint(data, methodData.settings.diffuseRelax.enableMaterialTest ? 1 : 0); + AddUint(data, 0); + break; + case nrd::Method::RELAX_SPECULAR: + AddUint(data, 0); + AddUint(data, methodData.settings.specularRelax.enableMaterialTest ? 1 : 0); + break; + case nrd::Method::RELAX_DIFFUSE_SPECULAR: + AddUint(data, methodData.settings.diffuseSpecularRelax.enableMaterialTestForDiffuse ? 1 : 0); + AddUint(data, methodData.settings.diffuseSpecularRelax.enableMaterialTestForSpecular ? 1 : 0); + break; + default: + // Should never get here! + AddUint(data, 0); + AddUint(data, 0); + break; + } + AddFloat(data, 0.0f); } size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) { - #define DENOISER_NAME "RELAX::Diffuse" + #define METHOD_NAME RELAX_Diffuse enum class Permanent { @@ -86,20 +118,21 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) DIFF_HISTORY_LENGTH_CURR, DIFF_HISTORY_LENGTH_PREV, NORMAL_ROUGHNESS_PREV, + MATERIAL_ID_PREV, VIEWZ_CURR, VIEWZ_PREV }; m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - m_PermanentPool.push_back({ Format::RGBA16_SFLOAT, w, h, 1 }); + m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); - m_PermanentPool.push_back( { Format::RGBA8_UNORM, w, h, 1 } ); - m_PermanentPool.push_back( { Format::R32_SFLOAT, w, h, 1 } ); - m_PermanentPool.push_back( { Format::R32_SFLOAT, w, h, 1 } ); - + m_PermanentPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); + m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_SFLOAT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_SFLOAT, w, h, 1} ); enum class Transient { @@ -110,11 +143,9 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - m_TransientPool.push_back( { Format::R16_SFLOAT, w, h, 1 } ); + m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, 1} ); - // Shared constants defined in Relax_Diffuse.hpp, - // void nrd::DenoiserImpl::AddSharedConstants_Relax(const MethodData& methodData, Constant*& data) - SetSharedConstants(2, 7, 8, 8); + RELAX_DECLARE_SHARED_CONSTANT_NUM; const uint32_t halfMaxPassNum = (RELAX_MAX_ATROUS_PASS_NUM - 2 + 1) / 2; @@ -128,7 +159,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::VIEWZ_CURR), 0, 1, AsUint(Permanent::VIEWZ_PREV) ); PushOutput( AsUint(Transient::VIEWZ_R16F) ); - AddDispatch(RELAX_Diffuse_Prepass, SumConstants(0, 1, 0, 4), 16, 1); + AddDispatch( RELAX_Diffuse_Prepass, SumConstants(0, 1, 0, 4), 16, 1 ); } PushPass("Reproject"); @@ -142,6 +173,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) PushInput( AsUint(Permanent::NORMAL_ROUGHNESS_PREV)); PushInput( AsUint(Permanent::VIEWZ_PREV), 0, 1, AsUint(Permanent::VIEWZ_CURR) ); PushInput( AsUint(Permanent::DIFF_HISTORY_LENGTH_PREV) ); + PushInput( AsUint(Permanent::MATERIAL_ID_PREV) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); // Bogus input that will not be fetched anyway PushOutput( AsUint(Permanent::DIFF_ILLUM_CURR) ); @@ -162,6 +194,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) PushInput( AsUint(Permanent::NORMAL_ROUGHNESS_PREV) ); PushInput( AsUint(Permanent::VIEWZ_PREV), 0, 1, AsUint(Permanent::VIEWZ_CURR) ); PushInput( AsUint(Permanent::DIFF_HISTORY_LENGTH_PREV) ); + PushInput( AsUint(Permanent::MATERIAL_ID_PREV) ); PushInput( AsUint(ResourceType::IN_DIFF_CONFIDENCE) ); PushOutput( AsUint(Permanent::DIFF_ILLUM_CURR) ); @@ -206,7 +239,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::DIFF_ILLUM_PREV) ); PushOutput( AsUint(Permanent::DIFF_HISTORY_LENGTH_PREV) ); - AddDispatch(RELAX_Diffuse_HistoryClamping, SumConstants(0, 0, 0, 1), 16, 1); + AddDispatch( RELAX_Diffuse_HistoryClamping, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Anti-firefly"); @@ -220,7 +253,8 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) AddDispatch( RELAX_Diffuse_Firefly, SumConstants(0, 0, 0, 0), 16, 1 ); } - PushPass("Spatial variance estimation"); + // A-trous (first) + PushPass("A-trous (SMEM)"); { PushInput( AsUint(Permanent::DIFF_ILLUM_PREV) ); PushInput( AsUint(Permanent::DIFF_HISTORY_LENGTH_CURR) ); @@ -229,32 +263,20 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::DIFF_ILLUM_PING) ); PushOutput( AsUint(Permanent::NORMAL_ROUGHNESS_PREV) ); + PushOutput( AsUint(Permanent::MATERIAL_ID_PREV) ); - AddDispatch( RELAX_Diffuse_SpatialVarianceEstimation, SumConstants(0, 0, 0, 2), 16, 1 ); - } - - // A-trous (first) - PushPass("A-trous (SMEM)"); - { - PushInput( AsUint(Transient::DIFF_ILLUM_PING) ); - PushInput( AsUint(Permanent::DIFF_HISTORY_LENGTH_CURR) ); - PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); - PushInput( AsUint(Transient::VIEWZ_R16F) ); - - PushOutput( AsUint(Transient::DIFF_ILLUM_PONG) ); - - AddDispatch( RELAX_Diffuse_ATrousShmem, SumConstants(0, 0, 1, 5), 8, 1 ); + AddDispatch( RELAX_Diffuse_ATrousShmem, SumConstants(0, 0, 1, 6), 8, 1 ); } // A-trous (odd) PushPass("A-trous"); { - PushInput( AsUint(Transient::DIFF_ILLUM_PONG) ); + PushInput( AsUint(Transient::DIFF_ILLUM_PING) ); PushInput( AsUint(Permanent::DIFF_HISTORY_LENGTH_CURR) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); - PushOutput( AsUint(Transient::DIFF_ILLUM_PING) ); + PushOutput( AsUint(Transient::DIFF_ILLUM_PONG) ); AddDispatchRepeated( RELAX_Diffuse_ATrousStandard, SumConstants(0, 0, 0, 5), 16, 1, halfMaxPassNum ); } @@ -262,12 +284,12 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) // A-trous (even) PushPass("A-trous"); { - PushInput( AsUint(Transient::DIFF_ILLUM_PING) ); + PushInput( AsUint(Transient::DIFF_ILLUM_PONG) ); PushInput( AsUint(Permanent::DIFF_HISTORY_LENGTH_CURR) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); - PushOutput( AsUint(Transient::DIFF_ILLUM_PONG) ); + PushOutput( AsUint(Transient::DIFF_ILLUM_PING) ); AddDispatchRepeated( RELAX_Diffuse_ATrousStandard, SumConstants(0, 0, 0, 5), 16, 1, halfMaxPassNum ); } @@ -275,7 +297,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) // A-trous (odd, last) PushPass("A-trous"); { - PushInput( AsUint(Transient::DIFF_ILLUM_PONG) ); + PushInput( AsUint(Transient::DIFF_ILLUM_PING) ); PushInput( AsUint(Permanent::DIFF_HISTORY_LENGTH_CURR) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); @@ -288,7 +310,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) // A-trous (even, last) PushPass("A-trous"); { - PushInput( AsUint(Transient::DIFF_ILLUM_PING) ); + PushInput( AsUint(Transient::DIFF_ILLUM_PONG) ); PushInput( AsUint(Permanent::DIFF_HISTORY_LENGTH_CURR) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); @@ -308,7 +330,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuse(uint16_t w, uint16_t h) AddDispatch( RELAX_Diffuse_SplitScreen, SumConstants(0, 0, 0, 2), 16, 1 ); } - #undef DENOISER_NAME + #undef METHOD_NAME return sizeof(RelaxDiffuseSpecularSettings); } @@ -324,7 +346,6 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuse(const MethodData& methodData) HISTORY_CLAMPING, HISTORY_CLAMPING_NO_FIREFLY, FIREFLY, - SPATIAL_VARIANCE_ESTIMATION, ATROUS_SMEM, ATROUS_ODD, ATROUS_EVEN, @@ -349,6 +370,19 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuse(const MethodData& methodData) float disocclusionThresholdOrtho = m_CommonSettings.disocclusionThreshold;// * fabs(zFar - zNear); float depthThresholdOrtho = settings.depthThreshold; // * fabs(zFar - zNear); + float tanHalfFov = 1.0f / m_ViewToClip.a00; + float aspect = m_ViewToClip.a00 / m_ViewToClip.a11; + ml::float3 frustumRight = m_WorldToView.GetRow0().To3d() * tanHalfFov; + ml::float3 frustumUp = m_WorldToView.GetRow1().To3d() * tanHalfFov * aspect; + ml::float3 frustumForward = RELAX_GetFrustumForward(m_ViewToWorld, m_Frustum); + + float prevTanHalfFov = 1.0f / m_ViewToClipPrev.a00; + float prevAspect = m_ViewToClipPrev.a00 / m_ViewToClipPrev.a11; + ml::float3 prevFrustumRight = m_WorldToViewPrev.GetRow0().To3d() * prevTanHalfFov; + ml::float3 prevFrustumUp = m_WorldToViewPrev.GetRow1().To3d() * prevTanHalfFov * prevAspect; + ml::float3 prevFrustumForward = RELAX_GetFrustumForward(m_ViewToWorldPrev, m_FrustumPrev); + bool isCameraStatic = RELAX_IsCameraStatic(ml::float3(m_CameraDelta.x, m_CameraDelta.y, m_CameraDelta.z), frustumRight, frustumUp, frustumForward, prevFrustumRight, prevFrustumUp, prevFrustumForward); + // Checkerboard logic uint32_t diffuseCheckerboard = 2; @@ -368,9 +402,9 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuse(const MethodData& methodData) if (m_CommonSettings.splitScreen >= 1.0f) { Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_Relax(methodData, data); - AddUint(data, diffuseCheckerboard); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); AddFloat(data, m_CommonSettings.splitScreen); + AddUint(data, diffuseCheckerboard); ValidateConstants(data); return; @@ -378,7 +412,7 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuse(const MethodData& methodData) // PREPASS Constant* data = PushDispatch(methodData, AsUint(Dispatch::PREPASS)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); AddFloat4(data, m_Rotator[0]); AddUint(data, diffuseCheckerboard); AddFloat(data, settings.prepassBlurRadius); @@ -388,20 +422,20 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuse(const MethodData& methodData) // REPROJECT data = PushDispatch(methodData, m_CommonSettings.isHistoryConfidenceInputsAvailable ? AsUint(Dispatch::REPROJECT_WITH_CONFIDENCE_INPUTS) : AsUint(Dispatch::REPROJECT)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); AddFloat(data, (float)settings.diffuseMaxAccumulatedFrameNum); AddFloat(data, (float)settings.diffuseMaxFastAccumulatedFrameNum); AddUint(data, diffuseCheckerboard); AddFloat(data, m_IsOrtho == 0 ? m_CommonSettings.disocclusionThreshold : disocclusionThresholdOrtho); - AddUint(data, settings.enableSkipReprojectionTestWithoutMotion); + AddUint(data, settings.enableReprojectionTestSkippingWithoutMotion && isCameraStatic); AddUint(data, m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE ? 1 : 0); - AddFloat(data, settings.rejectDiffuseHistoryNormalThreshold); + AddFloat(data, settings.diffuseHistoryRejectionNormalThreshold); AddUint(data, m_CommonSettings.isHistoryConfidenceInputsAvailable ? 1 : 0); ValidateConstants(data); // DISOCCLUSION FIX data = PushDispatch(methodData, AsUint(Dispatch::DISOCCLUSION_FIX)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); AddFloat(data, m_IsOrtho == 0 ? m_CommonSettings.disocclusionThreshold : disocclusionThresholdOrtho); AddFloat(data, settings.disocclusionFixEdgeStoppingNormalPower); AddFloat(data, settings.disocclusionFixMaxRadius); @@ -412,31 +446,24 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuse(const MethodData& methodData) { // HISTORY CLAMPING data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_CLAMPING)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); AddFloat(data, settings.historyClampingColorBoxSigmaScale); ValidateConstants(data); // FIREFLY data = PushDispatch(methodData, AsUint(Dispatch::FIREFLY)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); ValidateConstants(data); } else { // HISTORY CLAMPING WITHOUT FIREFLY data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_CLAMPING_NO_FIREFLY)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); AddFloat(data, settings.historyClampingColorBoxSigmaScale); ValidateConstants(data); } - // SPATIAL VARIANCE ESTIMATION - data = PushDispatch(methodData, AsUint(Dispatch::SPATIAL_VARIANCE_ESTIMATION)); - AddSharedConstants_Relax(methodData, data); - AddFloat(data, settings.phiNormal); - AddUint(data, settings.spatialVarianceEstimationHistoryThreshold); - ValidateConstants(data); - // A-TROUS uint32_t iterationNum = ml::Clamp(settings.atrousIterationNum, 2u, RELAX_MAX_ATROUS_PASS_NUM); for (uint32_t i = 0; i < iterationNum; i++) @@ -450,17 +477,18 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuse(const MethodData& methodData) dispatch = (i % 2 == 0) ? Dispatch::ATROUS_EVEN : Dispatch::ATROUS_ODD; data = PushDispatch(methodData, AsUint(dispatch)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); if (i == 0) { AddUint2(data, screenW, screenH); // For Atrous_shmem + AddUint(data, settings.spatialVarianceEstimationHistoryThreshold); } AddFloat(data, settings.diffusePhiLuminance); AddFloat(data, maxLuminanceRelativeDifference); AddFloat(data, m_IsOrtho == 0 ? settings.depthThreshold : depthThresholdOrtho); - AddFloat(data, settings.phiNormal); + AddFloat(data, settings.diffuseLobeAngleFraction); AddUint(data, 1 << i); ValidateConstants(data); } @@ -469,9 +497,9 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuse(const MethodData& methodData) if (m_CommonSettings.splitScreen > 0.0f) { data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_Relax(methodData, data); - AddUint(data, diffuseCheckerboard); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE); AddFloat(data, m_CommonSettings.splitScreen); + AddUint(data, diffuseCheckerboard); ValidateConstants(data); } } diff --git a/Source/Methods/Relax_DiffuseSpecular.hpp b/Source/Methods/Relax_DiffuseSpecular.hpp index 425d897..4fa1f16 100644 --- a/Source/Methods/Relax_DiffuseSpecular.hpp +++ b/Source/Methods/Relax_DiffuseSpecular.hpp @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) { - #define DENOISER_NAME "RELAX::DiffuseSpecular" + #define METHOD_NAME RELAX_DiffuseSpecular enum class Permanent { @@ -27,6 +27,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) SPEC_DIFF_HISTORY_LENGTH_CURR, SPEC_DIFF_HISTORY_LENGTH_PREV, NORMAL_ROUGHNESS_PREV, + MATERIAL_ID_PREV, VIEWZ_CURR, VIEWZ_PREV, }; @@ -38,14 +39,15 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - m_PermanentPool.push_back({ Format::RGBA16_SFLOAT, w, h, 1 }); + m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::R16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::R16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::RG8_UNORM, w, h, 1} ); m_PermanentPool.push_back( {Format::RG8_UNORM, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); - m_PermanentPool.push_back({ Format::R32_SFLOAT, w, h, 1 }); - m_PermanentPool.push_back({ Format::R32_SFLOAT, w, h, 1 }); + m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_SFLOAT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_SFLOAT, w, h, 1} ); enum class Transient { @@ -59,14 +61,12 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - m_TransientPool.push_back({ Format::RGBA16_SFLOAT, w, h, 1 }); + m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_TransientPool.push_back( {Format::R8_UNORM, w, h, 1} ); - m_TransientPool.push_back({ Format::R16_SFLOAT, w, h, 1 }); + m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, 1} ); - // Shared constants defined in Relax_Diffuse.hpp, - // void nrd::DenoiserImpl::AddSharedConstants_Relax(const MethodData& methodData, Constant*& data) - SetSharedConstants(2, 7, 8, 8); + RELAX_DECLARE_SHARED_CONSTANT_NUM; const uint32_t halfMaxPassNum = (RELAX_MAX_ATROUS_PASS_NUM - 2 + 1) / 2; @@ -82,7 +82,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::VIEWZ_CURR), 0, 1, AsUint(Permanent::VIEWZ_PREV)); PushOutput( AsUint(Transient::VIEWZ_R16F)); - AddDispatch( RELAX_DiffuseSpecular_Prepass, SumConstants(0, 1, 0, 6), 16, 1 ); + AddDispatch( RELAX_DiffuseSpecular_Prepass, SumConstants(0, 1, 0, 7), 16, 1 ); } PushPass("Reproject"); @@ -101,6 +101,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushInput( AsUint(Permanent::VIEWZ_PREV), 0, 1, AsUint(Permanent::VIEWZ_CURR)); PushInput( AsUint(Permanent::REFLECTION_HIT_T_PREV), 0, 1, AsUint(Permanent::REFLECTION_HIT_T_CURR) ); PushInput( AsUint(Permanent::SPEC_DIFF_HISTORY_LENGTH_PREV) ); + PushInput( AsUint(Permanent::MATERIAL_ID_PREV) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); // Bogus inputs that will not be fetched anyway PushInput( AsUint(Transient::VIEWZ_R16F) ); @@ -112,7 +113,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::SPEC_DIFF_HISTORY_LENGTH_CURR) ); PushOutput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE)); - AddDispatch( RELAX_DiffuseSpecular_Reproject, SumConstants(0, 0, 0, 13), 8, 1 ); + AddDispatch( RELAX_DiffuseSpecular_Reproject, SumConstants(0, 0, 0, 14), 8, 1 ); } PushPass("Reproject"); // With confidence inputs @@ -130,6 +131,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushInput( AsUint(Permanent::VIEWZ_PREV), 0, 1, AsUint(Permanent::VIEWZ_CURR)); PushInput( AsUint(Permanent::REFLECTION_HIT_T_PREV), 0, 1, AsUint(Permanent::REFLECTION_HIT_T_CURR) ); PushInput( AsUint(Permanent::SPEC_DIFF_HISTORY_LENGTH_PREV) ); + PushInput( AsUint(Permanent::MATERIAL_ID_PREV) ); PushInput( AsUint(ResourceType::IN_SPEC_CONFIDENCE)); PushInput( AsUint(ResourceType::IN_DIFF_CONFIDENCE)); @@ -141,7 +143,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::SPEC_DIFF_HISTORY_LENGTH_CURR) ); PushOutput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE)); - AddDispatch( RELAX_DiffuseSpecular_Reproject, SumConstants(0, 0, 0, 13), 8, 1 ); + AddDispatch( RELAX_DiffuseSpecular_Reproject, SumConstants(0, 0, 0, 14), 8, 1 ); } PushPass("Disocclusion fix"); @@ -189,7 +191,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushOutput(AsUint(Permanent::DIFF_ILLUM_PREV)); PushOutput(AsUint(Permanent::SPEC_DIFF_HISTORY_LENGTH_PREV)); - AddDispatch(RELAX_DiffuseSpecular_HistoryClamping, SumConstants(0, 0, 0, 1), 16, 1); + AddDispatch( RELAX_DiffuseSpecular_HistoryClamping, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Anti-firefly"); @@ -205,23 +207,26 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) AddDispatch( RELAX_DiffuseSpecular_Firefly, SumConstants(0, 0, 0, 0), 16, 1 ); } - PushPass("Spatial variance estimation"); + // A-trous (first) + PushPass("A-trous (SMEM)"); { PushInput( AsUint(Permanent::SPEC_ILLUM_PREV) ); PushInput( AsUint(Permanent::DIFF_ILLUM_PREV) ); PushInput( AsUint(Permanent::SPEC_DIFF_HISTORY_LENGTH_CURR) ); + PushInput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); PushOutput( AsUint(Transient::SPEC_ILLUM_PING) ); PushOutput( AsUint(Transient::DIFF_ILLUM_PING) ); - PushOutput( AsUint(Permanent::NORMAL_ROUGHNESS_PREV)); + PushOutput( AsUint(Permanent::NORMAL_ROUGHNESS_PREV) ); + PushOutput( AsUint(Permanent::MATERIAL_ID_PREV) ); - AddDispatch( RELAX_DiffuseSpecular_SpatialVarianceEstimation, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( RELAX_DiffuseSpecular_ATrousShmem, SumConstants(0, 0, 1, 14), 8, 1 ); } - - // A-trous (first) - PushPass("A-trous (SMEM)"); + + // A-trous (odd) + PushPass("A-trous"); { PushInput( AsUint(Transient::SPEC_ILLUM_PING) ); PushInput( AsUint(Transient::DIFF_ILLUM_PING) ); @@ -233,10 +238,10 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::SPEC_ILLUM_PONG) ); PushOutput( AsUint(Transient::DIFF_ILLUM_PONG) ); - AddDispatch( RELAX_DiffuseSpecular_ATrousShmem, SumConstants(0, 0, 1, 12), 8, 1 ); + AddDispatchRepeated( RELAX_DiffuseSpecular_ATrousStandard, SumConstants(0, 0, 0, 13), 16, 1, halfMaxPassNum ); } - // A-trous (odd) + // A-trous (even) PushPass("A-trous"); { PushInput( AsUint(Transient::SPEC_ILLUM_PONG) ); @@ -249,10 +254,10 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::SPEC_ILLUM_PING) ); PushOutput( AsUint(Transient::DIFF_ILLUM_PING) ); - AddDispatchRepeated( RELAX_DiffuseSpecular_ATrousStandard, SumConstants(0, 0, 0, 12), 16, 1, halfMaxPassNum ); + AddDispatchRepeated( RELAX_DiffuseSpecular_ATrousStandard, SumConstants(0, 0, 0, 13), 16, 1, halfMaxPassNum ); } - // A-trous (even) + // A-trous (odd, last) PushPass("A-trous"); { PushInput( AsUint(Transient::SPEC_ILLUM_PING) ); @@ -262,33 +267,17 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); - PushOutput( AsUint(Transient::SPEC_ILLUM_PONG) ); - PushOutput( AsUint(Transient::DIFF_ILLUM_PONG) ); - - AddDispatchRepeated( RELAX_DiffuseSpecular_ATrousStandard, SumConstants(0, 0, 0, 12), 16, 1, halfMaxPassNum ); - } - - // A-trous (odd, last) - PushPass("A-trous"); - { - PushInput( AsUint(Transient::SPEC_ILLUM_PONG) ); - PushInput( AsUint(Transient::DIFF_ILLUM_PONG) ); - PushInput( AsUint(Permanent::SPEC_DIFF_HISTORY_LENGTH_CURR) ); - PushInput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE) ); - PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); - PushInput( AsUint(Transient::VIEWZ_R16F) ); - PushOutput( AsUint( ResourceType::OUT_SPEC_RADIANCE_HITDIST ) ); PushOutput( AsUint( ResourceType::OUT_DIFF_RADIANCE_HITDIST ) ); - AddDispatch( RELAX_DiffuseSpecular_ATrousStandard, SumConstants(0, 0, 0, 12), 16, 1 ); + AddDispatch( RELAX_DiffuseSpecular_ATrousStandard, SumConstants(0, 0, 0, 13), 16, 1 ); } // A-trous (even, last) PushPass("A-trous"); { - PushInput( AsUint(Transient::SPEC_ILLUM_PING) ); - PushInput( AsUint(Transient::DIFF_ILLUM_PING) ); + PushInput( AsUint(Transient::SPEC_ILLUM_PONG) ); + PushInput( AsUint(Transient::DIFF_ILLUM_PONG) ); PushInput( AsUint(Permanent::SPEC_DIFF_HISTORY_LENGTH_CURR) ); PushInput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); @@ -297,9 +286,9 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) PushOutput( AsUint( ResourceType::OUT_SPEC_RADIANCE_HITDIST ) ); PushOutput( AsUint( ResourceType::OUT_DIFF_RADIANCE_HITDIST ) ); - AddDispatch( RELAX_DiffuseSpecular_ATrousStandard, SumConstants(0, 0, 0, 12), 16, 1 ); + AddDispatch( RELAX_DiffuseSpecular_ATrousStandard, SumConstants(0, 0, 0, 13), 16, 1 ); } - + PushPass("Split screen"); { PushInput( AsUint(ResourceType::IN_VIEWZ) ); @@ -312,7 +301,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxDiffuseSpecular(uint16_t w, uint16_t h) AddDispatch( RELAX_DiffuseSpecular_SplitScreen, SumConstants(0, 0, 0, 3), 16, 1 ); } - #undef DENOISER_NAME + #undef METHOD_NAME return sizeof(RelaxDiffuseSpecularSettings); } @@ -328,7 +317,6 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth HISTORY_CLAMPING, HISTORY_CLAMPING_NO_FIREFLY, FIREFLY, - SPATIAL_VARIANCE_ESTIMATION, ATROUS_SMEM, ATROUS_ODD, ATROUS_EVEN, @@ -353,6 +341,20 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth float disocclusionThresholdOrtho = m_CommonSettings.disocclusionThreshold;// * fabs(zFar - zNear); float depthThresholdOrtho = settings.depthThreshold; // * fabs(zFar - zNear); + float tanHalfFov = 1.0f / m_ViewToClip.a00; + float aspect = m_ViewToClip.a00 / m_ViewToClip.a11; + ml::float3 frustumRight = m_WorldToView.GetRow0().To3d() * tanHalfFov; + ml::float3 frustumUp = m_WorldToView.GetRow1().To3d() * tanHalfFov * aspect; + ml::float3 frustumForward = RELAX_GetFrustumForward(m_ViewToWorld, m_Frustum); + + float prevTanHalfFov = 1.0f / m_ViewToClipPrev.a00; + float prevAspect = m_ViewToClipPrev.a00 / m_ViewToClipPrev.a11; + ml::float3 prevFrustumRight = m_WorldToViewPrev.GetRow0().To3d() * prevTanHalfFov; + ml::float3 prevFrustumUp = m_WorldToViewPrev.GetRow1().To3d() * prevTanHalfFov * prevAspect; + ml::float3 prevFrustumForward = RELAX_GetFrustumForward(m_ViewToWorldPrev, m_FrustumPrev); + bool isCameraStatic = RELAX_IsCameraStatic(ml::float3(m_CameraDelta.x, m_CameraDelta.y, m_CameraDelta.z), frustumRight, frustumUp, frustumForward, prevFrustumRight, prevFrustumUp, prevFrustumForward); + + // Checkerboard logic uint32_t specularCheckerboard = 2; uint32_t diffuseCheckerboard = 2; @@ -375,10 +377,10 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth if (m_CommonSettings.splitScreen >= 1.0f) { Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); + AddFloat(data, m_CommonSettings.splitScreen); AddUint(data, diffuseCheckerboard); AddUint(data, specularCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); ValidateConstants(data); return; @@ -386,7 +388,7 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth // PREPASS Constant* data = PushDispatch(methodData, AsUint(Dispatch::PREPASS)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); AddFloat4(data, m_Rotator[0]); AddUint(data, diffuseCheckerboard); AddUint(data, specularCheckerboard); @@ -394,11 +396,12 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth AddFloat(data, settings.specularPrepassBlurRadius); AddFloat(data, 1.0f); AddFloat(data, m_IsOrtho == 0 ? settings.depthThreshold : depthThresholdOrtho); + AddFloat(data, settings.roughnessFraction); ValidateConstants(data); // REPROJECT data = PushDispatch(methodData, m_CommonSettings.isHistoryConfidenceInputsAvailable ? AsUint(Dispatch::REPROJECT_WITH_CONFIDENCE_INPUTS) : AsUint(Dispatch::REPROJECT)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); AddFloat(data, (float)settings.specularMaxAccumulatedFrameNum); AddFloat(data, (float)settings.specularMaxFastAccumulatedFrameNum); AddFloat(data, (float)settings.diffuseMaxAccumulatedFrameNum); @@ -406,17 +409,18 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth AddUint(data, diffuseCheckerboard); AddUint(data, specularCheckerboard); AddFloat(data, m_IsOrtho == 0 ? m_CommonSettings.disocclusionThreshold : disocclusionThresholdOrtho); + AddFloat(data, settings.roughnessFraction); AddFloat(data, settings.specularVarianceBoost); AddUint(data, settings.enableSpecularVirtualHistoryClamping ? 1 : 0); - AddUint(data, settings.enableSkipReprojectionTestWithoutMotion); + AddUint(data, settings.enableReprojectionTestSkippingWithoutMotion && isCameraStatic); AddUint(data, m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE ? 1 : 0); - AddFloat(data, settings.rejectDiffuseHistoryNormalThreshold); + AddFloat(data, settings.diffuseHistoryRejectionNormalThreshold); AddUint(data, m_CommonSettings.isHistoryConfidenceInputsAvailable ? 1 : 0); ValidateConstants(data); // DISOCCLUSION FIX data = PushDispatch(methodData, AsUint(Dispatch::DISOCCLUSION_FIX)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); AddFloat(data, m_IsOrtho == 0 ? m_CommonSettings.disocclusionThreshold : disocclusionThresholdOrtho); AddFloat(data, settings.disocclusionFixEdgeStoppingNormalPower); AddFloat(data, settings.disocclusionFixMaxRadius); @@ -427,31 +431,24 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth { // HISTORY CLAMPING data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_CLAMPING)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); AddFloat(data, settings.historyClampingColorBoxSigmaScale); ValidateConstants(data); // FIREFLY data = PushDispatch(methodData, AsUint(Dispatch::FIREFLY)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); ValidateConstants(data); } else { // HISTORY CLAMPING WITHOUT FIREFLY data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_CLAMPING_NO_FIREFLY)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); AddFloat(data, settings.historyClampingColorBoxSigmaScale); ValidateConstants(data); } - // SPATIAL VARIANCE ESTIMATION - data = PushDispatch(methodData, AsUint(Dispatch::SPATIAL_VARIANCE_ESTIMATION)); - AddSharedConstants_Relax(methodData, data); - AddFloat(data, settings.phiNormal); - AddUint(data, settings.spatialVarianceEstimationHistoryThreshold); - ValidateConstants(data); - // A-TROUS uint32_t iterationNum = ml::Clamp(settings.atrousIterationNum, 2u, RELAX_MAX_ATROUS_PASS_NUM); for (uint32_t i = 0; i < iterationNum; i++) @@ -465,16 +462,20 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth dispatch = (i % 2 == 0) ? Dispatch::ATROUS_EVEN : Dispatch::ATROUS_ODD; data = PushDispatch(methodData, AsUint(dispatch)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); if (i == 0) + { AddUint2(data, screenW, screenH); // For Atrous_shmem + AddUint(data, settings.spatialVarianceEstimationHistoryThreshold); + } AddFloat(data, settings.specularPhiLuminance); AddFloat(data, settings.diffusePhiLuminance); AddFloat(data, maxLuminanceRelativeDifference); AddFloat(data, m_IsOrtho == 0 ? settings.depthThreshold : depthThresholdOrtho); - AddFloat(data, settings.phiNormal); + AddFloat(data, settings.diffuseLobeAngleFraction); + AddFloat(data, settings.roughnessFraction); AddFloat(data, settings.specularLobeAngleFraction); AddFloat(data, ml::DegToRad(settings.specularLobeAngleSlack)); AddUint(data, 1 << i); @@ -489,10 +490,10 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxDiffuseSpecular(const MethodData& meth if (m_CommonSettings.splitScreen > 0.0f) { data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_DIFFUSE_SPECULAR); + AddFloat(data, m_CommonSettings.splitScreen); AddUint(data, diffuseCheckerboard); AddUint(data, specularCheckerboard); - AddFloat(data, m_CommonSettings.splitScreen); ValidateConstants(data); } } diff --git a/Source/Methods/Relax_Specular.hpp b/Source/Methods/Relax_Specular.hpp index 13d7f25..6d45635 100644 --- a/Source/Methods/Relax_Specular.hpp +++ b/Source/Methods/Relax_Specular.hpp @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) { - #define DENOISER_NAME "RELAX::Specular" + #define METHOD_NAME RELAX_Specular enum class Permanent { @@ -23,6 +23,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) SPEC_HISTORY_LENGTH_CURR, SPEC_HISTORY_LENGTH_PREV, NORMAL_ROUGHNESS_PREV, + MATERIAL_ID_PREV, VIEWZ_CURR, VIEWZ_PREV }; @@ -30,14 +31,15 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); - m_PermanentPool.push_back({ Format::RGBA16_SFLOAT, w, h, 1 }); + m_PermanentPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::R16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::R16_SFLOAT, w, h, 1} ); m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); m_PermanentPool.push_back( {Format::RGBA8_UNORM, w, h, 1} ); - m_PermanentPool.push_back({ Format::R32_SFLOAT, w, h, 1 }); - m_PermanentPool.push_back({ Format::R32_SFLOAT, w, h, 1 }); + m_PermanentPool.push_back( {Format::R8_UNORM, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_SFLOAT, w, h, 1} ); + m_PermanentPool.push_back( {Format::R32_SFLOAT, w, h, 1} ); enum class Transient { @@ -50,11 +52,9 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_TransientPool.push_back( {Format::RGBA16_SFLOAT, w, h, 1} ); m_TransientPool.push_back( {Format::R8_UNORM, w, h, 1} ); - m_TransientPool.push_back({ Format::R16_SFLOAT, w, h, 1 }); + m_TransientPool.push_back( {Format::R16_SFLOAT, w, h, 1} ); - // Shared constants defined in Relax_Diffuse.hpp, - // void nrd::DenoiserImpl::AddSharedConstants_Relax(const MethodData& methodData, Constant*& data) - SetSharedConstants(2, 7, 8, 8); + RELAX_DECLARE_SHARED_CONSTANT_NUM; const uint32_t halfMaxPassNum = (RELAX_MAX_ATROUS_PASS_NUM - 2 + 1) / 2; @@ -68,7 +68,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::VIEWZ_CURR), 0, 1, AsUint(Permanent::VIEWZ_PREV)); PushOutput( AsUint(Transient::VIEWZ_R16F)); - AddDispatch( RELAX_Specular_Prepass, SumConstants(0, 1, 0, 4), 16, 1 ); + AddDispatch( RELAX_Specular_Prepass, SumConstants(0, 1, 0, 5), 16, 1 ); } PushPass("Reproject"); @@ -83,6 +83,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushInput( AsUint(Permanent::VIEWZ_PREV), 0, 1, AsUint(Permanent::VIEWZ_CURR) ); PushInput( AsUint(Permanent::REFLECTION_HIT_T_PREV), 0, 1, AsUint(Permanent::REFLECTION_HIT_T_CURR) ); PushInput( AsUint(Permanent::SPEC_HISTORY_LENGTH_PREV) ); + PushInput( AsUint(Permanent::MATERIAL_ID_PREV) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); // Bogus input that will not be fetched anyway PushOutput( AsUint(Permanent::SPEC_ILLUM_CURR) ); @@ -91,7 +92,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::SPEC_HISTORY_LENGTH_CURR) ); PushOutput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE)); - AddDispatch( RELAX_Specular_Reproject, SumConstants(0, 0, 0, 9), 8, 1 ); + AddDispatch( RELAX_Specular_Reproject, SumConstants(0, 0, 0, 10), 8, 1 ); } PushPass("Reproject"); // With confidence inputs @@ -106,6 +107,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushInput( AsUint(Permanent::VIEWZ_PREV), 0, 1, AsUint(Permanent::VIEWZ_CURR) ); PushInput( AsUint(Permanent::REFLECTION_HIT_T_PREV), 0, 1, AsUint(Permanent::REFLECTION_HIT_T_CURR) ); PushInput( AsUint(Permanent::SPEC_HISTORY_LENGTH_PREV) ); + PushInput( AsUint(Permanent::MATERIAL_ID_PREV) ); PushInput( AsUint(ResourceType::IN_SPEC_CONFIDENCE) ); PushOutput( AsUint(Permanent::SPEC_ILLUM_CURR) ); @@ -114,7 +116,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::SPEC_HISTORY_LENGTH_CURR) ); PushOutput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE)); - AddDispatch( RELAX_Specular_Reproject, SumConstants(0, 0, 0, 9), 8, 1 ); + AddDispatch( RELAX_Specular_Reproject, SumConstants(0, 0, 0, 10), 8, 1 ); } PushPass("Disocclusion fix"); { @@ -139,7 +141,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::SPEC_ILLUM_CURR) ); PushOutput( AsUint(Permanent::SPEC_HISTORY_LENGTH_PREV) ); - AddDispatch( RELAX_Diffuse_HistoryClamping, SumConstants(0, 0, 0, 1), 16, 1 ); + AddDispatch( RELAX_Specular_HistoryClamping, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("History clamping"); // without firefly after it @@ -151,7 +153,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput(AsUint(Permanent::SPEC_ILLUM_PREV)); PushOutput(AsUint(Permanent::SPEC_HISTORY_LENGTH_PREV)); - AddDispatch(RELAX_Diffuse_HistoryClamping, SumConstants(0, 0, 0, 1), 16, 1); + AddDispatch( RELAX_Specular_HistoryClamping, SumConstants(0, 0, 0, 1), 16, 1 ); } PushPass("Anti-firefly"); @@ -162,24 +164,27 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Permanent::SPEC_ILLUM_PREV) ); - AddDispatch( RELAX_Diffuse_Firefly, SumConstants(0, 0, 0, 0), 16, 1 ); + AddDispatch( RELAX_Specular_Firefly, SumConstants(0, 0, 0, 0), 16, 1 ); } - PushPass("Spatial variance estimation"); + // A-trous (first) + PushPass("A-trous (SMEM)"); { PushInput( AsUint(Permanent::SPEC_ILLUM_PREV) ); PushInput( AsUint(Permanent::SPEC_HISTORY_LENGTH_CURR) ); + PushInput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); PushInput( AsUint(Transient::VIEWZ_R16F) ); PushOutput( AsUint(Transient::SPEC_ILLUM_PING) ); PushOutput( AsUint(Permanent::NORMAL_ROUGHNESS_PREV) ); + PushOutput( AsUint(Permanent::MATERIAL_ID_PREV) ); - AddDispatch( RELAX_Specular_SpatialVarianceEstimation, SumConstants(0, 0, 0, 2), 16, 1 ); + AddDispatch( RELAX_Specular_ATrousShmem, SumConstants(0, 0, 1, 13), 8, 1 ); } - // A-trous (first) - PushPass("A-trous (SMEM)"); + // A-trous (odd) + PushPass("A-trous"); { PushInput( AsUint(Transient::SPEC_ILLUM_PING) ); PushInput( AsUint(Permanent::SPEC_HISTORY_LENGTH_CURR) ); @@ -189,10 +194,10 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::SPEC_ILLUM_PONG) ); - AddDispatch( RELAX_Specular_ATrousShmem, SumConstants(0, 0, 1, 11), 8, 1 ); + AddDispatchRepeated( RELAX_Specular_ATrousStandard, SumConstants(0, 0, 0, 12), 16, 1, halfMaxPassNum ); } - // A-trous (odd) + // A-trous (even) PushPass("A-trous"); { PushInput( AsUint(Transient::SPEC_ILLUM_PONG) ); @@ -203,27 +208,13 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint(Transient::SPEC_ILLUM_PING) ); - AddDispatchRepeated( RELAX_Specular_ATrousStandard, SumConstants(0, 0, 0, 11), 16, 1, halfMaxPassNum ); - } - - // A-trous (even) - PushPass("A-trous"); - { - PushInput( AsUint(Transient::SPEC_ILLUM_PING) ); - PushInput( AsUint(Permanent::SPEC_HISTORY_LENGTH_CURR) ); - PushInput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE) ); - PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); - PushInput( AsUint(Transient::VIEWZ_R16F) ); - - PushOutput( AsUint(Transient::SPEC_ILLUM_PONG) ); - - AddDispatchRepeated( RELAX_Specular_ATrousStandard, SumConstants(0, 0, 0, 11), 16, 1, halfMaxPassNum ); + AddDispatchRepeated( RELAX_Specular_ATrousStandard, SumConstants(0, 0, 0, 12), 16, 1, halfMaxPassNum ); } // A-trous (odd, last) PushPass("A-trous"); { - PushInput( AsUint(Transient::SPEC_ILLUM_PONG) ); + PushInput( AsUint(Transient::SPEC_ILLUM_PING) ); PushInput( AsUint(Permanent::SPEC_HISTORY_LENGTH_CURR) ); PushInput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); @@ -231,13 +222,13 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint( ResourceType::OUT_SPEC_RADIANCE_HITDIST ) ); - AddDispatch( RELAX_Specular_ATrousStandard, SumConstants(0, 0, 0, 11), 16, 1 ); + AddDispatch( RELAX_Specular_ATrousStandard, SumConstants(0, 0, 0, 12), 16, 1 ); } // A-trous (even, last) PushPass("A-trous"); { - PushInput( AsUint(Transient::SPEC_ILLUM_PING) ); + PushInput( AsUint(Transient::SPEC_ILLUM_PONG) ); PushInput( AsUint(Permanent::SPEC_HISTORY_LENGTH_CURR) ); PushInput( AsUint(Transient::SPEC_REPROJECTION_CONFIDENCE) ); PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); @@ -245,7 +236,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) PushOutput( AsUint( ResourceType::OUT_SPEC_RADIANCE_HITDIST ) ); - AddDispatch( RELAX_Specular_ATrousStandard, SumConstants(0, 0, 0, 11), 16, 1 ); + AddDispatch( RELAX_Specular_ATrousStandard, SumConstants(0, 0, 0, 12), 16, 1 ); } PushPass("Split screen"); @@ -258,7 +249,7 @@ size_t nrd::DenoiserImpl::AddMethod_RelaxSpecular(uint16_t w, uint16_t h) AddDispatch( RELAX_Specular_SplitScreen, SumConstants(0, 0, 0, 2), 16, 1 ); } - #undef DENOISER_NAME + #undef METHOD_NAME return sizeof(RelaxSpecularSettings); } @@ -274,7 +265,6 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxSpecular(const MethodData& methodData) HISTORY_CLAMPING, HISTORY_CLAMPING_NO_FIREFLY, FIREFLY, - SPATIAL_VARIANCE_ESTIMATION, ATROUS_SMEM, ATROUS_ODD, ATROUS_EVEN, @@ -299,6 +289,20 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxSpecular(const MethodData& methodData) float disocclusionThresholdOrtho = m_CommonSettings.disocclusionThreshold;// * fabs(zFar - zNear); float depthThresholdOrtho = settings.depthThreshold; // * fabs(zFar - zNear); + float tanHalfFov = 1.0f / m_ViewToClip.a00; + float aspect = m_ViewToClip.a00 / m_ViewToClip.a11; + ml::float3 frustumRight = m_WorldToView.GetRow0().To3d() * tanHalfFov; + ml::float3 frustumUp = m_WorldToView.GetRow1().To3d() * tanHalfFov * aspect; + ml::float3 frustumForward = RELAX_GetFrustumForward(m_ViewToWorld, m_Frustum); + + float prevTanHalfFov = 1.0f / m_ViewToClipPrev.a00; + float prevAspect = m_ViewToClipPrev.a00 / m_ViewToClipPrev.a11; + ml::float3 prevFrustumRight = m_WorldToViewPrev.GetRow0().To3d() * prevTanHalfFov; + ml::float3 prevFrustumUp = m_WorldToViewPrev.GetRow1().To3d() * prevTanHalfFov * prevAspect; + ml::float3 prevFrustumForward = RELAX_GetFrustumForward(m_ViewToWorldPrev, m_FrustumPrev); + bool isCameraStatic = RELAX_IsCameraStatic(ml::float3(m_CameraDelta.x, m_CameraDelta.y, m_CameraDelta.z), frustumRight, frustumUp, frustumForward, prevFrustumRight, prevFrustumUp, prevFrustumForward); + + uint32_t specularCheckerboard = 2; switch (settings.checkerboardMode) @@ -317,9 +321,9 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxSpecular(const MethodData& methodData) if (m_CommonSettings.splitScreen >= 1.0f) { Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_Relax(methodData, data); - AddUint(data, specularCheckerboard); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); AddFloat(data, m_CommonSettings.splitScreen); + AddUint(data, specularCheckerboard); ValidateConstants(data); return; @@ -327,31 +331,33 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxSpecular(const MethodData& methodData) // PREPASS Constant* data = PushDispatch(methodData, AsUint(Dispatch::PREPASS)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); AddFloat4(data, m_Rotator[0]); AddUint(data, specularCheckerboard); AddFloat(data, settings.prepassBlurRadius); AddFloat(data, 1.0f); AddFloat(data, m_IsOrtho == 0 ? settings.depthThreshold : depthThresholdOrtho); + AddFloat(data, settings.roughnessFraction); ValidateConstants(data); // REPROJECT data = PushDispatch(methodData, m_CommonSettings.isHistoryConfidenceInputsAvailable ? AsUint(Dispatch::REPROJECT_WITH_CONFIDENCE_INPUTS) : AsUint(Dispatch::REPROJECT)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); AddFloat(data, (float)settings.specularMaxAccumulatedFrameNum); AddFloat(data, (float)settings.specularMaxFastAccumulatedFrameNum); AddUint(data, specularCheckerboard); AddFloat(data, m_IsOrtho == 0 ? m_CommonSettings.disocclusionThreshold : disocclusionThresholdOrtho); + AddFloat(data, settings.roughnessFraction); AddFloat(data, settings.specularVarianceBoost); AddUint(data, settings.enableSpecularVirtualHistoryClamping ? 1 : 0); - AddUint(data, settings.enableSkipReprojectionTestWithoutMotion); + AddUint(data, settings.enableReprojectionTestSkippingWithoutMotion && isCameraStatic); AddUint(data, m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE ? 1 : 0); AddUint(data, m_CommonSettings.isHistoryConfidenceInputsAvailable ? 1 : 0); ValidateConstants(data); // DISOCCLUSION FIX data = PushDispatch(methodData, AsUint(Dispatch::DISOCCLUSION_FIX)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); AddFloat(data, m_IsOrtho == 0 ? m_CommonSettings.disocclusionThreshold : disocclusionThresholdOrtho); AddFloat(data, settings.disocclusionFixEdgeStoppingNormalPower); AddFloat(data, settings.disocclusionFixMaxRadius); @@ -362,31 +368,24 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxSpecular(const MethodData& methodData) { // HISTORY CLAMPING data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_CLAMPING)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); AddFloat(data, settings.historyClampingColorBoxSigmaScale); ValidateConstants(data); // FIREFLY data = PushDispatch(methodData, AsUint(Dispatch::FIREFLY)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); ValidateConstants(data); } else { // HISTORY CLAMPING WITHOUT FIREFLY data = PushDispatch(methodData, AsUint(Dispatch::HISTORY_CLAMPING_NO_FIREFLY)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); AddFloat(data, settings.historyClampingColorBoxSigmaScale); ValidateConstants(data); } - // SPATIAL VARIANCE ESTIMATION - data = PushDispatch(methodData, AsUint(Dispatch::SPATIAL_VARIANCE_ESTIMATION)); - AddSharedConstants_Relax(methodData, data); - AddFloat(data, settings.phiNormal); - AddUint(data, settings.spatialVarianceEstimationHistoryThreshold); - ValidateConstants(data); - // A-TROUS uint32_t iterationNum = ml::Clamp(settings.atrousIterationNum, 2u, RELAX_MAX_ATROUS_PASS_NUM); for (uint32_t i = 0; i < iterationNum; i++) @@ -400,17 +399,19 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxSpecular(const MethodData& methodData) dispatch = (i % 2 == 0) ? Dispatch::ATROUS_EVEN : Dispatch::ATROUS_ODD; data = PushDispatch(methodData, AsUint(dispatch)); - AddSharedConstants_Relax(methodData, data); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); if (i == 0) { AddUint2(data, screenW, screenH); // For Atrous_shmem + AddUint(data, settings.spatialVarianceEstimationHistoryThreshold); } AddFloat(data, settings.specularPhiLuminance); AddFloat(data, maxLuminanceRelativeDifference); AddFloat(data, m_IsOrtho == 0 ? settings.depthThreshold : depthThresholdOrtho); - AddFloat(data, settings.phiNormal); + AddFloat(data, settings.diffuseLobeAngleFraction); + AddFloat(data, settings.roughnessFraction); AddFloat(data, settings.specularLobeAngleFraction); AddFloat(data, ml::DegToRad(settings.specularLobeAngleSlack)); AddUint(data, 1 << i); @@ -425,9 +426,9 @@ void nrd::DenoiserImpl::UpdateMethod_RelaxSpecular(const MethodData& methodData) if (m_CommonSettings.splitScreen > 0.0f) { data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_Relax(methodData, data); - AddUint(data, specularCheckerboard); + AddSharedConstants_Relax(methodData, data, nrd::Method::RELAX_SPECULAR); AddFloat(data, m_CommonSettings.splitScreen); + AddUint(data, specularCheckerboard); ValidateConstants(data); } } diff --git a/Source/Methods/Sigma_Shadow.hpp b/Source/Methods/Sigma_Shadow.hpp index 05b6a05..ff23c55 100644 --- a/Source/Methods/Sigma_Shadow.hpp +++ b/Source/Methods/Sigma_Shadow.hpp @@ -8,9 +8,11 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ +#define SIGMA_DECLARE_SHARED_CONSTANT_NUM SetSharedConstants(1, 1, 9, 10) + size_t nrd::DenoiserImpl::AddMethod_SigmaShadow(uint16_t w, uint16_t h) { - #define DENOISER_NAME "SIGMA::Shadow" + #define METHOD_NAME SIGMA_Shadow enum class Transient { @@ -34,7 +36,7 @@ size_t nrd::DenoiserImpl::AddMethod_SigmaShadow(uint16_t w, uint16_t h) m_TransientPool.push_back( {Format::RG8_UNORM, tilesW, tilesH, 1} ); m_TransientPool.push_back( {Format::R8_UNORM, tilesW, tilesH, 1} ); - SetSharedConstants(1, 1, 9, 10); + SIGMA_DECLARE_SHARED_CONSTANT_NUM; PushPass("Classify tiles"); { @@ -102,9 +104,9 @@ size_t nrd::DenoiserImpl::AddMethod_SigmaShadow(uint16_t w, uint16_t h) AddDispatch( SIGMA_Shadow_SplitScreen, SumConstants(0, 0, 0, 1), 16, 1 ); } - #undef DENOISER_NAME + #undef METHOD_NAME - return sizeof(SigmaShadowSettings); + return sizeof(SigmaSettings); } void nrd::DenoiserImpl::UpdateMethod_SigmaShadow(const MethodData& methodData) @@ -119,7 +121,7 @@ void nrd::DenoiserImpl::UpdateMethod_SigmaShadow(const MethodData& methodData) SPLIT_SCREEN, }; - const SigmaShadowSettings& settings = methodData.settings.shadowSigma; + const SigmaSettings& settings = methodData.settings.sigma; NRD_DECLARE_DIMS; @@ -130,7 +132,7 @@ void nrd::DenoiserImpl::UpdateMethod_SigmaShadow(const MethodData& methodData) if (m_CommonSettings.splitScreen >= 1.0f) { Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat(data, m_CommonSettings.splitScreen); ValidateConstants(data); @@ -139,32 +141,32 @@ void nrd::DenoiserImpl::UpdateMethod_SigmaShadow(const MethodData& methodData) // CLASSIFY_TILES Constant* data = PushDispatch(methodData, AsUint(Dispatch::CLASSIFY_TILES)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); ValidateConstants(data); // SMOOTH_TILES data = PushDispatch(methodData, AsUint(Dispatch::SMOOTH_TILES)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddUint2(data, tilesW, tilesH); ValidateConstants(data); // PRE_BLUR data = PushDispatch(methodData, AsUint(Dispatch::PRE_BLUR)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[0]); ValidateConstants(data); // BLUR data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[1]); ValidateConstants(data); // TEMPORAL_STABILIZATION data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_STABILIZATION)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat4x4(data, m_WorldToClipPrev); AddFloat4x4(data, m_ViewToWorld); AddUint(data, m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE ? 1 : 0); @@ -174,13 +176,13 @@ void nrd::DenoiserImpl::UpdateMethod_SigmaShadow(const MethodData& methodData) if (m_CommonSettings.splitScreen > 0.0f) { data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat(data, m_CommonSettings.splitScreen); ValidateConstants(data); } } -void nrd::DenoiserImpl::AddSharedConstants_SigmaShadow(const MethodData& methodData, const SigmaShadowSettings& settings, Constant*& data) +void nrd::DenoiserImpl::AddSharedConstants_Sigma(const MethodData& methodData, const SigmaSettings& settings, Constant*& data) { NRD_DECLARE_DIMS; diff --git a/Source/Methods/Sigma_ShadowTranslucency.hpp b/Source/Methods/Sigma_ShadowTranslucency.hpp index 74ed0d5..71987e8 100644 --- a/Source/Methods/Sigma_ShadowTranslucency.hpp +++ b/Source/Methods/Sigma_ShadowTranslucency.hpp @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. size_t nrd::DenoiserImpl::AddMethod_SigmaShadowTranslucency(uint16_t w, uint16_t h) { - #define DENOISER_NAME "SIGMA::ShadowTranscluency" + #define METHOD_NAME SIGMA_ShadowTranslucency enum class Transient { @@ -34,7 +34,7 @@ size_t nrd::DenoiserImpl::AddMethod_SigmaShadowTranslucency(uint16_t w, uint16_t m_TransientPool.push_back( {Format::RG8_UNORM, tilesW, tilesH, 1} ); m_TransientPool.push_back( {Format::R8_UNORM, tilesW, tilesH, 1} ); - SetSharedConstants(1, 1, 9, 10); + SIGMA_DECLARE_SHARED_CONSTANT_NUM; PushPass("Classify tiles"); { @@ -105,9 +105,9 @@ size_t nrd::DenoiserImpl::AddMethod_SigmaShadowTranslucency(uint16_t w, uint16_t AddDispatch( SIGMA_ShadowTranslucency_SplitScreen, SumConstants(0, 0, 0, 1), 16, 1 ); } - #undef DENOISER_NAME + #undef METHOD_NAME - return sizeof(SigmaShadowSettings); + return sizeof(SigmaSettings); } void nrd::DenoiserImpl::UpdateMethod_SigmaShadowTranslucency(const MethodData& methodData) @@ -122,7 +122,7 @@ void nrd::DenoiserImpl::UpdateMethod_SigmaShadowTranslucency(const MethodData& m SPLIT_SCREEN, }; - const SigmaShadowSettings& settings = methodData.settings.shadowSigma; + const SigmaSettings& settings = methodData.settings.sigma; NRD_DECLARE_DIMS; @@ -133,7 +133,7 @@ void nrd::DenoiserImpl::UpdateMethod_SigmaShadowTranslucency(const MethodData& m if (m_CommonSettings.splitScreen >= 1.0f) { Constant* data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat(data, m_CommonSettings.splitScreen); ValidateConstants(data); @@ -142,32 +142,32 @@ void nrd::DenoiserImpl::UpdateMethod_SigmaShadowTranslucency(const MethodData& m // CLASSIFY_TILES Constant* data = PushDispatch(methodData, AsUint(Dispatch::CLASSIFY_TILES)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); ValidateConstants(data); // SMOOTH_TILES data = PushDispatch(methodData, AsUint(Dispatch::SMOOTH_TILES)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddUint2(data, tilesW, tilesH); ValidateConstants(data); // PRE_BLUR data = PushDispatch(methodData, AsUint(Dispatch::PRE_BLUR)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[0]); ValidateConstants(data); // BLUR data = PushDispatch(methodData, AsUint(Dispatch::BLUR)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat4x4(data, m_WorldToView); AddFloat4(data, m_Rotator[1]); ValidateConstants(data); // TEMPORAL_STABILIZATION data = PushDispatch(methodData, AsUint(Dispatch::TEMPORAL_STABILIZATION)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat4x4(data, m_WorldToClipPrev); AddFloat4x4(data, m_ViewToWorld); AddUint(data, m_CommonSettings.accumulationMode != AccumulationMode::CONTINUE ? 1 : 0); @@ -177,7 +177,7 @@ void nrd::DenoiserImpl::UpdateMethod_SigmaShadowTranslucency(const MethodData& m if (m_CommonSettings.splitScreen > 0.0f) { data = PushDispatch(methodData, AsUint(Dispatch::SPLIT_SCREEN)); - AddSharedConstants_SigmaShadow(methodData, settings, data); + AddSharedConstants_Sigma(methodData, settings, data); AddFloat(data, m_CommonSettings.splitScreen); ValidateConstants(data); } diff --git a/Source/Methods/SpecularReflectionMv.hpp b/Source/Methods/SpecularReflectionMv.hpp new file mode 100644 index 0000000..00334ce --- /dev/null +++ b/Source/Methods/SpecularReflectionMv.hpp @@ -0,0 +1,59 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +size_t nrd::DenoiserImpl::AddMethod_SpecularReflectionMv() +{ + #define METHOD_NAME SpecularReflectionMv + + SetSharedConstants(0, 0, 0, 0); + + PushPass("Compute"); + { + PushInput( AsUint(ResourceType::IN_MV) ); + PushInput( AsUint(ResourceType::IN_NORMAL_ROUGHNESS) ); + PushInput( AsUint(ResourceType::IN_VIEWZ) ); + PushInput( AsUint(ResourceType::IN_SPEC_HITDIST) ); + + PushOutput( AsUint(ResourceType::OUT_SPEC_REFLECTION_MV) ); + + AddDispatch( SpecularReflectionMv_Compute, SumConstants(2, 2, 3, 2), 16, 1 ); + } + + #undef METHOD_NAME + + return sizeof(SpecularReflectionMvSettings); +} + +void nrd::DenoiserImpl::UpdateMethod_SpecularReflectionMv(const MethodData& methodData) +{ + enum class Dispatch + { + COMPUTE, + }; + + NRD_DECLARE_DIMS; + + // DRS will increase reprojected values, needed for stability, compensated by blur radius adjustment + float unproject = 1.0f / (0.5f * rectH * m_ProjectY); + + // COMPUTE + Constant* data = PushDispatch(methodData, AsUint(Dispatch::COMPUTE)); + AddFloat4x4(data, m_ViewToWorld); + AddFloat4x4(data, m_WorldToClipPrev); + AddFloat4(data, m_Frustum); + AddFloat4(data, ml::float4(m_ViewDirection.x, m_ViewDirection.y, m_ViewDirection.z, 0.0f)); + AddFloat2(data, 1.0f / float(rectW), 1.0f / float(rectH)); + AddFloat2(data, m_CommonSettings.motionVectorScale[0], m_CommonSettings.motionVectorScale[1]); + AddUint2(data, m_CommonSettings.inputSubrectOrigin[0], m_CommonSettings.inputSubrectOrigin[1]); + AddFloat(data, m_IsOrtho); + AddFloat(data, unproject); + AddUint(data, m_CommonSettings.isMotionVectorInWorldSpace ? 1 : 0); + ValidateConstants(data); +} diff --git a/Source/Shaders/DeltaOptimizationMv/DeltaOptimizationMv_Compute.cs.hlsl b/Source/Shaders/DeltaOptimizationMv/DeltaOptimizationMv_Compute.cs.hlsl new file mode 100644 index 0000000..575da7c --- /dev/null +++ b/Source/Shaders/DeltaOptimizationMv/DeltaOptimizationMv_Compute.cs.hlsl @@ -0,0 +1,153 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "NRD.hlsli" +#include "STL.hlsli" +#include "DeltaOptimizationMv/DeltaOptimizationMv_Compute.resources.hlsli" + +NRD_DECLARE_CONSTANTS + +#include "NRD_Common.hlsli" + +NRD_DECLARE_SAMPLERS + +NRD_DECLARE_INPUT_TEXTURES +NRD_DECLARE_OUTPUT_TEXTURES + +// acos(dot(a,b)) has severe precision issues for small angles +// length(cross(a,b)) == length(a) * length(b) * sin(angle) +// dot(a,b) == length(a) * length(b) * cos(angle) +float GetAngle(float3 a, float3 b) +{ + float s = saturate(length(cross(a, b))); + float c = saturate(dot(a, b)); + return atan2(s, c); +} + +float3 LoadCandidate(float2 samplePos) +{ + return gIn_PrevDeltaSecondaryPosW.SampleLevel(gLinearClamp, samplePos * gInvRectSize, 0.f).xyz; +} + +float LoadAngle(float2 samplePos, float3 primaryPosW, float3 refDir) +{ + float3 candidate = LoadCandidate(samplePos); + float3 cDir = normalize(candidate - primaryPosW); + float angle = GetAngle(cDir, refDir); + // angle^2 behaves much better + return angle * angle; +} + +[numthreads(GROUP_X, GROUP_Y, 1)] +NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId) +{ + static const float kMotionEpsilon = 1.e-4; + static const float kAngleEpsilon = 1.e-8; + static const float kAngleConvergenceEpsilon = 1.e-2; + // TODO: Expose these 2 parameters. + static const uint kMaxNewtonMethodIterations = 5; + static const uint kMaxLineSearchIterations = 10; + + const uint2 pixelPosUser = gRectOrigin + pixelPos; + + if (any(pixelPosUser >= gRectSize)) return; + + float3 initialMotion = gIn_ObjectMotion[pixelPosUser].xyz; + float3 primaryPosW = gIn_DeltaPrimaryPosW[pixelPosUser].xyz; + float3 secondaryPosW = gIn_DeltaSecondaryPosW[pixelPosUser].xyz; + + gOut_DeltaSecondaryPosW[pixelPosUser] = secondaryPosW; + + float2 pixelUv = float2(pixelPosUser + 0.5f) * gInvRectSize; + float2 prevPixelUV = STL::Geometry::GetPrevUvFromMotion(pixelUv, primaryPosW, gWorldToClipPrev, initialMotion, gIsWorldSpaceMotionEnabled); + float2 initialScreenMotion = prevPixelUV - pixelUv; + + // TODO: Add detection for secondary motion. + if (length(initialScreenMotion) >= kMotionEpsilon) + { + float2 prevSamplePos = prevPixelUV * gRectSize; + + float3 v = normalize(secondaryPosW - primaryPosW); + + float currAngle = LoadAngle(prevSamplePos, primaryPosW, v); + + for (uint i = 0; i < kMaxNewtonMethodIterations; ++i) + { + if (currAngle < kAngleEpsilon) + { + gOut_DeltaMv[pixelPosUser] = prevSamplePos * gInvRectSize - pixelUv; + return; + } + + const float h = 1.f; + float da_dx = (LoadAngle(prevSamplePos + float2(h, 0), primaryPosW, v) - LoadAngle(prevSamplePos + float2(-h, 0), primaryPosW, v)) / (2.f * h); + float da_dy = (LoadAngle(prevSamplePos + float2(0, h), primaryPosW, v) - LoadAngle(prevSamplePos + float2(0, -h), primaryPosW, v)) / (2.f * h); + float d2a_dx2 = (LoadAngle(prevSamplePos + float2(h, 0), primaryPosW, v) - 2 * currAngle + LoadAngle(prevSamplePos + float2(-h, 0), primaryPosW, v)) / (h * h); + float d2a_dy2 = (LoadAngle(prevSamplePos + float2(0, h), primaryPosW, v) - 2 * currAngle + LoadAngle(prevSamplePos + float2(0, -h), primaryPosW, v)) / (h * h); + float d2a_dxdy = ( + LoadAngle(prevSamplePos + float2(h, h), primaryPosW, v) + - LoadAngle(prevSamplePos + float2(h, -h), primaryPosW, v) + - LoadAngle(prevSamplePos + float2(-h, h), primaryPosW, v) + + LoadAngle(prevSamplePos + float2(-h, -h), primaryPosW, v) + ) / (4.f * h * h); + + // Gradient + float f0 = da_dx; + float f1 = da_dy; + + // Hessian + float j00 = d2a_dx2; + float j01 = d2a_dxdy; + float j11 = d2a_dy2; + + // Hessian inverse + float tmp1 = j00*j11 - j01*j01; + + // Can't find a suitable position, fallback to primary surface mvec + if (abs(tmp1) < 1e-15) + { + gOut_DeltaMv[pixelPosUser] = initialScreenMotion; + return; + } + + tmp1 = 1.f / tmp1; + float J00 = j11 * tmp1; + float J01 = -j01 * tmp1; + float J10 = -j01 * tmp1; + float J11 = j00 * tmp1; + + float2 displacement = -float2(J00*f0 + J01*f1, J10*f0 + J11*f1); + + // Backtracking line search with Armijo condition + float t = 1.0; + float alpha = 0.01; // in (0, 0.5] + float beta = 0.5; // in (0, 1) + float2 grad = float2(f0, f1); + + float tmp2 = alpha * dot(grad, displacement); + uint iter = 0; + while (LoadAngle(prevSamplePos + t * displacement, primaryPosW, v) > (currAngle + t * tmp2) && iter < kMaxLineSearchIterations) + { + t = beta * t; + ++iter; + } + + prevSamplePos += t * displacement; + } + + if (currAngle < kAngleConvergenceEpsilon) + { + gOut_DeltaMv[pixelPosUser] = prevSamplePos * gInvRectSize - pixelUv; + return; + } + } + + gOut_DeltaMv[pixelPosUser] = initialScreenMotion; +} diff --git a/Source/Shaders/Include/DeltaOptimizationMv/DeltaOptimizationMv_Compute.resources.hlsli b/Source/Shaders/Include/DeltaOptimizationMv/DeltaOptimizationMv_Compute.resources.hlsli new file mode 100644 index 0000000..01918ad --- /dev/null +++ b/Source/Shaders/Include/DeltaOptimizationMv/DeltaOptimizationMv_Compute.resources.hlsli @@ -0,0 +1,32 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ObjectMotion, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_DeltaPrimaryPosW, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_DeltaSecondaryPosW, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_PrevDeltaSecondaryPosW, t, 3 ) + +#define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_DeltaMv, u, 0 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_DeltaSecondaryPosW, u, 1 ) + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ + NRD_CONSTANT( uint2, gRectSize ) \ + NRD_CONSTANT( float2, gInvRectSize ) \ + NRD_CONSTANT( float2, gMotionVectorScale ) \ + NRD_CONSTANT( uint2, gRectOrigin ) \ + NRD_CONSTANT( uint, gIsWorldSpaceMotionEnabled ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/NRD_Common.hlsli b/Source/Shaders/Include/NRD_Common.hlsli index 460ab9f..794d2d9 100644 --- a/Source/Shaders/Include/NRD_Common.hlsli +++ b/Source/Shaders/Include/NRD_Common.hlsli @@ -26,7 +26,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. // FP16 -#ifdef COMPILER_DXC +#ifdef NRD_COMPILER_DXC #define half_float float16_t #define half_float2 float16_t2 #define half_float3 float16_t3 @@ -42,33 +42,13 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. // DEFAULT SETTINGS (can be modified) //================================================================================================================== -#ifndef NRD_USE_SANITIZATION - #define NRD_USE_SANITIZATION 0 // bool -#endif - -#ifndef NRD_USE_QUADRATIC_DISTRIBUTION - #define NRD_USE_QUADRATIC_DISTRIBUTION 0 // bool -#endif - -#ifndef NRD_BILATERAL_WEIGHT_VIEWZ_SENSITIVITY - #define NRD_BILATERAL_WEIGHT_VIEWZ_SENSITIVITY 100.0 // w = 1 / (1 + this * z) -#endif - -#ifndef NRD_BILATERAL_WEIGHT_CUTOFF - #define NRD_BILATERAL_WEIGHT_CUTOFF 0.03 // normalized % // TODO: 1-2%? -#endif - -#ifndef NRD_CATROM_SHARPNESS - #define NRD_CATROM_SHARPNESS 0.5 // [0; 1], 0.5 matches Catmull-Rom -#endif - -#if( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_UNORM8 ) - #define NRD_ENCODING_ERRORS float2( STL::Math::DegToRad( 1.2 ), 0.0025 ) -#elif( NRD_NORMAL_ENCODING == NRD_NORMAL_ENCODING_OCT10 ) - #define NRD_ENCODING_ERRORS float2( STL::Math::DegToRad( 0.4 ), 0.001 ) -#else - #define NRD_ENCODING_ERRORS float2( STL::Math::DegToRad( 0 ), 0.0 ) -#endif +#define NRD_USE_SANITIZATION 0 // bool +#define NRD_USE_QUADRATIC_DISTRIBUTION 0 // bool +#define NRD_BILATERAL_WEIGHT_VIEWZ_SENSITIVITY 100.0 // w = 1 / ( 1 + this * z ) +#define NRD_BILATERAL_WEIGHT_CUTOFF 0.03 // normalized % // TODO: 1-2%? +#define NRD_CATROM_SHARPNESS 0.5 // [ 0; 1 ], 0.5 matches Catmull-Rom +#define NRD_ENCODING_ERRORS float2( STL::Math::DegToRad( 0.5 ), 0.0002 ) +#define NRD_PARALLAX_NORMALIZATION 30.0 // was 60 in normal mode ( too laggy ) and 30 in reference and ortho modes //================================================================================================================== // CTA & preloading @@ -110,6 +90,15 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. // Misc +// sigma = standard deviation, variance = sigma ^ 2 +#define GetStdDev( m1, m2 ) sqrt( abs( ( m2 ) - ( m1 ) * ( m1 ) ) ) // sqrt( max( m2 - m1 * m1, 0.0 ) ) + +#if( NRD_USE_MATERIAL_ID == 1 ) + #define CompareMaterials( m0, m, mask ) ( ( mask ) == 0 ? 1.0 : ( ( m0 ) == ( m ) ) ) +#else + #define CompareMaterials( m0, m, mask ) 1.0 +#endif + #if( NRD_USE_SANITIZATION == 1 ) float4 Sanitize( float4 x, float4 replacer ) { @@ -135,12 +124,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define Sanitize( x, replacer ) ( x ) #endif -// sigma = standard deviation, variance = sigma ^ 2 -#define GetStdDev( m1, m2 ) sqrt( abs( m2 - m1 * m1 ) ) // sqrt( max( m2 - m1 * m1, 0.0 ) ) - -float PixelRadiusToWorld( float unproject, float isOrtho, float pixelRadius, float viewZ ) +float PixelRadiusToWorld( float unproject, float orthoMode, float pixelRadius, float viewZ ) { - return pixelRadius * unproject * lerp( viewZ, 1.0, abs( isOrtho ) ); + return pixelRadius * unproject * lerp( viewZ, 1.0, abs( orthoMode ) ); } float4 GetBlurKernelRotation( compiletime const uint mode, uint2 pixelPos, float4 baseRotator, uint frameIndex ) @@ -182,15 +168,39 @@ float2 ApplyCheckerboard( inout float2 uv, uint mode, uint counter, float2 scree int2 uvi = int2( uv * screenSize ); bool hasData = STL::Sequence::CheckerBoard( uvi, frameIndex ) == mode; if( !hasData ) - uvi.y += ( ( counter & 0x1 ) == 0 ) ? -1 : 1; + uvi.x += ( ( counter & 0x1 ) == 0 ) ? -1 : 1; uv = ( float2( uvi ) + 0.5 ) * invScreenSize; return float2( uv.x * 0.5, uv.y ); } -bool CompareMaterials( uint m0, uint m, uint mask ) +float GetSpecMagicCurve( float roughness, float power = 0.25 ) { - return ( m0 & mask ) == ( m & mask ); + // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtMl4oLTE1LjAqeCkiLCJjb2xvciI6IiNGMjE4MTgifSx7InR5cGUiOjAsImVxIjoiKDEtMl4oLTIwMCp4KngpKSooeF4wLjI1KSIsImNvbG9yIjoiIzIyRUQxNyJ9LHsidHlwZSI6MCwiZXEiOiIoMS0yXigtMjAwKngqeCkpKih4XjAuNSkiLCJjb2xvciI6IiMxNzE2MTYifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMSIsIjAiLCIxLjEiXSwic2l6ZSI6WzEwMDAsNTAwXX1d + + float f = 1.0 - exp2( -200.0 * roughness * roughness ); + f *= STL::Math::Pow01( roughness, power ); + + return f; +} + +float ComputeParallax( float3 X, float3 Xprev, float4 cameraDelta, bool orthoMode ) +{ + float3 Xt = Xprev - cameraDelta.xyz; + float p = dot( X, Xt ); + float parallax = sqrt( max( dot( X, X ) * dot( Xt, Xt ) - p * p, 0.0 ) ) / p; + + // Special case for ortho projection, where translation doesn't introduce parallax + parallax = orthoMode ? cameraDelta.w : parallax; // TODO: do it better! + + return parallax * NRD_PARALLAX_NORMALIZATION; +} + +float GetParallaxInPixels( float parallax, float unproject ) // TODO: ortho! +{ + float parallaxInPixels = parallax / ( NRD_PARALLAX_NORMALIZATION * unproject ); + + return parallaxInPixels; } // Kernel @@ -227,6 +237,9 @@ float2 GetGeometryWeightParams( float planeDistSensitivity, float frustumHeight, #define _ComputeWeight( p, value ) STL::Math::SmoothStep01( 1.0 - abs( value * p.x + p.y ) ) +#define GetRoughnessWeight( p, value ) _ComputeWeight( p, value ) +#define GetHitDistanceWeight( p, value ) _ComputeWeight( p, value ) + float GetGeometryWeight( float2 params0, float3 n0, float3 p ) { float d = dot( n0, p ); @@ -272,14 +285,14 @@ float4 GetBilateralWeight( float4 z, float zc ) float w4 = w12.x * w3.y; \ /* Fallback to custom bilinear */ \ w = useBicubic ? w : bilinearCustomWeights; \ - w4 = useBicubic ? w4 : 0.0001; \ + w4 = useBicubic ? w4 : 0.00001; \ float invSum = 1.0 / ( dot( w, 1.0 ) + w4 ); \ /* Texture coordinates */ \ float2 uv0 = centerPos + ( useBicubic ? float2( tc2.x, tc0.y ) : float2( 0, 0 ) ); \ float2 uv1 = centerPos + ( useBicubic ? float2( tc0.x, tc2.y ) : float2( 1, 0 ) ); \ float2 uv2 = centerPos + ( useBicubic ? float2( tc2.x, tc2.y ) : float2( 0, 1 ) ); \ float2 uv3 = centerPos + ( useBicubic ? float2( tc3.x, tc2.y ) : float2( 1, 1 ) ); \ - float2 uv4 = centerPos + ( useBicubic ? float2( tc2.x, tc3.y ) : float2( 0, 0 ) ); + float2 uv4 = centerPos + ( useBicubic ? float2( tc2.x, tc3.y ) : f ); // if NRD_USE_MATERIAL_ID = 1, failed reprojection ends here. If material test is OFF we must get a bilinear sample #define _BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights_Color( color, tex ) \ /* Sampling */ \ diff --git a/Source/Shaders/Include/REBLUR_Common.hlsli b/Source/Shaders/Include/REBLUR_Common.hlsli index 253cf90..79525cf 100644 --- a/Source/Shaders/Include/REBLUR_Common.hlsli +++ b/Source/Shaders/Include/REBLUR_Common.hlsli @@ -17,34 +17,28 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. // Storage #define REBLUR_ACCUMSPEED_BITS 6 -#define REBLUR_NORMAL_ROUGHNESS_ACCUMSPEED_BITS 9, 9, 14 - REBLUR_ACCUMSPEED_BITS, REBLUR_ACCUMSPEED_BITS +#define REBLUR_NORMAL_ACCUMSPEED_MATERIALID_BITS 12, 12, REBLUR_ACCUMSPEED_BITS, 2 // sum == 32! #define REBLUR_MAX_ACCUM_FRAME_NUM ( (1 << REBLUR_ACCUMSPEED_BITS ) - 1 ) +#define REBLUR_ROUGHNESS_ULP ( 1.0 / 255.0 ) +#define REBLUR_NORMAL_ULP STL::Math::DegToRad( 0.05 ) // Shared data -groupshared float4 s_Normal_Roughness[ BUFFER_Y ][ BUFFER_X ]; +groupshared float3 s_Normal[ BUFFER_Y ][ BUFFER_X ]; groupshared float s_ViewZ[ BUFFER_Y ][ BUFFER_X ]; // Data packing for the next frame -uint2 PackViewZNormalRoughnessAccumSpeeds( float viewZ, float diffAccumSpeed, float3 N, float roughness, float specAccumSpeed ) +uint PackViewZAccumSpeed( float viewZ, float diffAccumSpeed ) { - float t1 = diffAccumSpeed / REBLUR_MAX_ACCUM_FRAME_NUM; + float t = diffAccumSpeed / REBLUR_MAX_ACCUM_FRAME_NUM; uint crunchedViewZ = asuint( viewZ ) & ~REBLUR_MAX_ACCUM_FRAME_NUM; - - float4 t2; - t2.xy = STL::Packing::EncodeUnitVector( N ); - t2.z = roughness; - t2.w = specAccumSpeed / REBLUR_MAX_ACCUM_FRAME_NUM; - - uint2 p; - p.x = crunchedViewZ | STL::Packing::RgbaToUint( t1, REBLUR_ACCUMSPEED_BITS, 0, 0, 0 ).x; - p.y = STL::Packing::RgbaToUint( t2, REBLUR_NORMAL_ROUGHNESS_ACCUMSPEED_BITS ); + uint p = crunchedViewZ | STL::Packing::RgbaToUint( t, REBLUR_ACCUMSPEED_BITS, 0, 0, 0 ).x; return p; } -float4 UnpackViewZ( uint4 p ) +float4 UnpackPrevViewZ( uint4 p ) { return asfloat( p & ~REBLUR_MAX_ACCUM_FRAME_NUM ); } @@ -54,30 +48,35 @@ float4 UnpackDiffAccumSpeed( uint4 p ) return float4( p & REBLUR_MAX_ACCUM_FRAME_NUM ); } -float4 UnpackNormalRoughness( uint p ) +uint PackNormalAccumSpeedMaterialID( float3 N, float specAccumSpeed, float materialID ) { - float4 t = STL::Packing::UintToRgba( p, REBLUR_NORMAL_ROUGHNESS_ACCUMSPEED_BITS ); - float3 N = STL::Packing::DecodeUnitVector( t.xy ); + float4 t; + t.xy = STL::Packing::EncodeUnitVector( N ); + t.z = specAccumSpeed / REBLUR_MAX_ACCUM_FRAME_NUM; + t.w = materialID; + + uint p = STL::Packing::RgbaToUint( t, REBLUR_NORMAL_ACCUMSPEED_MATERIALID_BITS ); - return float4( p ? N : 0, t.z ); + return p; } -float4 UnpackRoughness( uint4 p ) +float3 UnpackPrevNormalAccumSpeedMaterialID( uint p, out float accumSpeed, out float materialID ) { - p >>= 9 + 9; - p &= 0xFF; + float4 t = STL::Packing::UintToRgba( p, REBLUR_NORMAL_ACCUMSPEED_MATERIALID_BITS ); + float3 N = STL::Packing::DecodeUnitVector( t.xy ); + + accumSpeed = t.z * REBLUR_MAX_ACCUM_FRAME_NUM; + materialID = t.w; - return float4( p ) / float( 0xFF ); + return p ? N : 0; } -float4 UnpackNormalRoughnessSpecAccumSpeed( uint p, out float accumSpeed ) +float3 UnpackPrevNormal( uint p ) { - float4 t = STL::Packing::UintToRgba( p, REBLUR_NORMAL_ROUGHNESS_ACCUMSPEED_BITS ); - float3 N = STL::Packing::DecodeUnitVector( t.xy ); - - accumSpeed = t.w * REBLUR_MAX_ACCUM_FRAME_NUM; + float unused1; + uint unused2; - return float4( N, t.z ); + return UnpackPrevNormalAccumSpeedMaterialID( p, unused1, unused2 ); } // Internal data @@ -99,8 +98,6 @@ float EstimateCurvature( float3 Ni, float3 Vi, float3 N, float3 X ) float3 edge = Xi - X; float curvature = dot( Ni - N, edge ) * rsqrt( STL::Math::LengthSquared( edge ) ); - // TODO: potentially imprecision mitigation is needed here... - return curvature; } @@ -110,8 +107,8 @@ float4 PackDiffSpecInternalData( float diffAccumSpeed, float specAccumSpeed, flo // 0-2 - specular mip level // 3 - surface occlusion // 4 - virtual occlusion - // 5 - curvatrue sign - // 6-7 - free + // 5 - curvature sign + // 6-7 - (free) fbits += 32.0 * ( curvature < 0.0 ? 1 : 0 ); @@ -155,16 +152,6 @@ float4 UnpackDiffSpecInternalData( float4 p ) // Accumulation speed -float GetSpecMagicCurve( float roughness, float power = 0.25 ) // TODO: REBLUR_SPEC_ACCUM_BASE_POWER? -{ - // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtMl4oLTE1LjAqeCkiLCJjb2xvciI6IiNGMjE4MTgifSx7InR5cGUiOjAsImVxIjoiKDEtMl4oLTIwMCp4KngpKSooeF4wLjI1KSIsImNvbG9yIjoiIzIyRUQxNyJ9LHsidHlwZSI6MCwiZXEiOiIoMS0yXigtMjAwKngqeCkpKih4XjAuNSkiLCJjb2xvciI6IiMxNzE2MTYifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMSIsIjAiLCIxLjEiXSwic2l6ZSI6WzEwMDAsNTAwXX1d - - float f = 1.0 - exp2( -200.0 * roughness * roughness ); - f *= STL::Math::Pow01( roughness, power ); - - return f; -} - float GetSpecAccumulatedFrameNum( float roughness, float powerScale ) { // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiI2MyooeF4wLjUpIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjowLCJlcSI6IjYzKigxLTJeKC0yMDAqeCp4KSkqKHheMC41KSIsImNvbG9yIjoiIzIyRkYwMCJ9LHsidHlwZSI6MCwiZXEiOiI2MyooMS0yXigtMjAwKngqeCkpKih4XjAuNjYpIiwiY29sb3IiOiIjRkMwMzAzIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMCIsIjEiLCIwIiwiNjMiXX1d @@ -204,38 +191,42 @@ float GetSpecAccumSpeed( float maxAccumSpeed, float roughness, float NoV, float // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oeCwxKSIsImNvbG9yIjoiI0YyMDkwOSJ9LHsidHlwZSI6MCwiZXEiOiIxLTJeKC0zLjUqeCp4KSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIjAiLCIyIiwiMCIsIjEuMSJdfV0- #define SaturateParallax( parallax ) saturate( 1.0 - exp2( -3.5 * ( parallax ) * ( parallax ) ) ) -float GetDisocclusionThreshold( float disocclusionThreshold, float jitterDeltaInPixels, float viewZ, float3 Nflat, float3 V ) +float GetDisocclusionThreshold( float disocclusionThreshold, float viewZ, float3 Nflat, float3 V ) { - float jitterDelta = PixelRadiusToWorld( gUnproject, gIsOrtho, jitterDeltaInPixels, viewZ ); + float jitterDelta = PixelRadiusToWorld( gUnproject, gOrthoMode, gJitterDelta, viewZ ); float NoV = abs( dot( Nflat, V ) ); - disocclusionThreshold += jitterDelta / ( max( NoV, 0.05 ) * viewZ ); + disocclusionThreshold += jitterDelta / ( max( NoV, 0.05 ) * viewZ + 1e-6 ); return disocclusionThreshold; } float3 GetViewVector( float3 X, bool isViewSpace = false ) { - return gIsOrtho == 0.0 ? normalize( -X ) : ( isViewSpace ? float3( 0, 0, -1 ) : gViewVectorWorld.xyz ); + return gOrthoMode == 0.0 ? normalize( -X ) : ( isViewSpace ? float3( 0, 0, -1 ) : gViewVectorWorld.xyz ); } -float ComputeParallax( float3 X, float3 Xprev, float4 cameraDelta ) +float GetRealCurvature( float curvature, float pixelSize, float NoV ) { - float3 Xt = Xprev - cameraDelta.xyz; - float p = dot( X, Xt ); - float parallax = sqrt( max( dot( X, X ) * dot( Xt, Xt ) - p * p, 0.0 ) ) / p; + // edgeLength = pixelSize / NoV + // real curvature = curvature / edgeLength - // Special case for ortho projection, where translation doesn't introduce parallax - parallax = gIsOrtho != 0 ? cameraDelta.w : parallax; // TODO: do it better! + return curvature * NoV / pixelSize; +} + +float ApplyThinLensEquation( float hitDist, float realCurvature ) +{ + float denom = 0.5 + realCurvature * hitDist; + denom = abs( denom ) < 1e-6 ? 0.5 : denom; // fixing imprecision problems + float hitDistFocused = 0.5 * hitDist / denom; - return parallax * REBLUR_PARALLAX_NORMALIZATION; + return hitDistFocused; } -float4 GetXvirtual( float3 X, float3 V, float NoV, float roughness, float hitDist, float viewZ, float c ) +float3 GetXvirtual( float3 X, float3 Xprev, float3 V, float NoV, float roughness, float hitDist, float realCurvature ) { /* The lens equation: - - c - local curvature - - C - curvature = c / edgeLength + - C - real curvature - O - object height - I - image height - F - focal distance @@ -259,28 +250,17 @@ float4 GetXvirtual( float3 X, float3 V, float NoV, float roughness, float hitDis Reverse sign because I is negative: I = 0.5 * O / ( 0.5 + C * O ) - - Real curvature from local curvature: - edgeLength = pixelSize / NoV - C = c * NoV / pixelSize */ - // TODO: better use "edge" from EstimateCurvature? - float pixelSize = PixelRadiusToWorld( gUnproject, gIsOrtho, 1.0, viewZ ); - c *= NoV / pixelSize; - - float denom = 0.5 + c * hitDist; - denom = abs( denom ) < 1e-6 ? 0.5 : denom; // fixing imprecision problems - float hitDistFocused = 0.5 * hitDist / denom; + float hitDistFocused = ApplyThinLensEquation( hitDist, realCurvature ); // "saturate" is needed to clamp values > 1 if curvature is negative float compressionRatio = saturate( ( abs( hitDistFocused ) + 1e-6 ) / ( hitDist + 1e-6 ) ); - // TODO: more complicated method is needed, because if elongation is very small X should become Xprev (signal starts to follow with surface motion) float f = STL::ImportanceSampling::GetSpecularDominantFactor( NoV, roughness, REBLUR_SPEC_DOMINANT_DIRECTION ); - float3 Xvirtual = X - V * hitDistFocused * f; + float3 Xvirtual = lerp( Xprev, X, compressionRatio * f ) - V * hitDistFocused * f; - return float4( Xvirtual, compressionRatio ); + return Xvirtual; } float GetMax( float3 c ) @@ -288,22 +268,6 @@ float GetMax( float3 c ) return max( c.x, max( c.y, c.z ) ); } -float GetColorErrorForAdaptiveRadiusScale( float4 curr, float4 prev, float nonLinearAccumSpeed, float roughness, float scale ) -{ - float2 p = float2( GetMax( prev.xyz ), prev.w ); - float2 c = float2( GetMax( curr.xyz ), curr.w ); - float2 f = abs( c - p ) / ( max( c, p ) + 0.001 ); - float s = 3.0 - scale; - - float error = max( f.x, f.y ); // TODO: store this value and normalize before use? can be helpful for normal weight - error = STL::Math::SmoothStep( 0.0, gResidualNoiseLevel * s, error ); - error *= STL::Math::Pow01( roughness, 0.33333 ); - error *= float( nonLinearAccumSpeed != 1.0 ); - error *= 1.0 - gReference; - - return error; -} - float4 MixSurfaceAndVirtualMotion( float4 s, float4 v, float virtualHistoryAmount, float hitDistToSurfaceRatio ) { float2 f; @@ -335,65 +299,96 @@ float InterpolateAccumSpeeds( float a, float b, float f ) return 1.0 / f - 1.0; } +float GetSensitivityToDarkness( float roughness ) +{ + // TODO: if roughness is close to 0, hitDist can be very divergent, antilag potentially can break accumulation + // on bumpy surfaces, "sensitivityToDarknessScale" can be increased in this case based on curvature + + // Artificially increase sensitivity to darkness for low roughness, because specular can be very hot + float sensitivityToDarknessScale = lerp( 3.0, 1.0, roughness ); + + return sensitivityToDarknessScale; +} + +float GetColorErrorForAdaptiveRadiusScale( float4 curr, float4 prev, float nonLinearAccumSpeed, float roughness, float scale ) +{ + float2 p = float2( GetMax( prev.xyz ), prev.w ); + float2 c = float2( GetMax( curr.xyz ), curr.w ); + float2 f = abs( c - p ) / ( max( c, p ) + gSensitivityToDarkness * GetSensitivityToDarkness( roughness ) + 0.001 ); + float s = 3.0 - scale; + + float error = max( f.x, f.y ); // TODO: store this value and normalize before use? can be helpful for normal weight + error = STL::Math::SmoothStep( 0.0, saturate( gResidualNoiseLevel * s ), error ); + error *= STL::Math::Pow01( lerp( 0.05, 1.0, roughness ), 0.33333 ); + error *= float( nonLinearAccumSpeed != 1.0 ); + error *= 1.0 - gReference; + + return error; +} + float ComputeAntilagScale ( inout float accumSpeed, float4 history, float4 signal, float4 m1, float4 sigma, - float4 antilag1, // .xy - sigma scale, .zw - sensitivity to darkness - float4 antilag2, // .xy - min threshold, .zw - max threshold + float4 antilagMinMaxThreshold, float2 antilagSigmaScale, float curvature, float roughness = 1.0 ) { - // TODO: if roughness is close to 0, hit dists can be very divergent, antilag potentially can break accumulation - // on bumpy surfaces, "sensitivityToDarknessScale" can be increased in this case based on curvature - - // Artificially increase sensitivity to darkness for low roughness, because specular can be very hot - float2 sensitivityToDarknessScale = lerp( 3.0, 1.0, roughness ); - // On-edge strictness m1 = lerp( m1, signal, abs( curvature ) ); // Antilag float2 h = float2( GetMax( history.xyz ), history.w ); - float2 m = float2( GetMax( m1.xyz ), m1.w ); - - float2 ma = float2( GetMax( m1.xyz - sigma.xyz ), m1.w - sigma.w ); - float2 mb = float2( GetMax( m1.xyz + sigma.xyz ), m1.w + sigma.w ); - float2 s = 0.5 * ( mb - ma ); + float2 c = float2( GetMax( m1.xyz ), m1.w ); // TODO: use signal, average antilag before use + float2 s = float2( GetMax( sigma.xyz ), sigma.w ); - float2 delta = abs( h - m ) - s * antilag1.xy; - delta /= max( m, h ) + antilag1.zw * sensitivityToDarknessScale + 1e-6; - delta = STL::Math::SmoothStep( antilag2.zw, antilag2.xy, delta ); + float2 delta = abs( h - c ) - s * antilagSigmaScale; + delta /= max( h, c ) + gSensitivityToDarkness * GetSensitivityToDarkness( roughness ) + 0.001; + delta = STL::Math::SmoothStep( antilagMinMaxThreshold.zw, antilagMinMaxThreshold.xy, delta ); float antilag = min( delta.x, delta.y ); - antilag = lerp( antilag, 1.0, 1.0 / ( 1.0 + accumSpeed ) ); // TODO: needed to avoid artefacts due to bad interaction of history, fast history and antilag + antilag = lerp( antilag, 1.0, 1.0 / ( 1.0 + accumSpeed ) ); // TODO: needed? + + #if( REBLUR_DEBUG != 0 ) + antilag = 1.0; + #endif return antilag; } // Kernel -float GetBlurRadius( float radius, float hitDist, float viewZ, float nonLinearAccumSpeed, float radiusBias, float radiusScale, float roughness = 1.0 ) +float GetResponsiveAccumulationAmount( float roughness ) +{ + float amount = 1.0 - ( roughness + 1e-6 ) / ( gResponsiveAccumulationRoughnessThreshold + 1e-6 ); + + return STL::Math::SmoothStep01( amount ); +} + +float GetBlurRadius( float radius, float hitDist, float frustumHeight, float nonLinearAccumSpeed, float radiusBias, float radiusScale, float roughness = 1.0 ) { // Scale down if accumulation goes well, keeping some non-zero scale to avoid under-blurring - float r = lerp( REBLUR_MIN_RADIUS_SCALE_AT_CONVERGED_STATE, 1.0, nonLinearAccumSpeed ); + float r = lerp( gMinConvergedStateBaseRadiusScale, 1.0, nonLinearAccumSpeed ); // Modify by hit distance - float frustumHeight = PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ); float hitDistFactor = hitDist / ( hitDist + frustumHeight ); r *= hitDistFactor; // Avoid over-blurring on contact - radiusBias *= lerp( roughness * roughness, 1.0, hitDistFactor ); + radiusBias *= hitDistFactor; // TODO: previously was: lerp( roughness * roughness, 1.0, hitDistFactor ) - // Final + // Main composition float pixelRadiusNorm = frustumHeight / ( 1.0 + frustumHeight ); // TODO: replace voodoo magic with physically based math pixelRadiusNorm = lerp( 1.0, pixelRadiusNorm, roughness * roughness ); r = radius * r * ( radiusScale + radiusBias * pixelRadiusNorm ) + max( radiusBias, 2.0 * roughness ) * radiusScale; - // Post final scales - r *= GetSpecMagicCurve( roughness ); + // Modify by roughness, allowing small blur even for 0 roughness if accumulation doesn't go well + float boost = lerp( 0.07, 0.0, GetResponsiveAccumulationAmount( roughness ) ); + float bumpedRoughness = lerp( roughness, 1.0, boost * nonLinearAccumSpeed ); + r *= GetSpecMagicCurve( bumpedRoughness ); + + // Disable spatial filtering in reference mode r *= 1.0 - gReference; return r; @@ -441,29 +436,42 @@ float2x3 GetKernelBasis( float3 V, float3 N, float worldRadius, float roughness return float2x3( T, B ); } -// Weight parameters +// Encoding precision aware weight functions ( for reprojection ) -float GetNormalWeightParams( float nonLinearAccumSpeed, float viewZ, float roughness = 1.0, float strictness = 1.0 ) +float GetEncodingAwareRoughnessWeight( float roughnessCurr, float roughnessPrev, float fraction ) { - // Estimate how many samples from a potentially bumpy normal map fit in the pixel - float frustumHeight = PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ); - float pixelRadiusNorm = frustumHeight / ( 1.0 + frustumHeight ); // TODO: replace voodoo magic with physically based math + float a = 1.0 / lerp( 0.01, 1.0, roughnessCurr * saturate( fraction ) ); + float d = abs( roughnessPrev - roughnessCurr ); - float s = lerp( 0.03, 0.16, pixelRadiusNorm ); - s = lerp( s, 1.0, nonLinearAccumSpeed ); - s = saturate( s * strictness ); + return STL::Math::SmoothStep01( 1.0 - ( d - REBLUR_ROUGHNESS_ULP ) * a ); +} + +float GetEncodingAwareNormalWeight( float3 Ncurr, float3 Nprev, float maxAngle ) +{ + float a = 1.0 / maxAngle; + float cosa = saturate( dot( Ncurr, Nprev ) ); + float d = STL::Math::AcosApprox( cosa ); + + return STL::Math::SmoothStep01( 1.0 - ( d - REBLUR_NORMAL_ULP ) * a ); +} - float params = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughness ); - params *= s; - params = 1.0 / max( params, NRD_ENCODING_ERRORS.x ); +// Weight parameters + +float GetNormalWeightParams( float nonLinearAccumSpeed, float frustumHeight, float fraction, float roughness = 1.0 ) +{ + // TODO: "pixelRadiusNorm" can be used to estimate how many samples from a potentially bumpy normal map fit into + // a pixel, i.e. to increase "fraction" a bit if "pixelRadiusNorm" is close to 1. It was used before. Now it's a + // backup plan. See "GetBlurRadius". - return params; + float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughness ); + angle *= lerp( saturate( fraction ), 1.0, nonLinearAccumSpeed ); // TODO: use as "percentOfVolume" instead? + + return 1.0 / max( angle, NRD_ENCODING_ERRORS.x ); } -float2 GetRoughnessWeightParams( float roughness, float percentOfRoughness = 0.03 ) +float2 GetRoughnessWeightParams( float roughness, float fraction ) { - // IMPORTANT: too small values of "percentOfRoughness" can ruin contact shadowing even if neighboring roughness is absolutely same due to re-packing imprecision problems. - float a = 1.0 / ( roughness * percentOfRoughness * 0.99 + 0.01 ); + float a = 1.0 / lerp( 0.01, 1.0, roughness * fraction ); float b = roughness * a; return float2( a, -b ); @@ -511,7 +519,7 @@ float GetNormalWeight( float param, float3 N, float3 n ) float cosa = saturate( dot( N, n ) ); float angle = STL::Math::AcosApprox( cosa ); - return _ComputeWeight( float2( param, -0.001 ), angle ); + return _ComputeWeight( float2( param, 0.0 ), angle ); } float4 GetNormalWeight4( float param, float3 N, float3 n00, float3 n10, float3 n01, float3 n11 ) @@ -524,12 +532,9 @@ float4 GetNormalWeight4( float param, float3 N, float3 n00, float3 n10, float3 n float4 angle = STL::Math::AcosApprox( saturate( cosa ) ); - return _ComputeWeight( float2( param, -0.001 ), angle ); + return _ComputeWeight( float2( param, 0.0 ), angle ); } -#define GetRoughnessWeight( p, value ) _ComputeWeight( p, value ) -#define GetHitDistanceWeight( p, value ) _ComputeWeight( p, value ) - float2 GetCombinedWeight ( float baseWeight, @@ -540,7 +545,7 @@ float2 GetCombinedWeight ) { float4 a = float4( geometryWeightParams.x, normalWeightParams, hitDistanceWeightParams.x, roughnessWeightParams.x ); - float4 b = float4( geometryWeightParams.y, -0.001, hitDistanceWeightParams.y, roughnessWeightParams.y ); + float4 b = float4( geometryWeightParams.y, 0.0, hitDistanceWeightParams.y, roughnessWeightParams.y ); float4 t; t.x = dot( Nv, Xvs ); diff --git a/Source/Shaders/Include/REBLUR_Common_DiffuseOcclusionSpatialFilter.hlsli b/Source/Shaders/Include/REBLUR_Common_DiffuseOcclusionSpatialFilter.hlsli index 6d99822..6074c56 100644 --- a/Source/Shaders/Include/REBLUR_Common_DiffuseOcclusionSpatialFilter.hlsli +++ b/Source/Shaders/Include/REBLUR_Common_DiffuseOcclusionSpatialFilter.hlsli @@ -18,37 +18,37 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. { float center = diff; - float radius = gDiffBlurRadius; + float radius = gBlurRadius; float minAccumSpeed = GetMipLevel( 1.0 ) + 0.001; float boost = saturate( 1.0 - diffInternalData.y / minAccumSpeed ); - radius *= ( 1.0 + 2.0 * boost ) / 3.0; + radius *= ( 1.0 + 5.0 * boost ) / 3.0; float radiusScale = 1.0; - float radiusBias = 0.0; // see GetBlurRadius() - float strictness = 1.0; + float radiusBias = 0.0; + float fractionScale = 1.0; #if( REBLUR_SPATIAL_MODE == REBLUR_POST_BLUR ) radiusScale = REBLUR_POST_BLUR_RADIUS_SCALE; - radiusBias = error.x * gDiffBlurRadiusScale + 0.00001; - strictness = REBLUR_POST_BLUR_STRICTNESS; + radiusBias = error.x * gBlurRadiusScale + 0.00001; + fractionScale = REBLUR_POST_BLUR_FRACTION_SCALE; #elif( REBLUR_SPATIAL_MODE == REBLUR_BLUR ) - radiusBias = error.x * gDiffBlurRadiusScale + 0.00001; - strictness = REBLUR_BLUR_NORMAL_WEIGHT_RELAXATION; + radiusBias = error.x * gBlurRadiusScale + 0.00001; + fractionScale = REBLUR_BLUR_FRACTION_SCALE; #endif // Blur radius - float hitDist = REBLUR_GetHitDist( center, viewZ, gDiffHitDistParams, 1.0 ); - float blurRadius = GetBlurRadius( radius, hitDist, viewZ, diffInternalData.x, radiusBias, radiusScale ); - float worldBlurRadius = PixelRadiusToWorld( gUnproject, gIsOrtho, blurRadius, viewZ ); + float frustumHeight = PixelRadiusToWorld( gUnproject, gOrthoMode, gRectSize.y, viewZ ); + float hitDist = REBLUR_GetHitDist( center, viewZ, gHitDistParams, 1.0 ); + float blurRadius = GetBlurRadius( radius, hitDist, frustumHeight, diffInternalData.x, radiusBias, radiusScale ); + float worldBlurRadius = PixelRadiusToWorld( gUnproject, gOrthoMode, blurRadius, viewZ ); // Denoising - float frustumHeight = PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ); float hitDistFactor = hitDist / ( hitDist + frustumHeight ); float3 Vv = GetViewVector( Xv, true ); float2x3 TvBv = GetKernelBasis( Vv, Nv, worldBlurRadius ); float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumHeight, Xv, Nv, lerp( 1.0, REBLUR_PLANE_DIST_MIN_SENSITIVITY_SCALE, diffInternalData.x ) ); - float normalWeightParams = GetNormalWeightParams( diffInternalData.x, viewZ, 1.0, gNormalWeightStrictness * strictness ); + float normalWeightParams = GetNormalWeightParams( diffInternalData.x, frustumHeight, gLobeAngleFraction * fractionScale ); float2 hitDistanceWeightParams = GetHitDistanceWeightParams( center, diffInternalData.x ); float sum = 1.0; @@ -77,9 +77,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. float2 s = gIn_Diff.SampleLevel( gNearestMirror, uvScaled, 0 ); float zs = s.y / NRD_FP16_VIEWZ_SCALE; - float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, zs, gIsOrtho ); + float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, zs, gOrthoMode ); - uint materialIDs; + float materialIDs; Ns = NRD_FrontEnd_UnpackNormalAndRoughness( Ns, materialIDs ); // Sample weight @@ -106,7 +106,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. error.x = GetColorErrorForAdaptiveRadiusScale( diff, center, diffInternalData.x, 1.0, REBLUR_SPATIAL_MODE ); // Input mix - diff = lerp( diff, center, REBLUR_INPUT_MIX.y ); + diff = lerp( diff, center, gInputMix * ( 1.0 - diffInternalData.x ) ); // Output #if( REBLUR_SPATIAL_MODE == REBLUR_BLUR ) diff --git a/Source/Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli b/Source/Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli index e11af04..b82f2a7 100644 --- a/Source/Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli +++ b/Source/Shaders/Include/REBLUR_Common_DiffuseSpatialFilter.hlsli @@ -28,42 +28,42 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. diff.xyz = STL::Color::Compress( diff.xyz, exposure ); #endif - float radius = gDiffBlurRadius; + float radius = gBlurRadius; #if( REBLUR_SPATIAL_MODE == REBLUR_PRE_BLUR ) float2 diffInternalData = REBLUR_PRE_BLUR_INTERNAL_DATA; radius *= REBLUR_PRE_BLUR_RADIUS_SCALE( 1.0 ); #else float minAccumSpeed = GetMipLevel( 1.0 ) + 0.001; float boost = saturate( 1.0 - diffInternalData.y / minAccumSpeed ); - radius *= ( 1.0 + 2.0 * boost ) / 3.0; + radius *= ( 1.0 + 5.0 * boost ) / 3.0; #endif float radiusScale = 1.0; - float radiusBias = 0.0; // see GetBlurRadius() - float strictness = 1.0; + float radiusBias = 0.0; + float fractionScale = 1.0; #if( REBLUR_SPATIAL_MODE == REBLUR_POST_BLUR ) radiusScale = REBLUR_POST_BLUR_RADIUS_SCALE; - radiusBias = error.x * gDiffBlurRadiusScale + 0.00001; - strictness = REBLUR_POST_BLUR_STRICTNESS; + radiusBias = error.x * gBlurRadiusScale + 0.00001; + fractionScale = REBLUR_POST_BLUR_FRACTION_SCALE; #elif( REBLUR_SPATIAL_MODE == REBLUR_BLUR ) - radiusBias = error.x * gDiffBlurRadiusScale + 0.00001; - strictness = REBLUR_BLUR_NORMAL_WEIGHT_RELAXATION; + radiusBias = error.x * gBlurRadiusScale + 0.00001; + fractionScale = REBLUR_BLUR_FRACTION_SCALE; #endif // Blur radius - float hitDist = REBLUR_GetHitDist( center.w, viewZ, gDiffHitDistParams, 1.0 ); - float blurRadius = GetBlurRadius( radius, hitDist, viewZ, diffInternalData.x, radiusBias, radiusScale ); - float worldBlurRadius = PixelRadiusToWorld( gUnproject, gIsOrtho, blurRadius, viewZ ); + float frustumHeight = PixelRadiusToWorld( gUnproject, gOrthoMode, gRectSize.y, viewZ ); + float hitDist = REBLUR_GetHitDist( center.w, viewZ, gHitDistParams, 1.0 ); + float blurRadius = GetBlurRadius( radius, hitDist, frustumHeight, diffInternalData.x, radiusBias, radiusScale ); + float worldBlurRadius = PixelRadiusToWorld( gUnproject, gOrthoMode, blurRadius, viewZ ); // Denoising - float frustumHeight = PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ); float hitDistFactor = hitDist / ( hitDist + frustumHeight ); float3 Vv = GetViewVector( Xv, true ); float2x3 TvBv = GetKernelBasis( Vv, Nv, worldBlurRadius ); float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumHeight, Xv, Nv, lerp( 1.0, REBLUR_PLANE_DIST_MIN_SENSITIVITY_SCALE, diffInternalData.x ) ); - float normalWeightParams = GetNormalWeightParams( diffInternalData.x, viewZ, 1.0, gNormalWeightStrictness * strictness ); + float normalWeightParams = GetNormalWeightParams( diffInternalData.x, frustumHeight, gLobeAngleFraction * fractionScale ); float2 hitDistanceWeightParams = GetHitDistanceWeightParams( center.w, diffInternalData.x ); float2 sum = 1.0; @@ -71,7 +71,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. blurRadius *= REBLUR_PRE_BLUR_SPATIAL_REUSE_BASE_RADIUS_SCALE; float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( 1.0 ); - float normalWeightParamsReuse = rcp( max( angle, NRD_ENCODING_ERRORS.x ) ); + float normalWeightParamsReuse = 1.0 / max( angle, NRD_ENCODING_ERRORS.x ); uint2 p = pixelPos; if( gDiffCheckerboard != 2 ) @@ -128,9 +128,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. float zs = gIn_ScaledViewZ.SampleLevel( gNearestMirror, uvScaled, 0 ) / NRD_FP16_VIEWZ_SCALE; #endif - float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, zs, gIsOrtho ); + float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, zs, gOrthoMode ); - uint materialIDs; + float materialIDs; Ns = NRD_FrontEnd_UnpackNormalAndRoughness( Ns, materialIDs ); // Sample weight @@ -184,7 +184,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. error.x = GetColorErrorForAdaptiveRadiusScale( diff, center, diffInternalData.x, 1.0, REBLUR_SPATIAL_MODE ); // Input mix - diff = lerp( diff, center, REBLUR_INPUT_MIX.xxxy ); + diff = lerp( diff, center, gInputMix * ( 1.0 - diffInternalData.x ) ); // Output gOut_Diff[ pixelPos ] = diff; diff --git a/Source/Shaders/Include/REBLUR_Common_SpecularOcclusionSpatialFilter.hlsli b/Source/Shaders/Include/REBLUR_Common_SpecularOcclusionSpatialFilter.hlsli index 2a3f4bb..1431b96 100644 --- a/Source/Shaders/Include/REBLUR_Common_SpecularOcclusionSpatialFilter.hlsli +++ b/Source/Shaders/Include/REBLUR_Common_SpecularOcclusionSpatialFilter.hlsli @@ -18,41 +18,43 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. { float center = spec; - float radius = gSpecBlurRadius; + float radius = gBlurRadius; float minAccumSpeed = GetMipLevel( roughness ) + 0.001; float boost = saturate( 1.0 - specInternalData.y / minAccumSpeed ); - radius *= ( 1.0 + 2.0 * boost ) / 3.0; - radius *= GetBlurRadiusScaleBasingOnTrimming( roughness, gSpecTrimmingParams.xyz ); + radius *= ( 1.0 + 5.0 * roughness * boost ) / 3.0; + radius *= GetBlurRadiusScaleBasingOnTrimming( roughness, gSpecLobeTrimmingParams.xyz ); float radiusScale = 1.0; - float radiusBias = 0.0; // see GetBlurRadius() - float strictness = 1.0; + float radiusBias = 0.0; + float fractionScale = 1.0; #if( REBLUR_SPATIAL_MODE == REBLUR_POST_BLUR ) radiusScale = REBLUR_POST_BLUR_RADIUS_SCALE; - radiusBias = lerp( REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ) * error.z * gSpecBlurRadiusScale + 0.00001; - strictness = REBLUR_POST_BLUR_STRICTNESS; + radiusBias = lerp( 1.0 / REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ) * error.z * gBlurRadiusScale + 0.00001; + radius *= lerp( REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ); + fractionScale = REBLUR_POST_BLUR_FRACTION_SCALE; #elif( REBLUR_SPATIAL_MODE == REBLUR_BLUR ) - radiusBias = lerp( REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ) * error.z * gSpecBlurRadiusScale + 0.00001; - strictness = REBLUR_BLUR_NORMAL_WEIGHT_RELAXATION; + radiusBias = lerp( 1.0 / REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ) * error.z * gBlurRadiusScale + 0.00001; + radius *= lerp( REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ); + fractionScale = REBLUR_BLUR_FRACTION_SCALE; #endif // Blur radius - float hitDist = REBLUR_GetHitDist( center, viewZ, gSpecHitDistParams, roughness ); - float blurRadius = GetBlurRadius( radius, hitDist, viewZ, specInternalData.x, radiusBias, radiusScale, roughness ); - float worldBlurRadius = PixelRadiusToWorld( gUnproject, gIsOrtho, blurRadius, viewZ ); + float frustumHeight = PixelRadiusToWorld( gUnproject, gOrthoMode, gRectSize.y, viewZ ); + float hitDist = REBLUR_GetHitDist( center, viewZ, gHitDistParams, roughness ); + float blurRadius = GetBlurRadius( radius, hitDist, frustumHeight, specInternalData.x, radiusBias, radiusScale, roughness ); + float worldBlurRadius = PixelRadiusToWorld( gUnproject, gOrthoMode, blurRadius, viewZ ); // Denoising - float frustumHeight = PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ); float hitDistFactor = hitDist / ( hitDist + frustumHeight ); float anisoFade = lerp( abs( curvature ), 1.0, specInternalData.x ); float3 Vv = GetViewVector( Xv, true ); float2x3 TvBv = GetKernelBasis( Vv, Nv, worldBlurRadius, roughness, anisoFade ); float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumHeight, Xv, Nv, lerp( 1.0, REBLUR_PLANE_DIST_MIN_SENSITIVITY_SCALE, specInternalData.x ) ); - float normalWeightParams = GetNormalWeightParams( specInternalData.x, viewZ, roughness, gNormalWeightStrictness * strictness ); + float normalWeightParams = GetNormalWeightParams( specInternalData.x, frustumHeight, gLobeAngleFraction * fractionScale, roughness ); float2 hitDistanceWeightParams = GetHitDistanceWeightParams( center, specInternalData.x ); - float2 roughnessWeightParams = GetRoughnessWeightParams( roughness ); + float2 roughnessWeightParams = GetRoughnessWeightParams( roughness, gRoughnessFraction * fractionScale ); float sum = 1.0; #if( REBLUR_SPATIAL_MODE == REBLUR_BLUR ) @@ -82,9 +84,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. float2 s = gIn_Spec.SampleLevel( gNearestMirror, uvScaled, 0 ); float zs = s.y / NRD_FP16_VIEWZ_SCALE; - float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, zs, gIsOrtho ); + float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, zs, gOrthoMode ); - uint materialIDs; + float materialIDs; Ns = NRD_FrontEnd_UnpackNormalAndRoughness( Ns, materialIDs ); // Sample weight @@ -111,7 +113,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. error.z = GetColorErrorForAdaptiveRadiusScale( spec, center, specInternalData.x, roughness, REBLUR_SPATIAL_MODE ); // Input mix - spec = lerp( spec, center, REBLUR_INPUT_MIX.y ); + spec = lerp( spec, center, gInputMix * ( 1.0 - specInternalData.x ) ); // Output #if( REBLUR_SPATIAL_MODE == REBLUR_BLUR ) diff --git a/Source/Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli b/Source/Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli index bffaf9d..41a3c5e 100644 --- a/Source/Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli +++ b/Source/Shaders/Include/REBLUR_Common_SpecularSpatialFilter.hlsli @@ -26,53 +26,55 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. float exposure = _NRD_GetColorCompressionExposureForSpatialPasses( roughness ); spec.xyz = STL::Color::Compress( spec.xyz, exposure ); - float radius = gSpecBlurRadius; + float radius = gBlurRadius; #if( REBLUR_SPATIAL_MODE == REBLUR_PRE_BLUR ) float2 specInternalData = REBLUR_PRE_BLUR_INTERNAL_DATA; radius *= REBLUR_PRE_BLUR_RADIUS_SCALE( roughness ); #else float minAccumSpeed = GetMipLevel( roughness ) + 0.001; float boost = saturate( 1.0 - specInternalData.y / minAccumSpeed ); - radius *= ( 1.0 + 2.0 * boost ) / 3.0; + radius *= ( 1.0 + 5.0 * roughness * boost ) / 3.0; #endif - radius *= GetBlurRadiusScaleBasingOnTrimming( roughness, gSpecTrimmingParams.xyz ); + radius *= GetBlurRadiusScaleBasingOnTrimming( roughness, gSpecLobeTrimmingParams.xyz ); float radiusScale = 1.0; - float radiusBias = 0.0; // see GetBlurRadius() - float strictness = 1.0; + float radiusBias = 0.0; + float fractionScale = 1.0; #if( REBLUR_SPATIAL_MODE == REBLUR_POST_BLUR ) radiusScale = REBLUR_POST_BLUR_RADIUS_SCALE; - radiusBias = lerp( REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ) * error.z * gSpecBlurRadiusScale + 0.00001; - strictness = REBLUR_POST_BLUR_STRICTNESS; + radiusBias = lerp( 1.0 / REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ) * error.z * gBlurRadiusScale + 0.00001; + radius *= lerp( REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ); + fractionScale = REBLUR_POST_BLUR_FRACTION_SCALE; #elif( REBLUR_SPATIAL_MODE == REBLUR_BLUR ) - radiusBias = lerp( REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ) * error.z * gSpecBlurRadiusScale + 0.00001; - strictness = REBLUR_BLUR_NORMAL_WEIGHT_RELAXATION; + radiusBias = lerp( 1.0 / REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ) * error.z * gBlurRadiusScale + 0.00001; + radius *= lerp( REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE, 1.0, error.w ); + fractionScale = REBLUR_BLUR_FRACTION_SCALE; #endif // Blur radius - float hitDist = REBLUR_GetHitDist( center.w, viewZ, gSpecHitDistParams, roughness ); - float blurRadius = GetBlurRadius( radius, hitDist, viewZ, specInternalData.x, radiusBias, radiusScale, roughness ); - float worldBlurRadius = PixelRadiusToWorld( gUnproject, gIsOrtho, blurRadius, viewZ ); + float frustumHeight = PixelRadiusToWorld( gUnproject, gOrthoMode, gRectSize.y, viewZ ); + float hitDist = REBLUR_GetHitDist( center.w, viewZ, gHitDistParams, roughness ); + float blurRadius = GetBlurRadius( radius, hitDist, frustumHeight, specInternalData.x, radiusBias, radiusScale, roughness ); + float worldBlurRadius = PixelRadiusToWorld( gUnproject, gOrthoMode, blurRadius, viewZ ); // Denoising - float frustumHeight = PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ); float hitDistFactor = hitDist / ( hitDist + frustumHeight ); float anisoFade = lerp( abs( curvature ), 1.0, specInternalData.x ); float3 Vv = GetViewVector( Xv, true ); float2x3 TvBv = GetKernelBasis( Vv, Nv, worldBlurRadius, roughness, anisoFade ); float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumHeight, Xv, Nv, lerp( 1.0, REBLUR_PLANE_DIST_MIN_SENSITIVITY_SCALE, specInternalData.x ) ); - float normalWeightParams = GetNormalWeightParams( specInternalData.x, viewZ, roughness, gNormalWeightStrictness * strictness ); + float normalWeightParams = GetNormalWeightParams( specInternalData.x, frustumHeight, gLobeAngleFraction * fractionScale, roughness ); float2 hitDistanceWeightParams = GetHitDistanceWeightParams( center.w, specInternalData.x ); - float2 roughnessWeightParams = GetRoughnessWeightParams( roughness ); + float2 roughnessWeightParams = GetRoughnessWeightParams( roughness, gRoughnessFraction * fractionScale ); float2 sum = 1.0; #ifdef REBLUR_SPATIAL_REUSE blurRadius *= REBLUR_PRE_BLUR_SPATIAL_REUSE_BASE_RADIUS_SCALE; float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughness ); - float normalWeightParamsReuse = rcp( max( angle, NRD_ENCODING_ERRORS.x ) ); + float normalWeightParamsReuse = 1.0 / max( angle, NRD_ENCODING_ERRORS.x ); float3 V = STL::Geometry::RotateVectorInverse( gWorldToView, Vv ); float NoV = abs( dot( N, V ) ); @@ -139,9 +141,9 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. float zs = gIn_ScaledViewZ.SampleLevel( gNearestMirror, uvScaled, 0 ) / NRD_FP16_VIEWZ_SCALE; #endif - float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, zs, gIsOrtho ); + float3 Xvs = STL::Geometry::ReconstructViewPosition( uv, gFrustum, zs, gOrthoMode ); - uint materialIDs; + float materialIDs; Ns = NRD_FrontEnd_UnpackNormalAndRoughness( Ns, materialIDs ); // Sample weight @@ -197,7 +199,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. error.z = GetColorErrorForAdaptiveRadiusScale( spec, center, specInternalData.x, roughness, REBLUR_SPATIAL_MODE ); // Input mix - spec = lerp( spec, center, REBLUR_INPUT_MIX.xxxy ); + spec = lerp( spec, center, gInputMix * ( 1.0 - specInternalData.x ) ); // Output gOut_Spec[ pixelPos ] = spec; diff --git a/Source/Shaders/Include/REBLUR_Config.hlsli b/Source/Shaders/Include/REBLUR_Config.hlsli index f968504..cf4d81e 100644 --- a/Source/Shaders/Include/REBLUR_Config.hlsli +++ b/Source/Shaders/Include/REBLUR_Config.hlsli @@ -9,7 +9,6 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. */ #define REBLUR_DEBUG 0 // 0+ ( output can be in radiance, AO or SO ) -#define REBLUR_DEBUG_ERROR_NORMALIZATION 0.15 // normalized % ( 0.04 for hit distance, 0.10 for color ) #define REBLUR_DEBUG_SPATIAL_DENSITY_CHECK 0 // Switches ( default 1 ) @@ -19,9 +18,10 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS 1 #define REBLUR_USE_ANISOTROPIC_KERNEL 1 #define REBLUR_USE_ACCUM_SPEED_NONLINEAR_INTERPOLATION 1 +#define REBLUR_USE_HISTORY_FIX 1 +#define REBLUR_USE_5X5_HISTORY_CLAMPING 1 // Switches ( default 0 ) -#define REBLUR_LOW_SPEC 0 // x1.3 perf boost, but IQ is worse ( DIFFUSE_SPECULAR on RTX 3090 @ 1440p 2.13 vs 2.60 ms ) #define REBLUR_USE_COLOR_CLAMPING_AABB 0 #define REBLUR_USE_WIDER_KERNEL_IN_HISTORY_FIX 0 // 1 - 1.9.0 behavior, 0 - new ( is it better? ) #define REBLUR_USE_SPATIAL_REUSE_FOR_HIT_DIST 0 // spatial reuse is about multi-bounce nature of light. Corners become darker if reuse is ON @@ -29,18 +29,19 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_USE_SCREEN_SPACE_SAMPLING 0 #define REBLUR_USE_5X5_ANTI_FIREFLY 0 #define REBLUR_USE_ANTILAG_NOT_INVOKING_HISTORY_FIX 0 +#define REBLUR_USE_BILINEAR_FOR_VIRTUAL_NORMAL_WEIGHT 0 // Experimental kernels #ifndef __cplusplus // https://www.desmos.com/calculator/e5mttzlg6v static const float3 g_Special6[ 6 ] = { - float3( -0.50 * sqrt(3.0) , -0.50 , 1.0 ), - float3( 0.00 , 1.00 , 1.0 ), - float3( 0.50 * sqrt(3.0) , -0.50 , 1.0 ), - float3( 0.00 , -0.30 , 0.3 ), - float3( 0.15 * sqrt(3.0) , 0.15 , 0.3 ), - float3( -0.15 * sqrt(3.0) , 0.15 , 0.3 ), + float3( -0.50 * sqrt(3.0) , -0.50 , 1.0 ), + float3( 0.00 , 1.00 , 1.0 ), + float3( 0.50 * sqrt(3.0) , -0.50 , 1.0 ), + float3( 0.00 , -0.30 , 0.3 ), + float3( 0.15 * sqrt(3.0) , 0.15 , 0.3 ), + float3( -0.15 * sqrt(3.0) , 0.15 , 0.3 ), }; // https://www.desmos.com/calculator/abaqyvswem @@ -62,63 +63,47 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_POISSON_SAMPLES( i ) g_Poisson8[ i ] #define REBLUR_PRE_BLUR_POISSON_SAMPLE_NUM 8 #define REBLUR_PRE_BLUR_POISSON_SAMPLES( i ) g_Poisson8[ i ] + #define REBLUR_PRE_BLUR_ROTATOR_MODE NRD_FRAME #define REBLUR_PRE_BLUR_INTERNAL_DATA float2( 1.0 / ( 1.0 + 8.0 ), 8.0 ) -#define REBLUR_PRE_BLUR_RADIUS_SCALE( r ) ( 1.0 / REBLUR_MIN_RADIUS_SCALE_AT_CONVERGED_STATE ) +#define REBLUR_PRE_BLUR_RADIUS_SCALE( r ) ( 1.0 / ( gMinConvergedStateBaseRadiusScale + 0.05 ) ) // TODO: better cancel it more naturally #define REBLUR_PRE_BLUR_SPATIAL_REUSE_BASE_RADIUS_SCALE 0.5 + #define REBLUR_BLUR_ROTATOR_MODE NRD_FRAME -#define REBLUR_BLUR_NORMAL_WEIGHT_RELAXATION 2.0 +#define REBLUR_BLUR_FRACTION_SCALE 2.0 + #define REBLUR_POST_BLUR_ROTATOR_MODE NRD_FRAME #define REBLUR_POST_BLUR_RADIUS_SCALE 3.0 -#define REBLUR_POST_BLUR_STRICTNESS 0.5 -#define REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE 2.0 -#define REBLUR_MIN_RADIUS_SCALE_AT_CONVERGED_STATE 0.25 +#define REBLUR_POST_BLUR_FRACTION_SCALE 0.5 + +#define REBLUR_VIRTUAL_MOTION_NORMAL_WEIGHT_ITERATION_NUM 2 // if > 2 then "prev" normal test is included +#define REBLUR_RADIUS_BIAS_CONFIDENCE_BASED_SCALE 3.0 #define REBLUR_SPEC_ACCUM_BASE_POWER 0.5 // previously was 0.66 ( less agressive accumulation, but virtual reprojection works well on flat surfaces and fixes the issue ) #define REBLUR_SPEC_ACCUM_CURVE 0.5 // aggressiveness of history rejection depending on viewing angle ( 1 - low, 0.66 - medium, 0.5 - high ) #define REBLUR_SPEC_BASIS_ROUGHNESS_THRESHOLD 0.8 #define REBLUR_SPEC_DOMINANT_DIRECTION STL_SPECULAR_DOMINANT_DIRECTION_G2 -#define REBLUR_PARALLAX_NORMALIZATION 30.0 // was 60 in normal mode (too laggy) and 30 in reference and ortho modes #define REBLUR_PLANE_DIST_MIN_SENSITIVITY_SCALE 0.05 #define REBLUR_TS_SIGMA_AMPLITUDE ( 3.0 * gFramerateScale ) #define REBLUR_TS_ACCUM_TIME ( 30 * 0.5 ) // "gFramerateScale to FPS scale" * "seconds" -#define REBLUR_MIP_NUM 4.999 +#define REBLUR_MIP_NUM 3.999 #define REBLUR_HIT_DIST_MIN_WEIGHT 0.1 -#define REBLUR_HIT_DIST_MIN_ACCUM_SPEED( r ) lerp( 0.2, 0.1, STL::Math::Sqrt01( r ) ) #define REBLUR_HIT_DIST_ACCELERATION float2( 1.0, 0.5 ) // .y is used to accelerate hit distance accumulation -#define REBLUR_INPUT_MIX float2( 0, 0 ) // ( .x - radiance, .y - hit distance ) preserves sharpness ( 0 - take output, 1 - take input ), can affects antilag and hit distance tracking if variance is high #define REBLUR_MIN_PDF 0.01 -#if( REBLUR_LOW_SPEC == 1 ) - #undef REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA - #undef REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TA - #undef REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS - #undef REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS - #undef REBLUR_USE_SCREEN_SPACE_SAMPLING - #undef REBLUR_POISSON_SAMPLE_NUM - #undef REBLUR_POISSON_SAMPLES - #undef REBLUR_PRE_BLUR_POISSON_SAMPLE_NUM - #undef REBLUR_PRE_BLUR_POISSON_SAMPLES - #undef REBLUR_POST_BLUR_ROTATOR_MODE - - #define REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA 0 - #define REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TA 0 - #define REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS 0 - #define REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS 0 - #define REBLUR_USE_SCREEN_SPACE_SAMPLING 1 - - #define REBLUR_POISSON_SAMPLE_NUM 6 - #define REBLUR_POISSON_SAMPLES( i ) g_Special6[ i ] - #define REBLUR_PRE_BLUR_POISSON_SAMPLE_NUM 6 - #define REBLUR_PRE_BLUR_POISSON_SAMPLES( i ) g_Special6[ i ] - - #define REBLUR_POST_BLUR_ROTATOR_MODE NRD_FRAME -#endif +/* +IMPORTANT: +0 can be used to unblock accumulation of hitDist, but due to strict hitDist weight and effects of feedback loop +color banding (crunched colors) will appear. It can be solved in two ways: +- accelerating hitDist accumulation to preserve noise a bit +- adding some hitDist input to the output in spatial passes +*/ +#define REBLUR_HIT_DIST_MIN_ACCUM_SPEED( r ) lerp( 0.2, 0.1, STL::Math::Sqrt01( r ) ) // Shared data -#define REBLUR_DIFF_SHARED_CB_DATA \ +#define REBLUR_SHARED_CB_DATA \ NRD_CONSTANT( float4x4, gViewToClip ) \ NRD_CONSTANT( float4, gFrustum ) \ - NRD_CONSTANT( float4, gDiffHitDistParams ) \ + NRD_CONSTANT( float4, gHitDistParams ) \ NRD_CONSTANT( float4, gViewVectorWorld ) \ NRD_CONSTANT( float2, gInvScreenSize ) \ NRD_CONSTANT( float2, gScreenSize ) \ @@ -127,86 +112,77 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_CONSTANT( float2, gRectSizePrev ) \ NRD_CONSTANT( float2, gResolutionScale ) \ NRD_CONSTANT( float2, gRectOffset ) \ + NRD_CONSTANT( float2, gSensitivityToDarkness ) \ NRD_CONSTANT( uint2, gRectOrigin ) \ NRD_CONSTANT( float, gReference ) \ - NRD_CONSTANT( float, gIsOrtho ) \ + NRD_CONSTANT( float, gOrthoMode ) \ NRD_CONSTANT( float, gUnproject ) \ NRD_CONSTANT( float, gDebug ) \ - NRD_CONSTANT( float, gInf ) \ + NRD_CONSTANT( float, gDenoisingRange ) \ NRD_CONSTANT( float, gPlaneDistSensitivity ) \ NRD_CONSTANT( float, gFramerateScale ) \ - NRD_CONSTANT( float, gDiffBlurRadius ) \ - NRD_CONSTANT( float, gDiffMaxAccumulatedFrameNum ) \ + NRD_CONSTANT( float, gBlurRadius ) \ + NRD_CONSTANT( float, gMaxAccumulatedFrameNum ) \ NRD_CONSTANT( float, gResidualNoiseLevel ) \ NRD_CONSTANT( float, gJitterDelta ) \ - NRD_CONSTANT( float, gUnused1 ) \ - NRD_CONSTANT( uint, gWorldSpaceMotion ) \ - NRD_CONSTANT( uint, gFrameIndex ) \ - NRD_CONSTANT( uint, gResetHistory ) \ - NRD_CONSTANT( uint, gDiffMaterialMask ) - -#define REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gViewToClip ) \ - NRD_CONSTANT( float4, gFrustum ) \ - NRD_CONSTANT( float4, gSpecHitDistParams ) \ - NRD_CONSTANT( float4, gViewVectorWorld ) \ - NRD_CONSTANT( float2, gInvScreenSize ) \ - NRD_CONSTANT( float2, gScreenSize ) \ - NRD_CONSTANT( float2, gInvRectSize ) \ - NRD_CONSTANT( float2, gRectSize ) \ - NRD_CONSTANT( float2, gRectSizePrev ) \ - NRD_CONSTANT( float2, gResolutionScale ) \ - NRD_CONSTANT( float2, gRectOffset ) \ - NRD_CONSTANT( uint2, gRectOrigin ) \ - NRD_CONSTANT( float, gReference ) \ - NRD_CONSTANT( float, gIsOrtho ) \ - NRD_CONSTANT( float, gUnproject ) \ - NRD_CONSTANT( float, gDebug ) \ - NRD_CONSTANT( float, gInf ) \ - NRD_CONSTANT( float, gPlaneDistSensitivity ) \ - NRD_CONSTANT( float, gFramerateScale ) \ - NRD_CONSTANT( float, gResidualNoiseLevel ) \ - NRD_CONSTANT( float, gJitterDelta ) \ - NRD_CONSTANT( float, gSpecBlurRadius ) \ - NRD_CONSTANT( float, gSpecMaxAccumulatedFrameNum ) \ - NRD_CONSTANT( float, gUnused1 ) \ - NRD_CONSTANT( uint, gWorldSpaceMotion ) \ - NRD_CONSTANT( uint, gFrameIndex ) \ - NRD_CONSTANT( uint, gResetHistory ) \ - NRD_CONSTANT( uint, gSpecMaterialMask ) - -#define REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gViewToClip ) \ - NRD_CONSTANT( float4, gFrustum ) \ - NRD_CONSTANT( float4, gDiffHitDistParams ) \ - NRD_CONSTANT( float4, gSpecHitDistParams ) \ - NRD_CONSTANT( float4, gViewVectorWorld ) \ - NRD_CONSTANT( float2, gInvScreenSize ) \ - NRD_CONSTANT( float2, gScreenSize ) \ - NRD_CONSTANT( float2, gInvRectSize ) \ - NRD_CONSTANT( float2, gRectSize ) \ - NRD_CONSTANT( float2, gRectSizePrev ) \ - NRD_CONSTANT( float2, gResolutionScale ) \ - NRD_CONSTANT( float2, gRectOffset ) \ - NRD_CONSTANT( uint2, gRectOrigin ) \ - NRD_CONSTANT( float, gReference ) \ - NRD_CONSTANT( float, gIsOrtho ) \ - NRD_CONSTANT( float, gUnproject ) \ - NRD_CONSTANT( float, gDebug ) \ - NRD_CONSTANT( float, gInf ) \ - NRD_CONSTANT( float, gPlaneDistSensitivity ) \ - NRD_CONSTANT( float, gFramerateScale ) \ - NRD_CONSTANT( float, gResidualNoiseLevel ) \ - NRD_CONSTANT( float, gDiffMaxAccumulatedFrameNum ) \ - NRD_CONSTANT( float, gSpecMaxAccumulatedFrameNum ) \ - NRD_CONSTANT( float, gUnused1 ) \ - NRD_CONSTANT( uint, gWorldSpaceMotion ) \ + NRD_CONSTANT( float, gInputMix ) \ + NRD_CONSTANT( float, gMinConvergedStateBaseRadiusScale ) \ + NRD_CONSTANT( float, gLobeAngleFraction ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANT( float, gResponsiveAccumulationRoughnessThreshold ) \ + NRD_CONSTANT( uint, gIsWorldSpaceMotionEnabled ) \ NRD_CONSTANT( uint, gFrameIndex ) \ NRD_CONSTANT( uint, gResetHistory ) \ NRD_CONSTANT( uint, gDiffMaterialMask ) \ - NRD_CONSTANT( uint, gSpecMaterialMask ) + NRD_CONSTANT( uint, gSpecMaterialMask ) \ + NRD_CONSTANT( uint, gUnused2 ) #if( !defined REBLUR_DIFFUSE && !defined REBLUR_SPECULAR ) #define REBLUR_DIFFUSE #define REBLUR_SPECULAR #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 + #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 + + #undef REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS + #define REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS 0 + + #undef REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS + #define REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS 0 + + #undef REBLUR_USE_5X5_HISTORY_CLAMPING + #define REBLUR_USE_5X5_HISTORY_CLAMPING 0 + + #undef REBLUR_USE_SCREEN_SPACE_SAMPLING + #define REBLUR_USE_SCREEN_SPACE_SAMPLING 1 + + #undef REBLUR_USE_5X5_ANTI_FIREFLY + #define REBLUR_USE_5X5_ANTI_FIREFLY 0 + + #undef REBLUR_POISSON_SAMPLE_NUM + #define REBLUR_POISSON_SAMPLE_NUM 6 + + #undef REBLUR_POISSON_SAMPLES + #define REBLUR_POISSON_SAMPLES( i ) g_Special6[ i ] + + #undef REBLUR_PRE_BLUR_POISSON_SAMPLE_NUM + #define REBLUR_PRE_BLUR_POISSON_SAMPLE_NUM 6 + + #undef REBLUR_PRE_BLUR_POISSON_SAMPLES + #define REBLUR_PRE_BLUR_POISSON_SAMPLES( i ) g_Special6[ i ] + + #undef REBLUR_PRE_BLUR_ROTATOR_MODE + #define REBLUR_PRE_BLUR_ROTATOR_MODE NRD_FRAME + + #undef REBLUR_BLUR_ROTATOR_MODE + #define REBLUR_BLUR_ROTATOR_MODE NRD_FRAME + + #undef REBLUR_POST_BLUR_ROTATOR_MODE + #define REBLUR_POST_BLUR_ROTATOR_MODE NRD_FRAME +#endif diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_AntiFirefly.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli similarity index 96% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_AntiFirefly.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli index 1534cc8..c0604a6 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_AntiFirefly.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecular_AntiFirefly.resources.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -53,7 +53,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float viewZ = scaledViewZ / NRD_FP16_VIEWZ_SCALE; [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) return; // Anti-firefly ( not needed for hit distance ) diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_AntiFirefly.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.resources.hlsli similarity index 81% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_AntiFirefly.resources.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.resources.hlsli index 1a4ca4b..c45a706 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_AntiFirefly.resources.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.resources.hlsli @@ -11,6 +11,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "REBLUR_Config.hlsli" #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 1 ) \ @@ -21,11 +22,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANTS_END #elif( defined REBLUR_DIFFUSE ) + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 1 ) \ @@ -34,11 +32,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANTS_END #else + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 1 ) \ @@ -47,11 +42,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANTS_END #endif +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANTS_END + #define NRD_DECLARE_SAMPLERS \ NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_Blur.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli similarity index 90% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_Blur.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli index 5c353f2..71d0f6c 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_Blur.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecular_Blur.resources.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -31,11 +31,11 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float viewZ = gIn_ScaledViewZ[ pixelPos ] / NRD_FP16_VIEWZ_SCALE; [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) return; // Normal and roughness - uint materialID; + float materialID; float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ], materialID ); float3 N = normalAndRoughness.xyz; float3 Nv = STL::Geometry::RotateVector( gWorldToView, N ); @@ -48,25 +48,25 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 specInternalData = internalData.zw; // Shared data - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); float4 rotator = GetBlurKernelRotation( REBLUR_BLUR_ROTATOR_MODE, pixelPos, gRotator, gFrameIndex ); float4 error = gInOut_Error[ pixelPos ]; - // Spatial filtering + // Spatial filtering (spec first - seems to work faster) #define REBLUR_SPATIAL_MODE REBLUR_BLUR - #if( defined REBLUR_DIFFUSE ) - float4 diff = gIn_Diff[ pixelPos ]; - - #include "REBLUR_Common_DiffuseSpatialFilter.hlsli" - #endif - #if( defined REBLUR_SPECULAR ) float4 spec = gIn_Spec[ pixelPos ]; #include "REBLUR_Common_SpecularSpatialFilter.hlsli" #endif + #if( defined REBLUR_DIFFUSE ) + float4 diff = gIn_Diff[ pixelPos ]; + + #include "REBLUR_Common_DiffuseSpatialFilter.hlsli" + #endif + // Output gInOut_Error[ pixelPos ] = error; } diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.resources.hlsli new file mode 100644 index 0000000..41a978f --- /dev/null +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.resources.hlsli @@ -0,0 +1,63 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "REBLUR_Config.hlsli" + +#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 4 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) + +#elif( defined REBLUR_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ + +#else + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) + +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float4x4, gWorldToView ) \ + NRD_CONSTANT( float4, gRotator ) \ + NRD_CONSTANT( float3, gSpecLobeTrimmingParams ) \ + NRD_CONSTANT( float, gBlurRadiusScale ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_HistoryFix.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli similarity index 88% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_HistoryFix.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli index 71e49a3..6a23940 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_HistoryFix.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecular_HistoryFix.resources.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -67,7 +67,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float viewZ = scaledViewZ / NRD_FP16_VIEWZ_SCALE; [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange || REBLUR_USE_HISTORY_FIX == 0 ) return; // Internal data @@ -77,14 +77,14 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 diffInternalData = internalData.xy; float2 specInternalData = internalData.zw; - // History reconstruction + // History reconstruction // materialID support? migrate to 5x5 filter? #if( defined REBLUR_DIFFUSE ) - float diffMipLevel = GetMipLevel( 1.0 ) * gDiffHistoryFixStrength; + float diffMipLevel = GetMipLevel( 1.0 ) * gHistoryFixStrength; ReconstructHistory( scaledViewZ, diffInternalData.y, diffMipLevel, pixelPos, pixelUv, gOut_Diff, gIn_Diff, gIn_ScaledViewZ ); #endif #if( defined REBLUR_SPECULAR ) - float specMipLevel = float( bits & 7 ) * gSpecHistoryFixStrength; + float specMipLevel = float( bits & 7 ) * gHistoryFixStrength; ReconstructHistory( scaledViewZ, specInternalData.y, specMipLevel, pixelPos, pixelUv, gOut_Spec, gIn_Spec, gIn_ScaledViewZ ); #endif } diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_HistoryFix.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.resources.hlsli similarity index 79% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_HistoryFix.resources.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.resources.hlsli index 1022fa4..f2416ab 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_HistoryFix.resources.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.resources.hlsli @@ -11,6 +11,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "REBLUR_Config.hlsli" #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 1 ) \ @@ -25,13 +26,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) \ NRD_INPUT_TEXTURE( RWTexture2D, gOut_HistoryStabilized_Spec, u, 3 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDiffHistoryFixStrength ) \ - NRD_CONSTANT( float, gSpecHistoryFixStrength ) \ - NRD_CONSTANTS_END #elif( defined REBLUR_DIFFUSE ) + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 1 ) \ @@ -42,12 +38,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ NRD_INPUT_TEXTURE( RWTexture2D, gOut_HistoryStabilized_Diff, u, 1 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDiffHistoryFixStrength ) \ - NRD_CONSTANTS_END #else + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 1 ) \ @@ -58,12 +50,13 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) \ NRD_INPUT_TEXTURE( RWTexture2D, gOut_HistoryStabilized_Spec, u, 1 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float, gSpecHistoryFixStrength ) \ - NRD_CONSTANTS_END #endif +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float, gHistoryFixStrength ) \ + NRD_CONSTANTS_END + #define NRD_DECLARE_SAMPLERS \ NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_PostBlur.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli similarity index 93% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_PostBlur.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli index edceb16..2808861 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_PostBlur.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecular_PostBlur.resources.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -31,11 +31,11 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float viewZ = gIn_ScaledViewZ[ pixelPos ] / NRD_FP16_VIEWZ_SCALE; [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) return; // Normal and roughness - uint materialID; + float materialID; float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ], materialID ); float3 N = normalAndRoughness.xyz; float3 Nv = STL::Geometry::RotateVector( gWorldToView, N ); @@ -48,7 +48,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 specInternalData = internalData.zw; // Shared data - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); float4 rotator = GetBlurKernelRotation( REBLUR_POST_BLUR_ROTATOR_MODE, pixelPos, gRotator, gFrameIndex ); float4 error = gInOut_Error[ pixelPos ]; diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.resources.hlsli new file mode 100644 index 0000000..41a978f --- /dev/null +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.resources.hlsli @@ -0,0 +1,63 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "REBLUR_Config.hlsli" + +#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 4 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) + +#elif( defined REBLUR_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ + +#else + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) + +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float4x4, gWorldToView ) \ + NRD_CONSTANT( float4, gRotator ) \ + NRD_CONSTANT( float3, gSpecLobeTrimmingParams ) \ + NRD_CONSTANT( float, gBlurRadiusScale ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_PreBlur.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli similarity index 93% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_PreBlur.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli index b419bba..560bca2 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_PreBlur.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecular_PreBlur.resources.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -52,10 +52,10 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float viewZ = abs( gIn_ViewZ[ pixelPosUser ] ); [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) return; - // Center data + // Checkerboard resolve // TODO: materialID support? float viewZ0 = abs( gIn_ViewZ[ pixelPosUser + int2( -1, 0 ) ] ); float viewZ1 = abs( gIn_ViewZ[ pixelPosUser + int2( 1, 0 ) ] ); float2 w = GetBilateralWeight( float2( viewZ0, viewZ1 ), viewZ ); @@ -89,7 +89,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Spatial filtering [branch] - if( gSpatialFiltering == 0 ) + if( gSpatialFiltering == 0.0 ) { #if( defined REBLUR_DIFFUSE ) gOut_Diff[ pixelPos ] = diff; @@ -101,14 +101,14 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : } // Normal and roughness - uint materialID; + float materialID; float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ], materialID ); float3 N = normalAndRoughness.xyz; float3 Nv = STL::Geometry::RotateVector( gWorldToView, N ); float roughness = normalAndRoughness.w; // Shared data - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); float4 rotator = GetBlurKernelRotation( REBLUR_PRE_BLUR_ROTATOR_MODE, pixelPos, gRotator, gFrameIndex ); float4 error = 1; float curvature = 0; diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.resources.hlsli new file mode 100644 index 0000000..12f1b7c --- /dev/null +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.resources.hlsli @@ -0,0 +1,84 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "REBLUR_Config.hlsli" + +#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + + #ifdef REBLUR_SPATIAL_REUSE + #define EXTRA_INPUTS \ + NRD_INPUT_TEXTURE( Texture2D, gIn_DiffDirectionPdf, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecDirectionPdf, t, 5 ) + #else + #define EXTRA_INPUTS + #endif + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) \ + EXTRA_INPUTS + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) + +#elif( defined REBLUR_DIFFUSE ) + + #ifdef REBLUR_SPATIAL_REUSE + #define EXTRA_INPUTS \ + NRD_INPUT_TEXTURE( Texture2D, gIn_DiffDirectionPdf, t, 3 ) + #else + #define EXTRA_INPUTS + #endif + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) \ + EXTRA_INPUTS + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ + +#else + + #ifdef REBLUR_SPATIAL_REUSE + #define EXTRA_INPUTS \ + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecDirectionPdf, t, 3 ) + #else + #define EXTRA_INPUTS + #endif + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) \ + EXTRA_INPUTS + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) + +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float4x4, gWorldToView ) \ + NRD_CONSTANT( float4, gRotator ) \ + NRD_CONSTANT( float3, gSpecLobeTrimmingParams ) \ + NRD_CONSTANT( float, gSpatialFiltering ) \ + NRD_CONSTANT( uint, gDiffCheckerboard ) \ + NRD_CONSTANT( uint, gSpecCheckerboard ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_SplitScreen.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.hlsli similarity index 84% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_SplitScreen.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.hlsli index eb0e228..1e2967a 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_SplitScreen.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecular_SplitScreen.resources.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -36,12 +36,12 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 pixelPos : SV_DispatchThreadId) #if( defined REBLUR_DIFFUSE ) checkerboardPos.x = pixelPos.x >> ( gDiffCheckerboard != 2 ? 1 : 0 ); float4 diffResult = gIn_Diff[ gRectOrigin + checkerboardPos ]; - gOut_Diff[ pixelPos ] = diffResult * float( viewZ < gInf ); + gOut_Diff[ pixelPos ] = diffResult * float( viewZ < gDenoisingRange ); #endif #if( defined REBLUR_SPECULAR ) checkerboardPos.x = pixelPos.x >> ( gSpecCheckerboard != 2 ? 1 : 0 ); float4 specResult = gIn_Spec[ gRectOrigin + checkerboardPos ]; - gOut_Spec[ pixelPos ] = specResult * float( viewZ < gInf ); + gOut_Spec[ pixelPos ] = specResult * float( viewZ < gDenoisingRange ); #endif } diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.resources.hlsli new file mode 100644 index 0000000..d03e31b --- /dev/null +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.resources.hlsli @@ -0,0 +1,53 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "REBLUR_Config.hlsli" + +#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) + +#elif( defined REBLUR_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ + +#else + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 1 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) + +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float, gSplitScreen ) \ + NRD_CONSTANT( uint, gDiffCheckerboard ) \ + NRD_CONSTANT( uint, gSpecCheckerboard ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli similarity index 54% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli index 78f4d6b..daebe6c 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli @@ -10,13 +10,16 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli" NRD_DECLARE_CONSTANTS #if( defined REBLUR_SPECULAR ) #define NRD_CTA_8X8 - #define NRD_USE_BORDER_2 + + #if( REBLUR_USE_5X5_HISTORY_CLAMPING == 1 ) + #define NRD_USE_BORDER_2 + #endif #endif #include "NRD_Common.hlsli" @@ -34,7 +37,7 @@ void Preload( uint2 sharedPos, int2 globalPos ) globalPos = clamp( globalPos, 0, gRectSize - 1.0 ); uint2 globalIdUser = gRectOrigin + globalPos; - s_Normal_Roughness[ sharedPos.y ][ sharedPos.x ] = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ globalIdUser ] ); + s_Normal[ sharedPos.y ][ sharedPos.x ] = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ globalIdUser ] ).xyz; #if( defined REBLUR_SPECULAR ) s_Spec[ sharedPos.y ][ sharedPos.x ] = gIn_Spec[ gPreblurEnabled ? globalPos : globalIdUser ]; @@ -49,6 +52,12 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : PRELOAD_INTO_SMEM; + // Normal and roughness + float materialID; + float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ], materialID ); + float3 N = normalAndRoughness.xyz; + float roughness = normalAndRoughness.w; + // Early out float viewZ = abs( gIn_ViewZ[ pixelPosUser ] ); float scaledViewZ = min( viewZ * NRD_FP16_VIEWZ_SCALE, NRD_FP16_MAX ); @@ -56,20 +65,16 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : gOut_ScaledViewZ[ pixelPos ] = scaledViewZ; [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) return; - // Normal and roughness - int2 smemPos = threadPos + BORDER; - float4 normalAndRoughness = s_Normal_Roughness[ smemPos.y ][ smemPos.x ]; - float3 N = normalAndRoughness.xyz; - float roughness = normalAndRoughness.w; - // Current position - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); float3 X = STL::Geometry::AffineTransform( gViewToWorld, Xv ); // Calculate distribution of normals + int2 smemPos = threadPos + BORDER; + #if( defined REBLUR_SPECULAR ) float4 spec = s_Spec[ smemPos.y ][ smemPos.x ]; float4 specM1 = spec; @@ -108,11 +113,12 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 d = float2( dx, dy ) - BORDER; if( all( abs( d ) <= 1 ) ) // only in 3x3 { - float3 n = s_Normal_Roughness[ pos.y ][ pos.x ].xyz; + float3 n = s_Normal[ pos.y ][ pos.x ]; Nflat += n; - float3 pv = STL::Geometry::ReconstructViewPosition( pixelUv + d * gInvRectSize, gFrustum, 1.0, gIsOrtho ); - float3 v = STL::Geometry::RotateVector( gViewToWorld, normalize( -pv ) ); + float3 xv = STL::Geometry::ReconstructViewPosition( pixelUv + d * gInvRectSize, gFrustum, 1.0, gOrthoMode ); + float3 x = STL::Geometry::AffineTransform( gViewToWorld, xv ); + float3 v = GetViewVector( x ); float c = EstimateCurvature( n, v, N, X ); float w = exp2( -0.5 * STL::Math::LengthSquared( d ) ); @@ -127,8 +133,6 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : } float3 Navg = Nflat / 9.0; - float flatness = STL::Math::SmoothStep( 0.985, 1.0, length( Navg ) ); - Nflat = normalize( Nflat ); #if( defined REBLUR_SPECULAR ) @@ -138,53 +142,53 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float4 specSigma = GetStdDev( specM1, specM2 ); minHitDist5x5 = min( minHitDist5x5, minHitDist3x3 ); - curvature /= curvatureSum; - // Mitigate imprecision problems - curvature *= STL::Math::LinearStep( 0.0, NRD_ENCODING_ERRORS.y + 1e-5, abs( curvature ) ); + curvature /= curvatureSum; + curvature *= STL::Math::LinearStep( 0.0, NRD_ENCODING_ERRORS.y, abs( curvature ) ); float roughnessModified = STL::Filtering::GetModifiedRoughnessFromNormalVariance( roughness, Navg ); #endif // Previous position for surface motion float3 motionVector = gIn_ObjectMotion[ pixelPosUser ] * gMotionVectorScale.xyy; // TODO: use nearest MV - float2 pixelUvPrev = STL::Geometry::GetPrevUvFromMotion( pixelUv, X, gWorldToClipPrev, motionVector, gWorldSpaceMotion ); + float2 pixelUvPrev = STL::Geometry::GetPrevUvFromMotion( pixelUv, X, gWorldToClipPrev, motionVector, gIsWorldSpaceMotionEnabled ); float isInScreen = IsInScreen2x2( pixelUvPrev, gRectSizePrev ); - float3 Xprev = X + motionVector * float( gWorldSpaceMotion != 0 ); + float3 Xprev = X + motionVector * float( gIsWorldSpaceMotionEnabled != 0 ); // Previous data ( 4x4, surface motion ) STL::Filtering::CatmullRom catmullRomFilterAtPrevPos = STL::Filtering::GetCatmullRomFilter( saturate( pixelUvPrev ), gRectSizePrev ); float2 catmullRomFilterAtPrevPosGatherOrigin = catmullRomFilterAtPrevPos.origin * gInvScreenSize; - uint4 prevPackRed0 = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 1, 1 ) ).wzxy; - uint4 prevPackRed1 = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 3, 1 ) ).wzxy; - uint4 prevPackRed2 = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 1, 3 ) ).wzxy; - uint4 prevPackRed3 = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 3, 3 ) ).wzxy; + uint4 packedPrevViewZDiffAccumSpeed0 = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 1, 1 ) ).wzxy; + uint4 packedPrevViewZDiffAccumSpeed1 = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 3, 1 ) ).wzxy; + uint4 packedPrevViewZDiffAccumSpeed2 = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 1, 3 ) ).wzxy; + uint4 packedPrevViewZDiffAccumSpeed3 = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 3, 3 ) ).wzxy; - float4 prevViewZ0 = UnpackViewZ( prevPackRed0 ); - float4 prevViewZ1 = UnpackViewZ( prevPackRed1 ); - float4 prevViewZ2 = UnpackViewZ( prevPackRed2 ); - float4 prevViewZ3 = UnpackViewZ( prevPackRed3 ); + float4 prevViewZ0 = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeed0 ); + float4 prevViewZ1 = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeed1 ); + float4 prevViewZ2 = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeed2 ); + float4 prevViewZ3 = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeed3 ); - // TODO: 4x4 normal checks are reduced to 2x2 footprint only ( missed samples are covered by an additional 3x3 edge check ) + #if( defined REBLUR_DIFFUSE ) + float4 diffPrevAccumSpeeds = UnpackDiffAccumSpeed( uint4( packedPrevViewZDiffAccumSpeed0.w, packedPrevViewZDiffAccumSpeed1.z, packedPrevViewZDiffAccumSpeed2.y, packedPrevViewZDiffAccumSpeed3.x ) ); + #endif + + // TODO: 4x4 normals and materialID are reduced to 2x2 only STL::Filtering::Bilinear bilinearFilterAtPrevPos = STL::Filtering::GetBilinearFilter( saturate( pixelUvPrev ), gRectSizePrev ); float2 bilinearFilterAtPrevPosGatherOrigin = ( bilinearFilterAtPrevPos.origin + 1.0 ) * gInvScreenSize; - uint4 prevPackGreen = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherGreen( gNearestClamp, bilinearFilterAtPrevPosGatherOrigin ).wzxy; + uint4 packedPrevNormalSpecAccumSpeed = gIn_Prev_Normal_SpecAccumSpeed.GatherRed( gNearestClamp, bilinearFilterAtPrevPosGatherOrigin ).wzxy; + float4 prevMaterialIDs; float4 specPrevAccumSpeeds; - float3 prevNormal00 = UnpackNormalRoughnessSpecAccumSpeed( prevPackGreen.x, specPrevAccumSpeeds.x ).xyz; - float3 prevNormal10 = UnpackNormalRoughnessSpecAccumSpeed( prevPackGreen.y, specPrevAccumSpeeds.y ).xyz; - float3 prevNormal01 = UnpackNormalRoughnessSpecAccumSpeed( prevPackGreen.z, specPrevAccumSpeeds.z ).xyz; - float3 prevNormal11 = UnpackNormalRoughnessSpecAccumSpeed( prevPackGreen.w, specPrevAccumSpeeds.w ).xyz; - - #if( defined REBLUR_DIFFUSE ) - float4 diffPrevAccumSpeeds = UnpackDiffAccumSpeed( uint4( prevPackRed0.w, prevPackRed1.z, prevPackRed2.y, prevPackRed3.x ) ); - #endif + float3 prevNormal00 = UnpackPrevNormalAccumSpeedMaterialID( packedPrevNormalSpecAccumSpeed.x, specPrevAccumSpeeds.x, prevMaterialIDs.x ); + float3 prevNormal10 = UnpackPrevNormalAccumSpeedMaterialID( packedPrevNormalSpecAccumSpeed.y, specPrevAccumSpeeds.y, prevMaterialIDs.y ); + float3 prevNormal01 = UnpackPrevNormalAccumSpeedMaterialID( packedPrevNormalSpecAccumSpeed.z, specPrevAccumSpeeds.z, prevMaterialIDs.z ); + float3 prevNormal11 = UnpackPrevNormalAccumSpeedMaterialID( packedPrevNormalSpecAccumSpeed.w, specPrevAccumSpeeds.w, prevMaterialIDs.w ); // Plane distance based disocclusion for surface motion float3 V = GetViewVector( X ); - float invFrustumHeight = STL::Math::PositiveRcp( PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ) ); + float invFrustumHeight = 1.0 / PixelRadiusToWorld( gUnproject, gOrthoMode, gRectSize.y, viewZ ); float3 prevNflatUnnormalized = prevNormal00 + prevNormal10 + prevNormal01 + prevNormal11; - float disocclusionThreshold = GetDisocclusionThreshold( gDisocclusionThreshold, gJitterDelta, viewZ, Nflat, V ); + float disocclusionThreshold = GetDisocclusionThreshold( gDisocclusionThreshold, viewZ, Nflat, V ); disocclusionThreshold = lerp( -1.0, disocclusionThreshold, isInScreen ); // out-of-screen = occlusion float3 Xvprev = STL::Geometry::AffineTransform( gWorldToViewPrev, Xprev ); float NoXprev1 = abs( dot( Xprev, Nflat ) ); @@ -207,58 +211,72 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : cosa.z = dot( N, prevNormal01 ); cosa.w = dot( N, prevNormal11 ); - float parallax = ComputeParallax( X, Xprev, gCameraDelta ); + float parallax = ComputeParallax( X, Xprev, gCameraDelta, gOrthoMode != 0 ); float cosAngleMin = lerp( -0.95, -0.01, SaturateParallax( parallax ) ); + float mvLength = length( ( pixelUvPrev - pixelUv ) * gRectSize ); float4 frontFacing = STL::Math::LinearStep( cosAngleMin, 0.01, cosa ); + frontFacing = lerp( 1.0, frontFacing, saturate( mvLength / 0.25 ) ); + occlusion0.w *= frontFacing.x; occlusion1.z *= frontFacing.y; occlusion2.y *= frontFacing.z; occlusion3.x *= frontFacing.w; // Avoid "got stuck in history" effect under slow motion when only 1 sample is valid from 2x2 footprint - float4 surfaceOcclusion2x2 = float4( occlusion0.w, occlusion1.z, occlusion2.y, occlusion3.x ); - float footprintQuality = STL::Filtering::ApplyBilinearFilter( surfaceOcclusion2x2.x, surfaceOcclusion2x2.y, surfaceOcclusion2x2.z, surfaceOcclusion2x2.w, bilinearFilterAtPrevPos ); + float footprintQuality = STL::Filtering::ApplyBilinearFilter( occlusion0.w, occlusion1.z, occlusion2.y, occlusion3.x, bilinearFilterAtPrevPos ); + footprintQuality = lerp( 0.5, 1.0, footprintQuality ); // Avoid footprint momentary stretching due to changed viewing angle float3 Vprev = normalize( Xprev - gCameraDelta.xyz ); float VoNflat = abs( dot( Nflat, V ) ) + 1e-3; float VoNflatprev = abs( dot( Nflat, Vprev ) ) + 1e-3; float sizeQuality = VoNflatprev / VoNflat; // this order because we need to fix stretching only, shrinking is OK - footprintQuality *= lerp( 0.1, 1.0, saturate( sizeQuality + abs( gIsOrtho ) ) ); + footprintQuality *= lerp( 0.1, 1.0, saturate( sizeQuality + abs( gOrthoMode ) ) ); + + float4 surfaceWeightsWithOcclusion = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevPos, float4( occlusion0.w, occlusion1.z, occlusion2.y, occlusion3.x ) ); - float surfaceOcclusionAvg = step( 15.5, dot( occlusion0 + occlusion1 + occlusion2 + occlusion3, 1.0 ) ) * REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA; + // Material ID // TODO: needed in "footprintQuality"? + float4 materialCmps = CompareMaterials( materialID, prevMaterialIDs, gDiffMaterialMask | gSpecMaterialMask ); + occlusion0.w *= materialCmps.x; + occlusion1.z *= materialCmps.y; + occlusion2.y *= materialCmps.z; + occlusion3.x *= materialCmps.w; + + float4 surfaceWeightsWithOcclusionAndMaterialID = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevPos, float4( occlusion0.w, occlusion1.z, occlusion2.y, occlusion3.x ) ); // IMPORTANT: CatRom or custom bilinear work as expected when only one is in use. When mixed, a disocclusion event can introduce a switch to // bilinear, which can snap to a single sample according to custom weights. It can introduce a discontinuity in color. In turn CatRom can immediately // react to this and increase local sharpness. Next, if another disocclusion happens, custom bilinear can snap to the sharpened sample again... // This process can continue almost infinitely, blowing up the image due to over sharpenning in a loop. It can be fixed by: // - using camera jittering - // - not using CatRom on edges + // - not using CatRom on edges (current approach) // - computing 4x4 normal weights - surfaceOcclusionAvg *= float( length( Navg ) > 0.65 ); // TODO: 0.85? - - float4 surfaceWeightsWithOcclusion = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevPos, surfaceOcclusion2x2 ); + bool isCatRomAllowedForSurfaceMotion = dot( occlusion0 + occlusion1 + occlusion2 + occlusion3, 1.0 ) > 15.5; + isCatRomAllowedForSurfaceMotion = isCatRomAllowedForSurfaceMotion & ( length( Navg ) > 0.65 ); // TODO: 0.85? + isCatRomAllowedForSurfaceMotion = isCatRomAllowedForSurfaceMotion & REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA; - float fbits = surfaceOcclusionAvg * 8.0; + float fbits = float( isCatRomAllowedForSurfaceMotion ) * 8.0; // Update accumulation speeds + // IMPORTANT: "Upper bound" is used to control accumulation, while "No confidence" artificially bumps number of accumulated + // frames to skip "HistoryFix" pass. Maybe introduce a bit in "fbits", because current behavior negatively impacts "TS"? #if( defined REBLUR_DIFFUSE ) - float diffMaxAccumSpeed = AdvanceAccumSpeed( diffPrevAccumSpeeds, surfaceWeightsWithOcclusion ); - diffMaxAccumSpeed *= footprintQuality; + float diffMaxAccumSpeedNoConfidence = AdvanceAccumSpeed( diffPrevAccumSpeeds, gDiffMaterialMask ? surfaceWeightsWithOcclusionAndMaterialID : surfaceWeightsWithOcclusion ); + diffMaxAccumSpeedNoConfidence *= footprintQuality; - float diffHistoryConfidence = 1.0; + float diffAccumSpeedUpperBound = diffMaxAccumSpeedNoConfidence; #if( defined REBLUR_PROVIDED_CONFIDENCE ) - diffHistoryConfidence = gIn_DiffConfidence[ pixelPosUser ]; + diffAccumSpeedUpperBound *= gIn_DiffConfidence[ pixelPosUser ]; #endif #endif #if( defined REBLUR_SPECULAR ) - float specMaxAccumSpeed = AdvanceAccumSpeed( specPrevAccumSpeeds, surfaceWeightsWithOcclusion ); - specMaxAccumSpeed *= footprintQuality; + float specMaxAccumSpeedNoConfidence = AdvanceAccumSpeed( specPrevAccumSpeeds, gSpecMaterialMask ? surfaceWeightsWithOcclusionAndMaterialID : surfaceWeightsWithOcclusion ); + specMaxAccumSpeedNoConfidence *= footprintQuality; - float specHistoryConfidence = 1.0; + float specAccumSpeedUpperBound = specMaxAccumSpeedNoConfidence; #if( defined REBLUR_PROVIDED_CONFIDENCE ) - specHistoryConfidence = gIn_SpecConfidence[ pixelPosUser ]; + specAccumSpeedUpperBound *= gIn_SpecConfidence[ pixelPosUser ]; #endif #endif @@ -268,65 +286,51 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float4 diffHistory = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_History_Diff, gIn_History_Spec, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - surfaceWeightsWithOcclusion, surfaceOcclusionAvg == 1.0, + surfaceWeightsWithOcclusionAndMaterialID, isCatRomAllowedForSurfaceMotion, specHistorySurface ); #elif( defined REBLUR_DIFFUSE ) float4 diffHistory = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_History_Diff, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - surfaceWeightsWithOcclusion, surfaceOcclusionAvg == 1.0 + surfaceWeightsWithOcclusionAndMaterialID, isCatRomAllowedForSurfaceMotion ); #else float4 specHistorySurface = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_History_Spec, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - surfaceWeightsWithOcclusion, surfaceOcclusionAvg == 1.0 + surfaceWeightsWithOcclusionAndMaterialID, isCatRomAllowedForSurfaceMotion ); #endif - // Noisy signal with checkerboard reconstruction uint checkerboard = STL::Sequence::CheckerBoard( pixelPos, gFrameIndex ); + // Diffuse #if( defined REBLUR_DIFFUSE ) float4 diff = gIn_Diff[ pixelPos ]; + + // Checkerboard resolve bool diffHasData = gDiffCheckerboard == 2 || checkerboard == gDiffCheckerboard; if( !diffHasData && gResetHistory == 0 ) { - float2 temporalAccumulationParams = GetTemporalAccumulationParams( isInScreen, diffMaxAccumSpeed * diffHistoryConfidence ); + float2 temporalAccumulationParams = GetTemporalAccumulationParams( isInScreen, diffAccumSpeedUpperBound ); float historyWeight = 1.0 - gCheckerboardResolveAccumSpeed * temporalAccumulationParams.x; diff = MixHistoryAndCurrent( diffHistory, diff, historyWeight ); } - #endif - #if( defined REBLUR_SPECULAR ) - bool specHasData = gSpecCheckerboard == 2 || checkerboard == gSpecCheckerboard; - if( !specHasData && gResetHistory == 0 ) - { - float2 temporalAccumulationParams = GetTemporalAccumulationParams( isInScreen, specMaxAccumSpeed * specHistoryConfidence, parallax, roughness ); - float historyWeight = 1.0 - gCheckerboardResolveAccumSpeed * temporalAccumulationParams.x; - - float4 specHistorySurfaceClamped = STL::Color::Clamp( specM1, specSigma * temporalAccumulationParams.y, specHistorySurface, REBLUR_USE_COLOR_CLAMPING_AABB ); // TODO: needed? - specHistorySurfaceClamped = lerp( specHistorySurfaceClamped, specHistorySurface, roughnessModified * roughnessModified ); - - spec = MixHistoryAndCurrent( specHistorySurfaceClamped, spec, historyWeight, roughnessModified ); - } - #endif - - // Diffuse - #if( defined REBLUR_DIFFUSE ) // Accumulation - float diffAccumSpeed = diffMaxAccumSpeed * diffHistoryConfidence; - float diffAccumSpeedNonLinear = 1.0 / ( min( diffAccumSpeed, gDiffMaxAccumulatedFrameNum ) + 1.0 ); + float diffAccumSpeed = diffAccumSpeedUpperBound; + float diffAccumSpeedNonLinear = 1.0 / ( min( diffAccumSpeed, gMaxAccumulatedFrameNum ) + 1.0 ); float4 diffResult = MixHistoryAndCurrent( diffHistory, diff, diffAccumSpeedNonLinear ); diffResult = Sanitize( diffResult, diff ); gOut_Diff[ pixelPos ] = diffResult; + float diffMipLevel = GetMipLevel( 1.0 ); float diffError = GetColorErrorForAdaptiveRadiusScale( diffResult, diffHistory, diffAccumSpeedNonLinear, 1.0, 0 ); - float diffAccumSpeedFinal = min( diffMaxAccumSpeed, max( diffAccumSpeed, GetMipLevel( 1.0 ) ) ); + float diffAccumSpeedFinal = min( diffMaxAccumSpeedNoConfidence, max( diffAccumSpeed, diffMipLevel ) ); #else float diffError = 0; float diffAccumSpeedFinal = 0; @@ -334,140 +338,175 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Specular #if( defined REBLUR_SPECULAR ) + float smc = GetSpecMagicCurve( roughnessModified ); + + // Checkerboard resolve + bool specHasData = gSpecCheckerboard == 2 || checkerboard == gSpecCheckerboard; + if( !specHasData && gResetHistory == 0 ) + { + float2 temporalAccumulationParams = GetTemporalAccumulationParams( isInScreen, specAccumSpeedUpperBound, parallax, roughness ); + float historyWeight = 1.0 - gCheckerboardResolveAccumSpeed * temporalAccumulationParams.x; + + float4 specHistorySurfaceClamped = STL::Color::Clamp( specM1, specSigma * temporalAccumulationParams.y, specHistorySurface, REBLUR_USE_COLOR_CLAMPING_AABB ); // TODO: needed? + specHistorySurfaceClamped = lerp( specHistorySurfaceClamped, specHistorySurface, smc ); + + spec = MixHistoryAndCurrent( specHistorySurfaceClamped, spec, historyWeight, roughnessModified ); + } + // Current hit distance float hitDistCurrent = lerp( minHitDist3x3, minHitDist5x5, STL::Math::SmoothStep( 0.04, 0.08, roughnessModified ) ); hitDistCurrent = STL::Color::Clamp( specM1.w, specSigma.w * 3.0, hitDistCurrent ); - float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gSpecHitDistParams, roughness ); + float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gHitDistParams, roughness ); hitDistCurrent *= hitDistScale; - // Parallax correction - float hitDistFactor = saturate( hitDistCurrent * invFrustumHeight ); - parallax *= hitDistFactor; - // Virtual motion float NoV = abs( dot( N, V ) ); - float4 Xvirtual = GetXvirtual( X, V, NoV, roughnessModified, hitDistCurrent, viewZ, curvature ); - float2 pixelUvVirtualPrev = STL::Geometry::GetScreenUv( gWorldToClipPrev, Xvirtual.xyz, false ); + float pixelSize = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); + float realCurvature = GetRealCurvature( curvature, pixelSize, NoV ); + float3 Xvirtual = GetXvirtual( X, Xprev, V, NoV, roughnessModified, hitDistCurrent, realCurvature ); + float2 pixelUvVirtualPrev = STL::Geometry::GetScreenUv( gWorldToClipPrev, Xvirtual, false ); STL::Filtering::Bilinear bilinearFilterAtPrevVirtualPos = STL::Filtering::GetBilinearFilter( saturate( pixelUvVirtualPrev ), gRectSizePrev ); float virtualHistoryAmount = IsInScreen2x2( pixelUvVirtualPrev, gRectSizePrev ); - virtualHistoryAmount *= flatness; virtualHistoryAmount *= 1.0 - gReference; virtualHistoryAmount *= STL::ImportanceSampling::GetSpecularDominantFactor( NoV, roughnessModified, REBLUR_SPEC_DOMINANT_DIRECTION ); + // Parallax correction + float parallaxOrig = parallax; + + float parallaxVirtual = ComputeParallax( Xvirtual, Xvirtual, gCameraDelta, gOrthoMode != 0 ); + parallax = max( parallax, parallaxVirtual * ( 1.0 - smc ) ); + + float hitDistFactor = saturate( hitDistCurrent * invFrustumHeight ); + parallax *= hitDistFactor; + // This scaler improves motion stability for roughness 0.4+ virtualHistoryAmount *= 1.0 - STL::Math::SmoothStep( 0.15, 0.85, roughness ) * ( 1.0 - hitDistFactor ); // Virtual motion - surface similarity // TODO: make it closer to the main disocclusion test float2 gatherUvVirtualPrev = ( bilinearFilterAtPrevVirtualPos.origin + 1.0 ) * gInvScreenSize; - uint4 prevPackRedVirtual = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, gatherUvVirtualPrev ).wzxy; - float4 prevViewZsVirtual = UnpackViewZ( prevPackRedVirtual ); + uint4 packedPrevViewZDiffAccumSpeedVirtual = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, gatherUvVirtualPrev ).wzxy; + float4 prevViewZsVirtual = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeedVirtual ); float3 Nvprev = STL::Geometry::RotateVector( gWorldToViewPrev, Nflat ); float4 ka; - ka.x = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.x, gIsOrtho ) ); - ka.y = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.y, gIsOrtho ) ); - ka.z = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.z, gIsOrtho ) ); - ka.w = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.w, gIsOrtho ) ); + ka.x = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.x, gOrthoMode ) ); + ka.y = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.y, gOrthoMode ) ); + ka.z = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.z, gOrthoMode ) ); + ka.w = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.w, gOrthoMode ) ); float kb = dot( Nvprev, Xvprev ); float4 f = abs( ka - kb ) * invFrustumHeight; - float4 virtualMotionSurfaceWeights = STL::Math::LinearStep( 0.015, 0.005, f ); - float4 virtualMotionFootprintWeights = virtualMotionSurfaceWeights; - - virtualHistoryAmount *= dot( virtualMotionSurfaceWeights, 0.25 ); - - // Virtual motion - normal similarity - uint4 prevPackGreenVirtual = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherGreen( gNearestClamp, gatherUvVirtualPrev ).wzxy; - float4 prevNormalAndRoughnessVirtual00 = UnpackNormalRoughness( prevPackGreenVirtual.x ); - float4 prevNormalAndRoughnessVirtual10 = UnpackNormalRoughness( prevPackGreenVirtual.y ); - float4 prevNormalAndRoughnessVirtual01 = UnpackNormalRoughness( prevPackGreenVirtual.z ); - float4 prevNormalAndRoughnessVirtual11 = UnpackNormalRoughness( prevPackGreenVirtual.w ); - - float lobeHalfAngle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughnessModified ); - float avgCurvatureAngle = STL::Math::AtanApprox( abs( curvature ) ) + NRD_ENCODING_ERRORS.x; - float specNormalParams = 1.0 / min( lobeHalfAngle + avgCurvatureAngle, STL::Math::DegToRad( 89.0 ) ); - float4 virtualMotionNormalWeights = GetNormalWeight4( specNormalParams, N, prevNormalAndRoughnessVirtual00.xyz, prevNormalAndRoughnessVirtual10.xyz, prevNormalAndRoughnessVirtual01.xyz, prevNormalAndRoughnessVirtual11.xyz ); - virtualMotionNormalWeights = lerp( 1.0, virtualMotionNormalWeights, Xvirtual.w ); - virtualMotionFootprintWeights *= virtualMotionNormalWeights; + float4 virtualMotionSurfaceWeights = step( f, disocclusionThreshold ); + float virtualHistoryConfidence = STL::Filtering::ApplyBilinearFilter( virtualMotionSurfaceWeights.x, virtualMotionSurfaceWeights.y, virtualMotionSurfaceWeights.z, virtualMotionSurfaceWeights.w, bilinearFilterAtPrevVirtualPos ); + virtualHistoryAmount *= virtualHistoryConfidence; // Virtual motion - roughness similarity - float4 prevRoughnessVirtual = float4( prevNormalAndRoughnessVirtual00.w, prevNormalAndRoughnessVirtual10.w, prevNormalAndRoughnessVirtual01.w, prevNormalAndRoughnessVirtual11.w ); - float2 specRoughnessParams = GetRoughnessWeightParams( roughness, 0.1 ); - float4 virtualMotionRoughnessWeights = GetRoughnessWeight( specRoughnessParams, prevRoughnessVirtual ); - virtualMotionFootprintWeights *= virtualMotionRoughnessWeights; + float prevRoughnessVirtual = gIn_Prev_Roughness.SampleLevel( gLinearClamp, pixelUvVirtualPrev * gResolutionScale, 0 ); + float virtualMotionRoughnessWeight = GetEncodingAwareRoughnessWeight( roughness, prevRoughnessVirtual, gRoughnessFraction * 2.0 ); + virtualHistoryConfidence *= virtualMotionRoughnessWeight; - float interpolatedRoughnessWeight = STL::Filtering::ApplyBilinearFilter( virtualMotionRoughnessWeights.x, virtualMotionRoughnessWeights.y, virtualMotionRoughnessWeights.z, virtualMotionRoughnessWeights.w, bilinearFilterAtPrevVirtualPos ); float NoVflat = abs( dot( Nflat, V ) ); float fresnelFactor = STL::BRDF::Pow5( NoVflat ); float virtualHistoryAmountRoughnessAdjustment = lerp( fresnelFactor, 1.0, SaturateParallax( parallax * 0.5 ) ) * 0.5; - virtualHistoryAmount *= lerp( virtualHistoryAmountRoughnessAdjustment, 1.0, interpolatedRoughnessWeight ); + virtualHistoryAmount *= lerp( virtualHistoryAmountRoughnessAdjustment, 1.0, roughness > prevRoughnessVirtual ? virtualMotionRoughnessWeight : 1.0 ); // Sample virtual history float4 bilinearWeightsWithOcclusionVirtual = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevVirtualPos, max( virtualMotionSurfaceWeights, 0.001 ) ); - float virtualOcclusionAvg = step( 3.5, dot( virtualMotionSurfaceWeights, 1.0 ) ) * REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TA; - virtualOcclusionAvg *= surfaceOcclusionAvg; + bool isCatRomAllowedForVirtualMotion = dot( virtualMotionSurfaceWeights, 1.0 ) > 3.5; + isCatRomAllowedForVirtualMotion = isCatRomAllowedForVirtualMotion & isCatRomAllowedForSurfaceMotion; + isCatRomAllowedForVirtualMotion = isCatRomAllowedForVirtualMotion & REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TA; float4 specHistoryVirtual = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_History_Spec, gLinearClamp, saturate( pixelUvVirtualPrev ) * gRectSizePrev, gInvScreenSize, - bilinearWeightsWithOcclusionVirtual, virtualOcclusionAvg == 1.0 + bilinearWeightsWithOcclusionVirtual, isCatRomAllowedForVirtualMotion ); - // Virtual motion - hit distance similarity - float parallaxScale = lerp( 0.125 + flatness * 0.125, 1.0, gReference ); - float specAccumSpeedSurface = GetSpecAccumSpeed( specMaxAccumSpeed * specHistoryConfidence, roughnessModified, NoV, parallax * parallaxScale ); - float specAccumSpeedSurfaceNonLinear = 1.0 / ( min( specAccumSpeedSurface, gSpecMaxAccumulatedFrameNum ) + 1.0 ); + // Virtual motion - hit distance similarity // TODO: move into "prev-prev" loop + float specAccumSpeedSurface = GetSpecAccumSpeed( specAccumSpeedUpperBound, roughnessModified, NoV, parallax ); // TODO: optional scale can be applied to parallax if local curvature is very high, but it can lead to lags + float specAccumSpeedSurfaceNonLinear = 1.0 / ( min( specAccumSpeedSurface, gMaxAccumulatedFrameNum ) + 1.0 ); float hitDistNorm = lerp( specHistorySurface.w, spec.w, max( specAccumSpeedSurfaceNonLinear, REBLUR_HIT_DIST_MIN_ACCUM_SPEED( roughnessModified ) ) ); // TODO: try to use "hitDistCurrent" - float hitDist = hitDistNorm * hitDistScale; - float hitDistVirtual = specHistoryVirtual.w * hitDistScale; - float hitDistDelta = abs( hitDistVirtual - hitDist ); // TODO: sigma can worsen! useful for high roughness only? - float hitDistMax = max( hitDistVirtual, hitDist ); - hitDistDelta /= hitDistMax + viewZ + 1e-6; // TODO: + roughnessModified? - float virtualMotionHitDistWeights = 1.0 - STL::Math::SmoothStep( 0.0, 0.25, STL::Math::Sqrt01( hitDistDelta ) * SaturateParallax( parallax * REBLUR_TS_SIGMA_AMPLITUDE ) ); - virtualMotionHitDistWeights = lerp( 1.0, virtualMotionHitDistWeights, Xvirtual.w ); - virtualMotionFootprintWeights *= virtualMotionHitDistWeights; - - // Accumulation acceleration - float specAccumSpeedVirtual = specMaxAccumSpeed * specHistoryConfidence; - float specMinAccumSpeed = min( specAccumSpeedVirtual, GetMipLevel( roughnessModified ) ); - float specAccumSpeedScale = 1.0 - STL::Math::SmoothStep01( dot( hitDistDelta, 0.25 ) * SaturateParallax( parallax * REBLUR_TS_SIGMA_AMPLITUDE ) ); - specAccumSpeedVirtual = lerp( specMinAccumSpeed, specAccumSpeedVirtual, specAccumSpeedScale ); + float hitDistFocused = ApplyThinLensEquation( hitDistNorm * hitDistScale, realCurvature ); + float hitDistVirtualFocused = ApplyThinLensEquation( specHistoryVirtual.w * hitDistScale, realCurvature ); + float hitDistDelta = abs( hitDistVirtualFocused - hitDistFocused ); // TODO: sigma can worsen! useful for high roughness only? + float hitDistMax = max( abs( hitDistVirtualFocused ), abs( hitDistFocused ) ); + hitDistDelta /= hitDistMax + viewZ * 0.01 + 1e-6; // "viewZ" is already taken into account in "parallax", but use 1% to decrease sensitivity to low values + float virtualMotionHitDistWeight = 1.0 - STL::Math::SmoothStep( 0.0, 0.25, STL::Math::Sqrt01( hitDistDelta ) * SaturateParallax( parallax * REBLUR_TS_SIGMA_AMPLITUDE ) ); + virtualHistoryConfidence *= virtualMotionHitDistWeight; + + // Normal weight ( with fixing trails if radiance on a flat surface is taken from a sloppy surface ) + float lobeHalfAngle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughnessModified ); + lobeHalfAngle += NRD_ENCODING_ERRORS.x + STL::Math::DegToRad( 1.5 ); // TODO: tune better? - // Fix trails if radiance on a flat surface is taken from a sloppy surface - float2 pixelUvDelta = pixelUvVirtualPrev - pixelUvPrev; - float trailConfidence = 1.0; + float parallaxInPixels = GetParallaxInPixels( parallaxOrig, gUnproject ); + float pixelSizeOverCurvatureRadius = curvature * NoV; // defines angle per 1 pixel + float tana = pixelSizeOverCurvatureRadius * ( lerp( parallaxInPixels, 0.0, roughness ) + 2.0 ); + float avgCurvatureAngle = STL::Math::AtanApprox( abs( tana ) ); + float magicScale = lerp( 10.0, 1.0, saturate( parallaxInPixels / 5.0 ) ); + float2 virtualMotionDelta = pixelUvVirtualPrev - pixelUvPrev; + virtualMotionDelta *= gOrthoMode == 0 ? magicScale : 1.0; + + float virtualMotionNormalWeight = 1.0; [unroll] - for( uint i = 0; i < 2; i++ ) + for( uint i = 0; i < REBLUR_VIRTUAL_MOTION_NORMAL_WEIGHT_ITERATION_NUM; i++ ) { - float2 pixelUvVirtualPrevPrev = pixelUvVirtualPrev + pixelUvDelta * ( 2.0 + i ); + float t = i + ( REBLUR_VIRTUAL_MOTION_NORMAL_WEIGHT_ITERATION_NUM < 3 ? 1.0 : 0.0 ); + float2 pixelUvVirtualPrevPrev = pixelUvVirtualPrev + virtualMotionDelta * t; + + #if( REBLUR_USE_BILINEAR_FOR_VIRTUAL_NORMAL_WEIGHT == 1 ) + STL::Filtering::Bilinear bilinearFilterAtPrevPrevVirtualPos = STL::Filtering::GetBilinearFilter( saturate( pixelUvVirtualPrevPrev ), gRectSizePrev ); + float2 gatherUvVirtualPrevPrev = ( bilinearFilterAtPrevPrevVirtualPos.origin + 1.0 ) * gInvScreenSize; + uint4 p = gIn_Prev_Normal_SpecAccumSpeed.GatherRed( gNearestClamp, gatherUvVirtualPrevPrev ).wzxy; - uint p = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds[ uint2( pixelUvVirtualPrevPrev * gRectSizePrev ) ].y; - float3 n = UnpackNormalRoughness( p ).xyz; + float3 n00 = UnpackPrevNormal( p.x ); + float3 n10 = UnpackPrevNormal( p.y ); + float3 n01 = UnpackPrevNormal( p.z ); + float3 n11 = UnpackPrevNormal( p.w ); - float cosa = dot( N, n ); - float angle = STL::Math::AcosApprox( saturate( cosa ) ); + float3 n = STL::Filtering::ApplyBilinearFilter( n00, n10, n01, n11, bilinearFilterAtPrevPrevVirtualPos ); + n = normalize( n ); + #else + uint p = gIn_Prev_Normal_SpecAccumSpeed[ uint2( pixelUvVirtualPrevPrev * gRectSizePrev ) ]; + float3 n = UnpackPrevNormal( p ); + #endif - trailConfidence *= _ComputeWeight( float2( specNormalParams, -0.001 ), angle ); + float maxAngle = lobeHalfAngle + avgCurvatureAngle * ( 1.0 + t ); + virtualMotionNormalWeight *= IsInScreen( pixelUvVirtualPrevPrev ) ? GetEncodingAwareNormalWeight( N, n, maxAngle ) : 1.0; } - trailConfidence = lerp( 1.0, trailConfidence, Xvirtual.w ); + float virtualMotionLengthInPixels = length( virtualMotionDelta * gRectSizePrev ); + virtualMotionNormalWeight = lerp( 1.0, virtualMotionNormalWeight, saturate( virtualMotionLengthInPixels / 0.5 ) ); - // Virtual history clamping - float virtualHistoryConfidence = STL::Filtering::ApplyBilinearFilter( virtualMotionFootprintWeights.x, virtualMotionFootprintWeights.y, virtualMotionFootprintWeights.z, virtualMotionFootprintWeights.w, bilinearFilterAtPrevVirtualPos ); - virtualHistoryConfidence *= trailConfidence; + virtualHistoryConfidence *= virtualMotionNormalWeight; + virtualHistoryAmount *= lerp( 0.333, 1.0, virtualMotionNormalWeight ); // TODO: should depend on virtualHistoryAmount and accumSpeed? - float smc = GetSpecMagicCurve( roughnessModified ); + // Virtual motion - accumulation acceleration + float responsiveAccumulationAmount = GetResponsiveAccumulationAmount( roughness ); + float specAccumSpeedVirtual = GetSpecAccumSpeed( specAccumSpeedUpperBound, lerp( 1.0, roughnessModified, responsiveAccumulationAmount ), 0.99999, 0.0 ); + + float specMipLevel = GetMipLevel( roughnessModified ); + float specMinAccumSpeed = min( specAccumSpeedVirtual, specMipLevel ); + float fpsScaler = lerp( saturate( gFramerateScale * gFramerateScale ), 1.0, virtualHistoryConfidence ); + + float specAccumSpeedScale = lerp( 0.7, 1.0, virtualMotionHitDistWeight ); + specAccumSpeedScale *= lerp( 0.7, 1.0, virtualMotionNormalWeight ); + specAccumSpeedScale *= fpsScaler; + + specAccumSpeedVirtual = lerp( specMinAccumSpeed, specAccumSpeedVirtual, specAccumSpeedScale ); + + // Virtual history clamping float sigmaScale = lerp( 1.0, 3.0, smc ) * ( 1.0 + 2.0 * smc * REBLUR_TS_SIGMA_AMPLITUDE * virtualHistoryConfidence ); float4 specHistoryVirtualClamped = STL::Color::Clamp( specM1, specSigma * sigmaScale, specHistoryVirtual, REBLUR_USE_COLOR_CLAMPING_AABB ); float unclampedVirtualHistoryAmount = lerp( virtualHistoryConfidence, 1.0, smc * STL::Math::SmoothStep( 0.2, 0.4, roughnessModified ) ); + unclampedVirtualHistoryAmount *= lerp( 1.0, smc * 0.5 + 0.5, responsiveAccumulationAmount ); float4 specHistoryVirtualMixed = lerp( specHistoryVirtualClamped, specHistoryVirtual, unclampedVirtualHistoryAmount ); // Final composition float specAccumSpeed = InterpolateAccumSpeeds( specAccumSpeedSurface, specAccumSpeedVirtual, virtualHistoryAmount ); - float specAccumSpeedNonLinear = 1.0 / ( min( specAccumSpeed, gSpecMaxAccumulatedFrameNum ) + 1.0 ); + float specAccumSpeedNonLinear = 1.0 / ( min( specAccumSpeed, gMaxAccumulatedFrameNum ) + 1.0 ); float4 specHistory = MixSurfaceAndVirtualMotion( specHistorySurface, specHistoryVirtualMixed, virtualHistoryAmount, hitDistFactor ); float4 specResult = MixHistoryAndCurrent( specHistory, spec, specAccumSpeedNonLinear, roughnessModified ); @@ -475,13 +514,14 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : gOut_Spec[ pixelPos ] = specResult; - fbits += floor( GetMipLevel( roughnessModified ) ); - fbits += virtualOcclusionAvg * 16.0; + fbits += floor( specMipLevel ); + fbits += float( isCatRomAllowedForVirtualMotion ) * 16.0; virtualHistoryConfidence = lerp( 1.0, virtualHistoryConfidence, virtualHistoryAmount ); + virtualHistoryConfidence = lerp( virtualHistoryConfidence, 1.0, specAccumSpeedNonLinear ); float specError = GetColorErrorForAdaptiveRadiusScale( specResult, specHistory, specAccumSpeedNonLinear, roughnessModified, 0 ); - float specAccumSpeedFinal = min( specMaxAccumSpeed, max( specAccumSpeed, GetMipLevel( roughnessModified ) ) ); + float specAccumSpeedFinal = min( specMaxAccumSpeedNoConfidence, max( specAccumSpeed, specMipLevel ) ); #else float virtualHistoryAmount = 0; float virtualHistoryConfidence = 0; diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli similarity index 54% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli index c161f66..18435d3 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.resources.hlsli @@ -11,10 +11,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "REBLUR_Config.hlsli" #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + #if( defined REBLUR_PROVIDED_CONFIDENCE ) #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_DiffConfidence, t, 8 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecConfidence, t, 9 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_DiffConfidence, t, 10 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecConfidence, t, 11 ) #else #define EXTRA_INPUTS #endif @@ -23,11 +24,13 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ObjectMotion, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_History_Diff, t, 5 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 6 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_History_Spec, t, 7 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_DiffAccumSpeed, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Normal_SpecAccumSpeed, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Roughness, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 6 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_History_Diff, t, 7 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 8 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_History_Spec, t, 9 ) \ EXTRA_INPUTS #define NRD_DECLARE_OUTPUT_TEXTURES \ @@ -35,29 +38,13 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_InternalData, u, 1 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Error, u, 2 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 3 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 4 ) \ - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToViewPrev ) \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4x4, gWorldToClip ) \ - NRD_CONSTANT( float4, gFrustumPrev ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ - NRD_CONSTANT( float, gDisocclusionThreshold ) \ - NRD_CONSTANT( float, gJitterDelta ) \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( uint, gPreblurEnabled ) \ - NRD_CONSTANTS_END + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 4 ) + #elif( defined REBLUR_DIFFUSE ) + #if( defined REBLUR_PROVIDED_CONFIDENCE ) #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_DiffConfidence, t, 6 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_DiffConfidence, t, 7 ) #else #define EXTRA_INPUTS #endif @@ -66,9 +53,10 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ObjectMotion, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_History_Diff, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_DiffAccumSpeed, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Normal_SpecAccumSpeed, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_History_Diff, t, 6 ) \ EXTRA_INPUTS #define NRD_DECLARE_OUTPUT_TEXTURES \ @@ -77,24 +65,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Error, u, 2 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 3 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToViewPrev ) \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4, gFrustumPrev ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ - NRD_CONSTANT( float, gDisocclusionThreshold ) \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( uint, gPreblurEnabled ) \ - NRD_CONSTANTS_END #else + #if( defined REBLUR_PROVIDED_CONFIDENCE ) #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecConfidence, t, 6 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecConfidence, t, 8 ) #else #define EXTRA_INPUTS #endif @@ -103,9 +78,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ObjectMotion, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_History_Spec, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_DiffAccumSpeed, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Normal_SpecAccumSpeed, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Roughness, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 6 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_History_Spec, t, 7 ) \ EXTRA_INPUTS #define NRD_DECLARE_OUTPUT_TEXTURES \ @@ -114,22 +91,24 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Error, u, 2 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 3 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToViewPrev ) \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4x4, gWorldToClip ) \ - NRD_CONSTANT( float4, gFrustumPrev ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ - NRD_CONSTANT( float, gDisocclusionThreshold ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( uint, gPreblurEnabled ) \ - NRD_CONSTANTS_END #endif +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float4x4, gWorldToViewPrev ) \ + NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ + NRD_CONSTANT( float4x4, gViewToWorld ) \ + NRD_CONSTANT( float4x4, gWorldToClip ) \ + NRD_CONSTANT( float4, gFrustumPrev ) \ + NRD_CONSTANT( float4, gCameraDelta ) \ + NRD_CONSTANT( float2, gMotionVectorScale ) \ + NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ + NRD_CONSTANT( float, gDisocclusionThreshold ) \ + NRD_CONSTANT( uint, gDiffCheckerboard ) \ + NRD_CONSTANT( uint, gSpecCheckerboard ) \ + NRD_CONSTANT( uint, gPreblurEnabled ) \ + NRD_CONSTANTS_END + #define NRD_DECLARE_SAMPLERS \ NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli similarity index 79% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli index 0097c53..24e31b8 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -58,19 +58,22 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float viewZ = s_ViewZ[ smemPos.y ][ smemPos.x ]; [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) { - gOut_ViewZ_Normal_Roughness_AccumSpeeds[ pixelPos ] = PackViewZNormalRoughnessAccumSpeeds( NRD_INF, 0.0, float3( 0, 0, 1 ), 1.0, 0.0 ); + gOut_ViewZ_DiffAccumSpeed[ pixelPos ] = PackViewZAccumSpeed( NRD_INF, 0.0 ); + gOut_Normal_SpecAccumSpeed[ pixelPos ] = PackNormalAccumSpeedMaterialID( float3( 0, 0, 1 ), 0.0, 0 ); + // gOut_Roughness is not used return; } // Normal and roughness - float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ] ); + float materialID; + float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ], materialID ); float3 N = normalAndRoughness.xyz; float roughness = normalAndRoughness.w; // Position - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); float3 X = STL::Geometry::AffineTransform( gViewToWorld, Xv ); // Anti-firefly ( not needed for hit distance ) @@ -161,17 +164,17 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Compute previous pixel position offseti -= BORDER; float2 offset = float2( offseti ) * gInvRectSize; - float3 Xvnearest = STL::Geometry::ReconstructViewPosition( pixelUv + offset, gFrustum, viewZnearest, gIsOrtho ); + float3 Xvnearest = STL::Geometry::ReconstructViewPosition( pixelUv + offset, gFrustum, viewZnearest, gOrthoMode ); float3 Xnearest = STL::Geometry::AffineTransform( gViewToWorld, Xvnearest ); float3 motionVector = gIn_ObjectMotion[ pixelPosUser + offseti ] * gMotionVectorScale.xyy; - float2 pixelUvPrev = STL::Geometry::GetPrevUvFromMotion( pixelUv + offset, Xnearest, gWorldToClipPrev, motionVector, gWorldSpaceMotion ); + float2 pixelUvPrev = STL::Geometry::GetPrevUvFromMotion( pixelUv + offset, Xnearest, gWorldToClipPrev, motionVector, gIsWorldSpaceMotionEnabled ); pixelUvPrev -= offset; float isInScreen = IsInScreen2x2( pixelUvPrev, gRectSizePrev ); - float3 Xprev = X + motionVector * float( gWorldSpaceMotion != 0 ); + float3 Xprev = X + motionVector * float( gIsWorldSpaceMotionEnabled != 0 ); // Compute parallax - float parallax = ComputeParallax( X, Xprev, gCameraDelta ); + float parallax = ComputeParallax( X, Xprev, gCameraDelta, gOrthoMode != 0 ); // Internal data float curvature; @@ -182,7 +185,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float4 error = gIn_Error[ pixelPos ]; float virtualHistoryAmount = error.y; - float2 occlusionAvg = float2( ( bits & uint2( 8, 16 ) ) != 0 ); + float2 isCatRomAllowed = float2( ( bits & uint2( 8, 16 ) ) != 0 ); STL::Filtering::Bilinear bilinearFilterAtPrevPos = STL::Filtering::GetBilinearFilter( saturate( pixelUvPrev ), gRectSizePrev ); float4 bilinearWeightsWithOcclusion = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevPos, 1.0 ); @@ -193,26 +196,27 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float4 diffHistory = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_HistoryStabilized_Diff, gIn_HistoryStabilized_Spec, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - bilinearWeightsWithOcclusion, occlusionAvg.x == 1.0 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS, + bilinearWeightsWithOcclusion, isCatRomAllowed.x == 1.0 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS, specHistorySurface ); #elif( defined REBLUR_DIFFUSE ) float4 diffHistory = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_HistoryStabilized_Diff, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - bilinearWeightsWithOcclusion, occlusionAvg.x == 1.0 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS + bilinearWeightsWithOcclusion, isCatRomAllowed.x == 1.0 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS ); #else float4 specHistorySurface = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_HistoryStabilized_Spec, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - bilinearWeightsWithOcclusion, occlusionAvg.x == 1.0 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS + bilinearWeightsWithOcclusion, isCatRomAllowed.x == 1.0 && REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TS ); #endif + // Diffuse #if( defined REBLUR_DIFFUSE ) // Antilag - float diffAntilag = ComputeAntilagScale( diffInternalData.y, diffHistory, diff, diffM1, diffSigma, gDiffAntilag1, gDiffAntilag2, curvature ); + float diffAntilag = ComputeAntilagScale( diffInternalData.y, diffHistory, diff, diffM1, diffSigma, gAntilagMinMaxThreshold, gAntilagSigmaScale, curvature ); float diffMipScale = lerp( 0.0, 1.0, REBLUR_USE_ANTILAG_NOT_INVOKING_HISTORY_FIX ); float diffMinAccumSpeed = min( diffInternalData.y, GetMipLevel( 1.0 ) * diffMipScale ); @@ -226,7 +230,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float diffHistoryWeight = ( gFramerateScale * REBLUR_TS_ACCUM_TIME ) / ( 1.0 + gFramerateScale * REBLUR_TS_ACCUM_TIME ); diffHistoryWeight *= diffTemporalAccumulationParams.x; - diffHistoryWeight *= gDiffStabilizationStrength; + diffHistoryWeight *= gStabilizationStrength; diffHistoryWeight = 1.0 - diffHistoryWeight; #if( REBLUR_DEBUG_SPATIAL_DENSITY_CHECK == 1 ) diffHistoryWeight = 1.0; @@ -239,12 +243,8 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #if( REBLUR_DEBUG != 0 ) uint diffMode = REBLUR_DEBUG; if( diffMode == 1 ) // Accumulated frame num - diffResult.w = saturate( diffInternalData.y / ( gDiffMaxAccumulatedFrameNum + 1.0 ) ); - else if( diffMode == 2 ) // Curvature magnitude - diffResult.w = abs( curvature ); - else if( diffMode == 3 ) // Curvature sign - diffResult.w = curvature < 0 ? 1 : 0; - else if( diffMode == 4 ) // Error + diffResult.w = saturate( diffInternalData.y / ( gMaxAccumulatedFrameNum + 1.0 ) ); + else if( diffMode == 2 ) // Error diffResult.w = error.x; diffResult.xyz = STL::Color::ColorizeZucconi( diffResult.w ); @@ -253,22 +253,23 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Output gOut_Diff[ pixelPos ] = diffResult; #endif + gOut_ViewZ_DiffAccumSpeed[ pixelPos ] = PackViewZAccumSpeed( viewZ, diffInternalData.y ); + // Specular #if( defined REBLUR_SPECULAR ) + gOut_Roughness[ pixelPos ] = roughness; + // Current hit distance - float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gSpecHitDistParams, roughness ); + float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gHitDistParams, roughness ); float hitDist = spec.w * hitDistScale; - // Parallax correction - float invFrustumHeight = STL::Math::PositiveRcp( PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ) ); - float hitDistFactor = saturate( hitDist * invFrustumHeight ); - parallax *= hitDistFactor; - // Sample virtual history float3 V = GetViewVector( X ); float NoV = abs( dot( N, V ) ); - float4 Xvirtual = GetXvirtual( X, V, NoV, roughness, hitDist, viewZ, curvature ); - float2 pixelUvVirtualPrev = STL::Geometry::GetScreenUv( gWorldToClipPrev, Xvirtual.xyz, false ); + float pixelSize = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); + float realCurvature = GetRealCurvature( curvature, pixelSize, NoV ); + float3 Xvirtual = GetXvirtual( X, Xprev, V, NoV, roughness, hitDist, realCurvature ); + float2 pixelUvVirtualPrev = STL::Geometry::GetScreenUv( gWorldToClipPrev, Xvirtual, false ); STL::Filtering::Bilinear bilinearFilterAtPrevVirtualPos = STL::Filtering::GetBilinearFilter( saturate( pixelUvVirtualPrev ), gRectSizePrev ); float4 bilinearWeightsWithOcclusionVirtual = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevVirtualPos, 1.0 ); @@ -276,32 +277,42 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float4 specHistoryVirtual = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_HistoryStabilized_Spec, gLinearClamp, saturate( pixelUvVirtualPrev ) * gRectSizePrev, gInvScreenSize, - bilinearWeightsWithOcclusionVirtual, occlusionAvg.y == 1.0 && REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS + bilinearWeightsWithOcclusionVirtual, isCatRomAllowed.y == 1.0 && REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TS ); + // Parallax correction + float parallaxVirtual = ComputeParallax( Xvirtual, Xvirtual, gCameraDelta, gOrthoMode != 0 ); + float smc = GetSpecMagicCurve( roughness ); + parallax = max( parallax, parallaxVirtual * ( 1.0 - smc ) ); + + float invFrustumHeight = 1.0 / PixelRadiusToWorld( gUnproject, gOrthoMode, gRectSize.y, viewZ );; + float hitDistFactor = saturate( hitDist * invFrustumHeight ); + parallax *= hitDistFactor; + // Virtual motion - hit distance similarity - float hitDistVirtual = specHistoryVirtual.w * hitDistScale; - float hitDistDelta = abs( hitDistVirtual - hitDist ); // TODO: sigma can worsen! useful for high roughness only? - float hitDistMax = max( hitDistVirtual, hitDist ); + float hitDistFocused = ApplyThinLensEquation( hitDist, realCurvature ); + float hitDistVirtualFocused = ApplyThinLensEquation( specHistoryVirtual.w * hitDistScale, realCurvature ); + float hitDistDelta = abs( hitDistVirtualFocused - hitDistFocused ); // TODO: sigma can worsen! useful for high roughness only? + float hitDistMax = max( hitDistVirtualFocused, hitDistFocused ); hitDistDelta *= STL::Math::PositiveRcp( hitDistMax + viewZ ); float virtualHistoryHitDistConfidence = 1.0 - STL::Math::SmoothStep( 0.0, 0.25, STL::Math::Sqrt01( hitDistDelta ) * SaturateParallax( parallax * REBLUR_TS_SIGMA_AMPLITUDE ) ); - virtualHistoryHitDistConfidence = lerp( 1.0, virtualHistoryHitDistConfidence, Xvirtual.w ); float virtualHistoryConfidence = error.w; virtualHistoryConfidence *= virtualHistoryHitDistConfidence; // Virtual history clamping - float smc = GetSpecMagicCurve( roughness ); + float responsiveAccumulationAmount = GetResponsiveAccumulationAmount( roughness ); float sigmaScale = lerp( 1.0, 3.0, smc ) + smc * gFramerateScale * virtualHistoryConfidence; float4 specHistoryVirtualClamped = STL::Color::Clamp( specM1, specSigma * sigmaScale, specHistoryVirtual ); float unclampedVirtualHistoryAmount = lerp( virtualHistoryConfidence, 1.0, smc * STL::Math::SmoothStep( 0.2, 0.4, roughness ) ); + unclampedVirtualHistoryAmount *= lerp( 1.0, smc * 0.5 + 0.5, responsiveAccumulationAmount ); float4 specHistoryVirtualMixed = lerp( specHistoryVirtualClamped, specHistoryVirtual, unclampedVirtualHistoryAmount ); // Combine surface and virtual motion float4 specHistory = MixSurfaceAndVirtualMotion( specHistorySurface, specHistoryVirtualMixed, virtualHistoryAmount, hitDistFactor ); // Antilag - float specAntilag = ComputeAntilagScale( specInternalData.y, specHistory, spec, specM1, specSigma, gSpecAntilag1, gSpecAntilag2, curvature, roughness ); + float specAntilag = ComputeAntilagScale( specInternalData.y, specHistory, spec, specM1, specSigma, gAntilagMinMaxThreshold, gAntilagSigmaScale, curvature, roughness ); float specMipScale = lerp( 1.0 - virtualHistoryConfidence, 1.0, REBLUR_USE_ANTILAG_NOT_INVOKING_HISTORY_FIX ); float specMinAccumSpeed = min( specInternalData.y, GetMipLevel( roughness ) * specMipScale ); @@ -315,7 +326,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float specHistoryWeight = ( gFramerateScale * REBLUR_TS_ACCUM_TIME ) / ( 1.0 + gFramerateScale * REBLUR_TS_ACCUM_TIME ); specHistoryWeight *= specTemporalAccumulationParams.x; - specHistoryWeight *= gSpecStabilizationStrength; + specHistoryWeight *= gStabilizationStrength; specHistoryWeight = 1.0 - specHistoryWeight; #if( REBLUR_DEBUG_SPATIAL_DENSITY_CHECK == 1 ) specHistoryWeight = 1.0; @@ -328,13 +339,13 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #if( REBLUR_DEBUG != 0 ) uint specMode = REBLUR_DEBUG; if( specMode == 1 ) // Accumulated frame num - specResult.w = saturate( specInternalData.y / ( gSpecMaxAccumulatedFrameNum + 1.0 ) ); - else if( specMode == 2 ) // Curvature magnitude + specResult.w = saturate( specInternalData.y / ( gMaxAccumulatedFrameNum + 1.0 ) ); + else if( specMode == 2 ) // Error + specResult.w = error.z; + else if( specMode == 3 ) // Curvature magnitude specResult.w = abs( curvature ); - else if( specMode == 3 ) // Curvature sign + else if( specMode == 4 ) // Curvature sign specResult.w = curvature < 0 ? 1 : 0; - else if( specMode == 4 ) // Error - specResult.w = error.z; else if( specMode == 5 ) // Virtual history amount specResult.w = virtualHistoryAmount; else if( specMode == 6 ) // Virtual history confidence @@ -349,13 +360,5 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Output gOut_Spec[ pixelPos ] = specResult; #endif - - // Output - #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - gOut_ViewZ_Normal_Roughness_AccumSpeeds[ pixelPos ] = PackViewZNormalRoughnessAccumSpeeds( viewZ, diffInternalData.y, N, roughness, specInternalData.y ); - #elif( defined REBLUR_DIFFUSE ) - gOut_ViewZ_Normal_Roughness_AccumSpeeds[ pixelPos ] = PackViewZNormalRoughnessAccumSpeeds( viewZ, diffInternalData.y, N, 1.0, 0.0 ); - #else - gOut_ViewZ_Normal_Roughness_AccumSpeeds[ pixelPos ] = PackViewZNormalRoughnessAccumSpeeds( viewZ, 0.0, N, roughness, specInternalData.y ); - #endif + gOut_Normal_SpecAccumSpeed[ pixelPos ] = PackNormalAccumSpeedMaterialID( N, specInternalData.y, materialID ); } diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli similarity index 52% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli index 2b278c2..d8171fc 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.resources.hlsli @@ -11,6 +11,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "REBLUR_Config.hlsli" #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ @@ -23,26 +24,14 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 8 ) #define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_Normal_Roughness_AccumSpeeds, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float4, gDiffAntilag1 ) \ - NRD_CONSTANT( float4, gDiffAntilag2 ) \ - NRD_CONSTANT( float4, gSpecAntilag1 ) \ - NRD_CONSTANT( float4, gSpecAntilag2 ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gDiffStabilizationStrength ) \ - NRD_CONSTANT( float, gSpecStabilizationStrength ) \ - NRD_CONSTANTS_END + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_DiffAccumSpeed, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Normal_SpecAccumSpeed, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Roughness, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 3 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 4 ) #elif( defined REBLUR_DIFFUSE ) + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ @@ -53,22 +42,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 6 ) #define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_Normal_Roughness_AccumSpeeds, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float4, gDiffAntilag1 ) \ - NRD_CONSTANT( float4, gDiffAntilag2 ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gDiffStabilizationStrength ) \ - NRD_CONSTANTS_END + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_DiffAccumSpeed, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Normal_SpecAccumSpeed, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 2 ) #else + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ @@ -79,22 +58,24 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 6 ) #define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_Normal_Roughness_AccumSpeeds, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float4, gSpecAntilag1 ) \ - NRD_CONSTANT( float4, gSpecAntilag2 ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gSpecStabilizationStrength ) \ - NRD_CONSTANTS_END + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_DiffAccumSpeed, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Normal_SpecAccumSpeed, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Roughness, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 3 ) #endif +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ + NRD_CONSTANT( float4x4, gViewToWorld ) \ + NRD_CONSTANT( float4, gCameraDelta ) \ + NRD_CONSTANT( float4, gAntilagMinMaxThreshold ) \ + NRD_CONSTANT( float2, gAntilagSigmaScale ) \ + NRD_CONSTANT( float2, gMotionVectorScale ) \ + NRD_CONSTANT( float, gStabilizationStrength ) \ + NRD_CONSTANTS_END + #define NRD_DECLARE_SAMPLERS \ NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli similarity index 90% rename from Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli index e8f6cbb..50d2369 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecularOcclusion_Blur.resources.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -41,11 +41,11 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #endif [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) return; // Normal and roughness - uint materialID; + float materialID; float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ], materialID ); float3 N = normalAndRoughness.xyz; float3 Nv = STL::Geometry::RotateVector( gWorldToView, N ); @@ -58,25 +58,25 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 specInternalData = internalData.zw; // Shared data - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); float4 rotator = GetBlurKernelRotation( REBLUR_BLUR_ROTATOR_MODE, pixelPos, gRotator, gFrameIndex ); float4 error = gInOut_Error[ pixelPos ]; - // Spatial filtering + // Spatial filtering (spec first - seems to work faster) #define REBLUR_SPATIAL_MODE REBLUR_BLUR - #if( defined REBLUR_DIFFUSE ) - float diff = diffData.x; - - #include "REBLUR_Common_DiffuseOcclusionSpatialFilter.hlsli" - #endif - #if( defined REBLUR_SPECULAR ) float spec = specData.x; #include "REBLUR_Common_SpecularOcclusionSpatialFilter.hlsli" #endif + #if( defined REBLUR_DIFFUSE ) + float diff = diffData.x; + + #include "REBLUR_Common_DiffuseOcclusionSpatialFilter.hlsli" + #endif + // Output gInOut_Error[ pixelPos ] = error; } diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.resources.hlsli new file mode 100644 index 0000000..c2ba256 --- /dev/null +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.resources.hlsli @@ -0,0 +1,60 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "REBLUR_Config.hlsli" + +#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) + +#elif( defined REBLUR_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) + +#else + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) + +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float4x4, gWorldToView ) \ + NRD_CONSTANT( float4, gRotator ) \ + NRD_CONSTANT( float3, gSpecLobeTrimmingParams ) \ + NRD_CONSTANT( float, gBlurRadiusScale ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli similarity index 81% rename from Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli index 9a9c350..f5dcd0e 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecularOcclusion_HistoryFix.resources.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -42,7 +42,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #endif [branch] - if( scaledViewZ / NRD_FP16_VIEWZ_SCALE > gInf ) + if( scaledViewZ / NRD_FP16_VIEWZ_SCALE > gDenoisingRange || REBLUR_USE_HISTORY_FIX == 0 ) return; // Internal data @@ -52,14 +52,14 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 diffInternalData = internalData.xy; float2 specInternalData = internalData.zw; - // History reconstruction + // History reconstruction // materialID support? migrate to 5x5 filter? #if( defined REBLUR_DIFFUSE ) - float diffMipLevel = GetMipLevel( 1.0 ) * gDiffHistoryFixStrength; + float diffMipLevel = GetMipLevel( 1.0 ) * gHistoryFixStrength; ReconstructHistory( diffData.x, diffData.y, diffInternalData.y, diffMipLevel, pixelPos, pixelUv, gOut_Diff, gIn_Diff ); #endif #if( defined REBLUR_SPECULAR ) - float specMipLevel = float( bits & 7 ) * gSpecHistoryFixStrength; + float specMipLevel = float( bits & 7 ) * gHistoryFixStrength; ReconstructHistory( specData.x, specData.y, specInternalData.y, specMipLevel, pixelPos, pixelUv, gOut_Spec, gIn_Spec ); #endif } diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_HistoryFix.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.resources.hlsli similarity index 71% rename from Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_HistoryFix.resources.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.resources.hlsli index ccbb542..36c4521 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_HistoryFix.resources.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.resources.hlsli @@ -11,6 +11,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "REBLUR_Config.hlsli" #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) \ @@ -20,13 +21,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDiffHistoryFixStrength ) \ - NRD_CONSTANT( float, gSpecHistoryFixStrength ) \ - NRD_CONSTANTS_END #elif( defined REBLUR_DIFFUSE ) + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) @@ -34,12 +30,8 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDiffHistoryFixStrength ) \ - NRD_CONSTANTS_END #else + #define NRD_DECLARE_INPUT_TEXTURES \ NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 1 ) @@ -47,12 +39,13 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float, gSpecHistoryFixStrength ) \ - NRD_CONSTANTS_END #endif +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float, gHistoryFixStrength ) \ + NRD_CONSTANTS_END + #define NRD_DECLARE_SAMPLERS \ NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli similarity index 78% rename from Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli index e93df37..f0aadb0 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecularOcclusion_PostBlur.resources.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -41,11 +41,11 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #endif [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) return; // Normal and roughness - uint materialID; + float materialID; float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ], materialID ); float3 N = normalAndRoughness.xyz; float3 Nv = STL::Geometry::RotateVector( gWorldToView, N ); @@ -58,16 +58,15 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 specInternalData = internalData.zw; // Output - #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - gOut_ViewZ_Normal_Roughness_AccumSpeeds[ pixelPos ] = PackViewZNormalRoughnessAccumSpeeds( viewZ, diffInternalData.y, N, roughness, specInternalData.y ); - #elif( defined REBLUR_DIFFUSE ) - gOut_ViewZ_Normal_Roughness_AccumSpeeds[ pixelPos ] = PackViewZNormalRoughnessAccumSpeeds( viewZ, diffInternalData.y, N, 1.0, 0.0 ); - #else - gOut_ViewZ_Normal_Roughness_AccumSpeeds[ pixelPos ] = PackViewZNormalRoughnessAccumSpeeds( viewZ, 0.0, N, roughness, specInternalData.y ); + gOut_ViewZ_DiffAccumSpeed[ pixelPos ] = PackViewZAccumSpeed( viewZ, diffInternalData.y ); + gOut_Normal_SpecAccumSpeed[ pixelPos ] = PackNormalAccumSpeedMaterialID( N, specInternalData.y, materialID ); + + #if( defined REBLUR_SPECULAR ) + gOut_Roughness[ pixelPos ] = roughness; #endif // Shared data - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); float4 rotator = GetBlurKernelRotation( REBLUR_POST_BLUR_ROTATOR_MODE, pixelPos, gRotator, gFrameIndex ); float4 error = gInOut_Error[ pixelPos ]; diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.resources.hlsli new file mode 100644 index 0000000..448ac5d --- /dev/null +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.resources.hlsli @@ -0,0 +1,68 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "REBLUR_Config.hlsli" + +#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_DiffAccumSpeed, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Normal_SpecAccumSpeed, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Roughness, u, 3 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 4 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 5 ) + +#elif( defined REBLUR_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_DiffAccumSpeed, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Normal_SpecAccumSpeed, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 3 ) + +#else + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_DiffAccumSpeed, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Normal_SpecAccumSpeed, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Roughness, u, 3 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 4 ) + +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float4x4, gWorldToView ) \ + NRD_CONSTANT( float4, gRotator ) \ + NRD_CONSTANT( float3, gSpecLobeTrimmingParams ) \ + NRD_CONSTANT( float, gBlurRadiusScale ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli similarity index 83% rename from Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli index 9c4330d..28193e9 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecularOcclusion_SplitScreen.resources.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -36,12 +36,12 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 pixelPos : SV_DispatchThreadId) #if( defined REBLUR_DIFFUSE ) checkerboardPos.x = pixelPos.x >> ( gDiffCheckerboard != 2 ? 1 : 0 ); float diffResult = gIn_Diff[ gRectOrigin + checkerboardPos ]; - gOut_Diff[ pixelPos ] = diffResult * float( viewZ < gInf ); + gOut_Diff[ pixelPos ] = diffResult * float( viewZ < gDenoisingRange ); #endif #if( defined REBLUR_SPECULAR ) checkerboardPos.x = pixelPos.x >> ( gSpecCheckerboard != 2 ? 1 : 0 ); float specResult = gIn_Spec[ gRectOrigin + checkerboardPos ]; - gOut_Spec[ pixelPos ] = specResult * float( viewZ < gInf ); + gOut_Spec[ pixelPos ] = specResult * float( viewZ < gDenoisingRange ); #endif } diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_SplitScreen.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.resources.hlsli similarity index 50% rename from Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_SplitScreen.resources.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.resources.hlsli index 2a52f2c..e7d07d7 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_SplitScreen.resources.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.resources.hlsli @@ -11,55 +11,43 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "REBLUR_Config.hlsli" #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - #define EXTRA_INPUTS \ + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) - #define EXTRA_OUTPUTS \ + #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( float, gSplitScreen ) \ - NRD_CONSTANTS_END #elif( defined REBLUR_DIFFUSE ) - #define EXTRA_INPUTS \ + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( float, gSplitScreen ) \ - NRD_CONSTANTS_END #else - #define EXTRA_INPUTS \ + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 1 ) - #define EXTRA_OUTPUTS \ + #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( float, gSplitScreen ) \ - NRD_CONSTANTS_END #endif -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ - EXTRA_INPUTS - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - EXTRA_OUTPUTS +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float, gSplitScreen ) \ + NRD_CONSTANT( uint, gDiffCheckerboard ) \ + NRD_CONSTANT( uint, gSpecCheckerboard ) \ + NRD_CONSTANTS_END #define NRD_DECLARE_SAMPLERS \ NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli similarity index 56% rename from Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli index 66e802b..68eb8e5 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli @@ -10,13 +10,16 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.resources.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.resources.hlsli" NRD_DECLARE_CONSTANTS #if( defined REBLUR_SPECULAR ) #define NRD_CTA_8X8 - #define NRD_USE_BORDER_2 + + #if( REBLUR_USE_5X5_HISTORY_CLAMPING == 1 ) + #define NRD_USE_BORDER_2 + #endif #endif #include "NRD_Common.hlsli" @@ -33,7 +36,7 @@ void Preload( uint2 sharedPos, int2 globalPos ) { globalPos = clamp( globalPos, 0, gRectSize - 1.0 ); - s_Normal_Roughness[ sharedPos.y ][ sharedPos.x ] = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ gRectOrigin + globalPos ] ); + s_Normal[ sharedPos.y ][ sharedPos.x ] = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ gRectOrigin + globalPos ] ).xyz; #if( defined REBLUR_SPECULAR ) globalPos.x >>= gSpecCheckerboard != 2 ? 1 : 0; @@ -50,12 +53,18 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : PRELOAD_INTO_SMEM; + // Normal and roughness + float materialID; + float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ], materialID ); + float3 N = normalAndRoughness.xyz; + float roughness = normalAndRoughness.w; + // Early out float viewZ = abs( gIn_ViewZ[ pixelPosUser ] ); float scaledViewZ = min( viewZ * NRD_FP16_VIEWZ_SCALE, NRD_FP16_MAX ); [branch] - if( viewZ > gInf ) + if( viewZ > gDenoisingRange ) { #if( defined REBLUR_DIFFUSE ) gOut_Diff[ pixelPos ] = float2( 0, scaledViewZ ); @@ -68,17 +77,13 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : return; } - // Normal and roughness - int2 smemPos = threadPos + BORDER; - float4 normalAndRoughness = s_Normal_Roughness[ smemPos.y ][ smemPos.x ]; - float3 N = normalAndRoughness.xyz; - float roughness = normalAndRoughness.w; - // Current position - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); float3 X = STL::Geometry::AffineTransform( gViewToWorld, Xv ); // Calculate distribution of normals + int2 smemPos = threadPos + BORDER; + #if( defined REBLUR_SPECULAR ) float spec = s_Spec[ smemPos.y ][ smemPos.x ]; float specM1 = spec; @@ -117,11 +122,12 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 d = float2( dx, dy ) - BORDER; if( all( abs( d ) <= 1 ) ) // only in 3x3 { - float3 n = s_Normal_Roughness[ pos.y ][ pos.x ].xyz; - Nflat += n; + float3 n = s_Normal[ pos.y ][ pos.x ]; + Nflat += n; - float3 pv = STL::Geometry::ReconstructViewPosition( pixelUv + d * gInvRectSize, gFrustum, 1.0, gIsOrtho ); - float3 v = STL::Geometry::RotateVector( gViewToWorld, normalize( -pv ) ); + float3 xv = STL::Geometry::ReconstructViewPosition( pixelUv + d * gInvRectSize, gFrustum, 1.0, gOrthoMode ); + float3 x = STL::Geometry::AffineTransform( gViewToWorld, xv ); + float3 v = GetViewVector( x ); float c = EstimateCurvature( n, v, N, X ); float w = exp2( -0.5 * STL::Math::LengthSquared( d ) ); @@ -136,8 +142,6 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : } float3 Navg = Nflat / 9.0; - float flatness = STL::Math::SmoothStep( 0.985, 1.0, length( Navg ) ); - Nflat = normalize( Nflat ); #if( defined REBLUR_SPECULAR ) @@ -147,53 +151,53 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float specSigma = GetStdDev( specM1, specM2 ); minHitDist5x5 = min( minHitDist5x5, minHitDist3x3 ); - curvature /= curvatureSum; - // Mitigate imprecision problems - curvature *= STL::Math::LinearStep( 0.0, NRD_ENCODING_ERRORS.y + 1e-5, abs( curvature ) ); + curvature /= curvatureSum; + curvature *= STL::Math::LinearStep( 0.0, NRD_ENCODING_ERRORS.y, abs( curvature ) ); float roughnessModified = STL::Filtering::GetModifiedRoughnessFromNormalVariance( roughness, Navg ); #endif // Previous position for surface motion float3 motionVector = gIn_ObjectMotion[ pixelPosUser ] * gMotionVectorScale.xyy; // TODO: use nearest MV - float2 pixelUvPrev = STL::Geometry::GetPrevUvFromMotion( pixelUv, X, gWorldToClipPrev, motionVector, gWorldSpaceMotion ); + float2 pixelUvPrev = STL::Geometry::GetPrevUvFromMotion( pixelUv, X, gWorldToClipPrev, motionVector, gIsWorldSpaceMotionEnabled ); float isInScreen = IsInScreen2x2( pixelUvPrev, gRectSizePrev ); - float3 Xprev = X + motionVector * float( gWorldSpaceMotion != 0 ); + float3 Xprev = X + motionVector * float( gIsWorldSpaceMotionEnabled != 0 ); // Previous data ( 4x4, surface motion ) STL::Filtering::CatmullRom catmullRomFilterAtPrevPos = STL::Filtering::GetCatmullRomFilter( saturate( pixelUvPrev ), gRectSizePrev ); float2 catmullRomFilterAtPrevPosGatherOrigin = catmullRomFilterAtPrevPos.origin * gInvScreenSize; - uint4 prevPackRed0 = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 1, 1 ) ).wzxy; - uint4 prevPackRed1 = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 3, 1 ) ).wzxy; - uint4 prevPackRed2 = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 1, 3 ) ).wzxy; - uint4 prevPackRed3 = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 3, 3 ) ).wzxy; + uint4 packedPrevViewZDiffAccumSpeed0 = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 1, 1 ) ).wzxy; + uint4 packedPrevViewZDiffAccumSpeed1 = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 3, 1 ) ).wzxy; + uint4 packedPrevViewZDiffAccumSpeed2 = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 1, 3 ) ).wzxy; + uint4 packedPrevViewZDiffAccumSpeed3 = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, catmullRomFilterAtPrevPosGatherOrigin, float2( 3, 3 ) ).wzxy; - float4 prevViewZ0 = UnpackViewZ( prevPackRed0 ); - float4 prevViewZ1 = UnpackViewZ( prevPackRed1 ); - float4 prevViewZ2 = UnpackViewZ( prevPackRed2 ); - float4 prevViewZ3 = UnpackViewZ( prevPackRed3 ); + float4 prevViewZ0 = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeed0 ); + float4 prevViewZ1 = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeed1 ); + float4 prevViewZ2 = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeed2 ); + float4 prevViewZ3 = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeed3 ); - // TODO: 4x4 normal checks are reduced to 2x2 footprint only ( missed samples are covered by an additional 3x3 edge check ) + #if( defined REBLUR_DIFFUSE ) + float4 diffPrevAccumSpeeds = UnpackDiffAccumSpeed( uint4( packedPrevViewZDiffAccumSpeed0.w, packedPrevViewZDiffAccumSpeed1.z, packedPrevViewZDiffAccumSpeed2.y, packedPrevViewZDiffAccumSpeed3.x ) ); + #endif + + // TODO: 4x4 normals and materialID are reduced to 2x2 only STL::Filtering::Bilinear bilinearFilterAtPrevPos = STL::Filtering::GetBilinearFilter( saturate( pixelUvPrev ), gRectSizePrev ); float2 bilinearFilterAtPrevPosGatherOrigin = ( bilinearFilterAtPrevPos.origin + 1.0 ) * gInvScreenSize; - uint4 prevPackGreen = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherGreen( gNearestClamp, bilinearFilterAtPrevPosGatherOrigin ).wzxy; + uint4 packedPrevNormalSpecAccumSpeed = gIn_Prev_Normal_SpecAccumSpeed.GatherRed( gNearestClamp, bilinearFilterAtPrevPosGatherOrigin ).wzxy; + float4 prevMaterialIDs; float4 specPrevAccumSpeeds; - float3 prevNormal00 = UnpackNormalRoughnessSpecAccumSpeed( prevPackGreen.x, specPrevAccumSpeeds.x ).xyz; - float3 prevNormal10 = UnpackNormalRoughnessSpecAccumSpeed( prevPackGreen.y, specPrevAccumSpeeds.y ).xyz; - float3 prevNormal01 = UnpackNormalRoughnessSpecAccumSpeed( prevPackGreen.z, specPrevAccumSpeeds.z ).xyz; - float3 prevNormal11 = UnpackNormalRoughnessSpecAccumSpeed( prevPackGreen.w, specPrevAccumSpeeds.w ).xyz; - - #if( defined REBLUR_DIFFUSE ) - float4 diffPrevAccumSpeeds = UnpackDiffAccumSpeed( uint4( prevPackRed0.w, prevPackRed1.z, prevPackRed2.y, prevPackRed3.x ) ); - #endif + float3 prevNormal00 = UnpackPrevNormalAccumSpeedMaterialID( packedPrevNormalSpecAccumSpeed.x, specPrevAccumSpeeds.x, prevMaterialIDs.x ); + float3 prevNormal10 = UnpackPrevNormalAccumSpeedMaterialID( packedPrevNormalSpecAccumSpeed.y, specPrevAccumSpeeds.y, prevMaterialIDs.y ); + float3 prevNormal01 = UnpackPrevNormalAccumSpeedMaterialID( packedPrevNormalSpecAccumSpeed.z, specPrevAccumSpeeds.z, prevMaterialIDs.z ); + float3 prevNormal11 = UnpackPrevNormalAccumSpeedMaterialID( packedPrevNormalSpecAccumSpeed.w, specPrevAccumSpeeds.w, prevMaterialIDs.w ); // Plane distance based disocclusion for surface motion float3 V = GetViewVector( X ); - float invFrustumHeight = STL::Math::PositiveRcp( PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ) ); + float invFrustumHeight = 1.0 / PixelRadiusToWorld( gUnproject, gOrthoMode, gRectSize.y, viewZ ); float3 prevNflatUnnormalized = prevNormal00 + prevNormal10 + prevNormal01 + prevNormal11; - float disocclusionThreshold = GetDisocclusionThreshold( gDisocclusionThreshold, gJitterDelta, viewZ, Nflat, V ); + float disocclusionThreshold = GetDisocclusionThreshold( gDisocclusionThreshold, viewZ, Nflat, V ); disocclusionThreshold = lerp( -1.0, disocclusionThreshold, isInScreen ); // out-of-screen = occlusion float3 Xvprev = STL::Geometry::AffineTransform( gWorldToViewPrev, Xprev ); float NoXprev1 = abs( dot( Xprev, Nflat ) ); @@ -216,58 +220,72 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : cosa.z = dot( N, prevNormal01 ); cosa.w = dot( N, prevNormal11 ); - float parallax = ComputeParallax( X, Xprev, gCameraDelta ); + float parallax = ComputeParallax( X, Xprev, gCameraDelta, gOrthoMode != 0 ); float cosAngleMin = lerp( -0.95, -0.01, SaturateParallax( parallax ) ); + float mvLength = length( ( pixelUvPrev - pixelUv ) * gRectSize ); float4 frontFacing = STL::Math::LinearStep( cosAngleMin, 0.01, cosa ); + frontFacing = lerp( 1.0, frontFacing, saturate( mvLength / 0.25 ) ); + occlusion0.w *= frontFacing.x; occlusion1.z *= frontFacing.y; occlusion2.y *= frontFacing.z; occlusion3.x *= frontFacing.w; // Avoid "got stuck in history" effect under slow motion when only 1 sample is valid from 2x2 footprint - float4 surfaceOcclusion2x2 = float4( occlusion0.w, occlusion1.z, occlusion2.y, occlusion3.x ); - float footprintQuality = STL::Filtering::ApplyBilinearFilter( surfaceOcclusion2x2.x, surfaceOcclusion2x2.y, surfaceOcclusion2x2.z, surfaceOcclusion2x2.w, bilinearFilterAtPrevPos ); + float footprintQuality = STL::Filtering::ApplyBilinearFilter( occlusion0.w, occlusion1.z, occlusion2.y, occlusion3.x, bilinearFilterAtPrevPos ); + footprintQuality = lerp( 0.5, 1.0, footprintQuality ); // Avoid footprint momentary stretching due to changed viewing angle float3 Vprev = normalize( Xprev - gCameraDelta.xyz ); float VoNflat = abs( dot( Nflat, V ) ) + 1e-3; float VoNflatprev = abs( dot( Nflat, Vprev ) ) + 1e-3; float sizeQuality = VoNflatprev / VoNflat; // this order because we need to fix stretching only, shrinking is OK - footprintQuality *= lerp( 0.1, 1.0, saturate( sizeQuality + abs( gIsOrtho ) ) ); + footprintQuality *= lerp( 0.1, 1.0, saturate( sizeQuality + abs( gOrthoMode ) ) ); - float surfaceOcclusionAvg = step( 15.5, dot( occlusion0 + occlusion1 + occlusion2 + occlusion3, 1.0 ) ) * REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA; + float4 surfaceWeightsWithOcclusion = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevPos, float4( occlusion0.w, occlusion1.z, occlusion2.y, occlusion3.x ) ); + + // Material ID // TODO: needed in "footprintQuality"? + float4 materialCmps = CompareMaterials( materialID, prevMaterialIDs, gDiffMaterialMask | gSpecMaterialMask ); + occlusion0.w *= materialCmps.x; + occlusion1.z *= materialCmps.y; + occlusion2.y *= materialCmps.z; + occlusion3.x *= materialCmps.w; + + float4 surfaceWeightsWithOcclusionAndMaterialID = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevPos, float4( occlusion0.w, occlusion1.z, occlusion2.y, occlusion3.x ) ); // IMPORTANT: CatRom or custom bilinear work as expected when only one is in use. When mixed, a disocclusion event can introduce a switch to // bilinear, which can snap to a single sample according to custom weights. It can introduce a discontinuity in color. In turn CatRom can immediately // react to this and increase local sharpness. Next, if another disocclusion happens, custom bilinear can snap to the sharpened sample again... // This process can continue almost infinitely, blowing up the image due to over sharpenning in a loop. It can be fixed by: // - using camera jittering - // - not using CatRom on edges + // - not using CatRom on edges (current approach) // - computing 4x4 normal weights - surfaceOcclusionAvg *= float( length( Navg ) > 0.65 ); // TODO: 0.85? - - float4 surfaceWeightsWithOcclusion = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevPos, surfaceOcclusion2x2 ); + bool isCatRomAllowedForSurfaceMotion = dot( occlusion0 + occlusion1 + occlusion2 + occlusion3, 1.0 ) > 15.5; + isCatRomAllowedForSurfaceMotion = isCatRomAllowedForSurfaceMotion & ( length( Navg ) > 0.65 ); // TODO: 0.85? + isCatRomAllowedForSurfaceMotion = isCatRomAllowedForSurfaceMotion & REBLUR_USE_CATROM_FOR_SURFACE_MOTION_IN_TA; - float fbits = surfaceOcclusionAvg * 8.0; + float fbits = float( isCatRomAllowedForSurfaceMotion ) * 8.0; // Update accumulation speeds + // IMPORTANT: "Upper bound" is used to control accumulation, while "No confidence" artificially bumps number of accumulated + // frames to skip "HistoryFix" pass. Maybe introduce a bit in "fbits", because current behavior negatively impacts "TS"? #if( defined REBLUR_DIFFUSE ) - float diffMaxAccumSpeed = AdvanceAccumSpeed( diffPrevAccumSpeeds, surfaceWeightsWithOcclusion ); - diffMaxAccumSpeed *= footprintQuality; + float diffMaxAccumSpeedNoConfidence = AdvanceAccumSpeed( diffPrevAccumSpeeds, gDiffMaterialMask ? surfaceWeightsWithOcclusionAndMaterialID : surfaceWeightsWithOcclusion ); + diffMaxAccumSpeedNoConfidence *= footprintQuality; - float diffHistoryConfidence = 1.0; + float diffAccumSpeedUpperBound = diffMaxAccumSpeedNoConfidence; #if( defined REBLUR_PROVIDED_CONFIDENCE ) - diffHistoryConfidence = gIn_DiffConfidence[ pixelPosUser ]; + diffAccumSpeedUpperBound *= gIn_DiffConfidence[ pixelPosUser ]; #endif #endif #if( defined REBLUR_SPECULAR ) - float specMaxAccumSpeed = AdvanceAccumSpeed( specPrevAccumSpeeds, surfaceWeightsWithOcclusion ); - specMaxAccumSpeed *= footprintQuality; + float specMaxAccumSpeedNoConfidence = AdvanceAccumSpeed( specPrevAccumSpeeds, gSpecMaterialMask ? surfaceWeightsWithOcclusionAndMaterialID : surfaceWeightsWithOcclusion ); + specMaxAccumSpeedNoConfidence *= footprintQuality; - float specHistoryConfidence = 1.0; + float specAccumSpeedUpperBound = specMaxAccumSpeedNoConfidence; #if( defined REBLUR_PROVIDED_CONFIDENCE ) - specHistoryConfidence = gIn_SpecConfidence[ pixelPosUser ]; + specAccumSpeedUpperBound *= gIn_SpecConfidence[ pixelPosUser ]; #endif #endif @@ -277,24 +295,23 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float diffHistory = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_History_Diff, gIn_History_Spec, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - surfaceWeightsWithOcclusion, surfaceOcclusionAvg == 1.0, + surfaceWeightsWithOcclusionAndMaterialID, isCatRomAllowedForSurfaceMotion, specHistorySurface ); #elif( defined REBLUR_DIFFUSE ) float diffHistory = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_History_Diff, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - surfaceWeightsWithOcclusion, surfaceOcclusionAvg == 1.0 + surfaceWeightsWithOcclusionAndMaterialID, isCatRomAllowedForSurfaceMotion ); #else float specHistorySurface = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_History_Spec, gLinearClamp, saturate( pixelUvPrev ) * gRectSizePrev, gInvScreenSize, - surfaceWeightsWithOcclusion, surfaceOcclusionAvg == 1.0 + surfaceWeightsWithOcclusionAndMaterialID, isCatRomAllowedForSurfaceMotion ); #endif - // Noisy signal with checkerboard reconstruction uint checkerboard = STL::Sequence::CheckerBoard( pixelPos, gFrameIndex ); int3 checkerboardPos = pixelPosUser.xyx + int3( -1, 0, 1 ); float viewZ0 = gIn_ViewZ[ checkerboardPos.xy ]; @@ -302,7 +319,9 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float2 neighboorWeight = GetBilateralWeight( float2( viewZ0, viewZ1 ), viewZ ); neighboorWeight *= STL::Math::PositiveRcp( neighboorWeight.x + neighboorWeight.y ); + // Diffuse #if( defined REBLUR_DIFFUSE ) + // Checkerboard resolve // TODO: materialID support? bool diffHasData = gDiffCheckerboard == 2 || checkerboard == gDiffCheckerboard; uint shift = gDiffCheckerboard != 2 ? 1 : 0; @@ -315,16 +334,35 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : diff *= saturate( 1.0 - neighboorWeight.x - neighboorWeight.y ); diff += d0 * neighboorWeight.x + d1 * neighboorWeight.y; - float2 temporalAccumulationParams = GetTemporalAccumulationParams( isInScreen, diffMaxAccumSpeed * diffHistoryConfidence ); + float2 temporalAccumulationParams = GetTemporalAccumulationParams( isInScreen, diffAccumSpeedUpperBound ); float historyWeight = 1.0 - gCheckerboardResolveAccumSpeed * temporalAccumulationParams.x; diff = MixHistoryAndCurrent( diffHistory.xxxx, diff.xxxx, historyWeight ).w; } + + // Accumulation + float diffAccumSpeed = diffAccumSpeedUpperBound; + float diffAccumSpeedNonLinear = 1.0 / ( min( diffAccumSpeed, gMaxAccumulatedFrameNum ) + 1.0 ); + + float diffResult = MixHistoryAndCurrent( diffHistory.xxxx, diff.xxxx, diffAccumSpeedNonLinear ).w; + diffResult = Sanitize( diffResult, diff ); + + gOut_Diff[ pixelPos ] = float2( diffResult, scaledViewZ ); + + float diffMipLevel = GetMipLevel( 1.0 ); + float diffError = GetColorErrorForAdaptiveRadiusScale( diffResult, diffHistory, diffAccumSpeedNonLinear, 1.0, 0 ); + float diffAccumSpeedFinal = min( diffMaxAccumSpeedNoConfidence, max( diffAccumSpeed, diffMipLevel ) ); + #else + float diffError = 0; + float diffAccumSpeedFinal = 0; #endif + // Specular #if( defined REBLUR_SPECULAR ) - bool specHasData = gSpecCheckerboard == 2 || checkerboard == gSpecCheckerboard; + float smc = GetSpecMagicCurve( roughnessModified ); + // Checkerboard resolve // TODO: materialID support? + bool specHasData = gSpecCheckerboard == 2 || checkerboard == gSpecCheckerboard; float s0 = s_Spec[ smemPos.y ][ smemPos.x - 1 ]; float s1 = s_Spec[ smemPos.y ][ smemPos.x + 1 ]; @@ -333,170 +371,169 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : spec *= saturate( 1.0 - neighboorWeight.x - neighboorWeight.y ); spec += s0 * neighboorWeight.x + s1 * neighboorWeight.y; - float2 temporalAccumulationParams = GetTemporalAccumulationParams( isInScreen, specMaxAccumSpeed * specHistoryConfidence, parallax, roughness ); + float2 temporalAccumulationParams = GetTemporalAccumulationParams( isInScreen, specAccumSpeedUpperBound, parallax, roughness ); float historyWeight = 1.0 - gCheckerboardResolveAccumSpeed * temporalAccumulationParams.x; float specHistorySurfaceClamped = STL::Color::Clamp( specM1, specSigma * temporalAccumulationParams.y, specHistorySurface ); // TODO: needed? - specHistorySurfaceClamped = lerp( specHistorySurfaceClamped, specHistorySurface, roughnessModified * roughnessModified ); + specHistorySurfaceClamped = lerp( specHistorySurfaceClamped, specHistorySurface, smc ); spec = MixHistoryAndCurrent( specHistorySurfaceClamped.xxxx, spec.xxxx, historyWeight, roughnessModified ).w; } - #endif - // Diffuse - #if( defined REBLUR_DIFFUSE ) - // Accumulation - float diffAccumSpeed = diffMaxAccumSpeed * diffHistoryConfidence; - float diffAccumSpeedNonLinear = 1.0 / ( min( diffAccumSpeed, gDiffMaxAccumulatedFrameNum ) + 1.0 ); - - float diffResult = MixHistoryAndCurrent( diffHistory.xxxx, diff.xxxx, diffAccumSpeedNonLinear ).w; - diffResult = Sanitize( diffResult, diff ); - - gOut_Diff[ pixelPos ] = float2( diffResult, scaledViewZ ); - - float diffError = GetColorErrorForAdaptiveRadiusScale( diffResult, diffHistory, diffAccumSpeedNonLinear, 1.0, 0 ); - float diffAccumSpeedFinal = min( diffMaxAccumSpeed, max( diffAccumSpeed, GetMipLevel( 1.0 ) ) ); - #else - float diffError = 0; - float diffAccumSpeedFinal = 0; - #endif - - // Specular - #if( defined REBLUR_SPECULAR ) // Current hit distance float hitDistCurrent = lerp( minHitDist3x3, minHitDist5x5, STL::Math::SmoothStep( 0.04, 0.08, roughnessModified ) ); hitDistCurrent = STL::Color::Clamp( specM1, specSigma * 3.0, hitDistCurrent ); - float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gSpecHitDistParams, roughness ); + float hitDistScale = _REBLUR_GetHitDistanceNormalization( viewZ, gHitDistParams, roughness ); hitDistCurrent *= hitDistScale; - // Parallax correction - float hitDistFactor = saturate( hitDistCurrent * invFrustumHeight ); - parallax *= hitDistFactor; - // Virtual motion float NoV = abs( dot( N, V ) ); - float4 Xvirtual = GetXvirtual( X, V, NoV, roughnessModified, hitDistCurrent, viewZ, curvature ); - float2 pixelUvVirtualPrev = STL::Geometry::GetScreenUv( gWorldToClipPrev, Xvirtual.xyz, false ); + float pixelSize = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); + float realCurvature = GetRealCurvature( curvature, pixelSize, NoV ); + float3 Xvirtual = GetXvirtual( X, Xprev, V, NoV, roughnessModified, hitDistCurrent, realCurvature ); + float2 pixelUvVirtualPrev = STL::Geometry::GetScreenUv( gWorldToClipPrev, Xvirtual, false ); STL::Filtering::Bilinear bilinearFilterAtPrevVirtualPos = STL::Filtering::GetBilinearFilter( saturate( pixelUvVirtualPrev ), gRectSizePrev ); float virtualHistoryAmount = IsInScreen2x2( pixelUvVirtualPrev, gRectSizePrev ); - virtualHistoryAmount *= flatness; virtualHistoryAmount *= 1.0 - gReference; virtualHistoryAmount *= STL::ImportanceSampling::GetSpecularDominantFactor( NoV, roughnessModified, REBLUR_SPEC_DOMINANT_DIRECTION ); + // Parallax correction + float parallaxOrig = parallax; + + float parallaxVirtual = ComputeParallax( Xvirtual, Xvirtual, gCameraDelta, gOrthoMode != 0 ); + parallax = max( parallax, parallaxVirtual * ( 1.0 - smc ) ); + + float hitDistFactor = saturate( hitDistCurrent * invFrustumHeight ); + parallax *= hitDistFactor; + // This scaler improves motion stability for roughness 0.4+ virtualHistoryAmount *= 1.0 - STL::Math::SmoothStep( 0.15, 0.85, roughness ) * ( 1.0 - hitDistFactor ); // Virtual motion - surface similarity // TODO: make it closer to the main disocclusion test float2 gatherUvVirtualPrev = ( bilinearFilterAtPrevVirtualPos.origin + 1.0 ) * gInvScreenSize; - uint4 prevPackRedVirtual = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherRed( gNearestClamp, gatherUvVirtualPrev ).wzxy; - float4 prevViewZsVirtual = UnpackViewZ( prevPackRedVirtual ); + uint4 packedPrevViewZDiffAccumSpeedVirtual = gIn_Prev_ViewZ_DiffAccumSpeed.GatherRed( gNearestClamp, gatherUvVirtualPrev ).wzxy; + float4 prevViewZsVirtual = UnpackPrevViewZ( packedPrevViewZDiffAccumSpeedVirtual ); float3 Nvprev = STL::Geometry::RotateVector( gWorldToViewPrev, Nflat ); float4 ka; - ka.x = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.x, gIsOrtho ) ); - ka.y = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.y, gIsOrtho ) ); - ka.z = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.z, gIsOrtho ) ); - ka.w = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.w, gIsOrtho ) ); + ka.x = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.x, gOrthoMode ) ); + ka.y = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.y, gOrthoMode ) ); + ka.z = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.z, gOrthoMode ) ); + ka.w = dot( Nvprev, STL::Geometry::ReconstructViewPosition( pixelUvVirtualPrev, gFrustumPrev, prevViewZsVirtual.w, gOrthoMode ) ); float kb = dot( Nvprev, Xvprev ); float4 f = abs( ka - kb ) * invFrustumHeight; - float4 virtualMotionSurfaceWeights = STL::Math::LinearStep( 0.015, 0.005, f ); - float4 virtualMotionFootprintWeights = virtualMotionSurfaceWeights; - - virtualHistoryAmount *= dot( virtualMotionSurfaceWeights, 0.25 ); - - // Virtual motion - normal similarity - uint4 prevPackGreenVirtual = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds.GatherGreen( gNearestClamp, gatherUvVirtualPrev ).wzxy; - float4 prevNormalAndRoughnessVirtual00 = UnpackNormalRoughness( prevPackGreenVirtual.x ); - float4 prevNormalAndRoughnessVirtual10 = UnpackNormalRoughness( prevPackGreenVirtual.y ); - float4 prevNormalAndRoughnessVirtual01 = UnpackNormalRoughness( prevPackGreenVirtual.z ); - float4 prevNormalAndRoughnessVirtual11 = UnpackNormalRoughness( prevPackGreenVirtual.w ); - - float lobeHalfAngle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughnessModified ); - float avgCurvatureAngle = STL::Math::AtanApprox( abs( curvature ) ) + NRD_ENCODING_ERRORS.x; - float specNormalParams = 1.0 / min( lobeHalfAngle + avgCurvatureAngle, STL::Math::DegToRad( 89.0 ) ); - float4 virtualMotionNormalWeights = GetNormalWeight4( specNormalParams, N, prevNormalAndRoughnessVirtual00.xyz, prevNormalAndRoughnessVirtual10.xyz, prevNormalAndRoughnessVirtual01.xyz, prevNormalAndRoughnessVirtual11.xyz ); - virtualMotionNormalWeights = lerp( 1.0, virtualMotionNormalWeights, Xvirtual.w ); - virtualMotionFootprintWeights *= virtualMotionNormalWeights; + float4 virtualMotionSurfaceWeights = step( f, disocclusionThreshold ); + float virtualHistoryConfidence = STL::Filtering::ApplyBilinearFilter( virtualMotionSurfaceWeights.x, virtualMotionSurfaceWeights.y, virtualMotionSurfaceWeights.z, virtualMotionSurfaceWeights.w, bilinearFilterAtPrevVirtualPos ); + virtualHistoryAmount *= virtualHistoryConfidence; // Virtual motion - roughness similarity - float4 prevRoughnessVirtual = float4( prevNormalAndRoughnessVirtual00.w, prevNormalAndRoughnessVirtual10.w, prevNormalAndRoughnessVirtual01.w, prevNormalAndRoughnessVirtual11.w ); - float2 specRoughnessParams = GetRoughnessWeightParams( roughness, 0.1 ); - float4 virtualMotionRoughnessWeights = GetRoughnessWeight( specRoughnessParams, prevRoughnessVirtual ); - virtualMotionFootprintWeights *= virtualMotionRoughnessWeights; + float prevRoughnessVirtual = gIn_Prev_Roughness.SampleLevel( gLinearClamp, pixelUvVirtualPrev * gResolutionScale, 0 ); + float virtualMotionRoughnessWeight = GetEncodingAwareRoughnessWeight( roughness, prevRoughnessVirtual, gRoughnessFraction * 2.0 ); + virtualHistoryConfidence *= virtualMotionRoughnessWeight; - float interpolatedRoughnessWeight = STL::Filtering::ApplyBilinearFilter( virtualMotionRoughnessWeights.x, virtualMotionRoughnessWeights.y, virtualMotionRoughnessWeights.z, virtualMotionRoughnessWeights.w, bilinearFilterAtPrevVirtualPos ); float NoVflat = abs( dot( Nflat, V ) ); float fresnelFactor = STL::BRDF::Pow5( NoVflat ); float virtualHistoryAmountRoughnessAdjustment = lerp( fresnelFactor, 1.0, SaturateParallax( parallax * 0.5 ) ) * 0.5; - virtualHistoryAmount *= lerp( virtualHistoryAmountRoughnessAdjustment, 1.0, interpolatedRoughnessWeight ); + virtualHistoryAmount *= lerp( virtualHistoryAmountRoughnessAdjustment, 1.0, roughness > prevRoughnessVirtual ? virtualMotionRoughnessWeight : 1.0 ); // Sample virtual history float4 bilinearWeightsWithOcclusionVirtual = STL::Filtering::GetBilinearCustomWeights( bilinearFilterAtPrevVirtualPos, max( virtualMotionSurfaceWeights, 0.001 ) ); - float virtualOcclusionAvg = step( 3.5, dot( virtualMotionSurfaceWeights, 1.0 ) ) * REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TA; - virtualOcclusionAvg *= surfaceOcclusionAvg; + bool isCatRomAllowedForVirtualMotion = dot( virtualMotionSurfaceWeights, 1.0 ) > 3.5; + isCatRomAllowedForVirtualMotion = isCatRomAllowedForVirtualMotion & isCatRomAllowedForSurfaceMotion; + isCatRomAllowedForVirtualMotion = isCatRomAllowedForVirtualMotion & REBLUR_USE_CATROM_FOR_VIRTUAL_MOTION_IN_TA; float specHistoryVirtual = BicubicFilterNoCornersWithFallbackToBilinearFilterWithCustomWeights( gIn_History_Spec, gLinearClamp, saturate( pixelUvVirtualPrev ) * gRectSizePrev, gInvScreenSize, - bilinearWeightsWithOcclusionVirtual, virtualOcclusionAvg == 1.0 + bilinearWeightsWithOcclusionVirtual, isCatRomAllowedForVirtualMotion ); - // Virtual motion - hit distance similarity - float parallaxScale = lerp( 0.125 + flatness * 0.125, 1.0, gReference ); - float specAccumSpeedSurface = GetSpecAccumSpeed( specMaxAccumSpeed * specHistoryConfidence, roughnessModified, NoV, parallax * parallaxScale ); - float specAccumSpeedSurfaceNonLinear = 1.0 / ( min( specAccumSpeedSurface, gSpecMaxAccumulatedFrameNum ) + 1.0 ); + // Virtual motion - hit distance similarity // TODO: move into "prev-prev" loop + float specAccumSpeedSurface = GetSpecAccumSpeed( specAccumSpeedUpperBound, roughnessModified, NoV, parallax ); // TODO: optional scale can be applied to parallax if local curvature is very high, but it can lead to lags + float specAccumSpeedSurfaceNonLinear = 1.0 / ( min( specAccumSpeedSurface, gMaxAccumulatedFrameNum ) + 1.0 ); float hitDistNorm = lerp( specHistorySurface, spec, max( specAccumSpeedSurfaceNonLinear, REBLUR_HIT_DIST_MIN_ACCUM_SPEED( roughnessModified ) ) ); // TODO: try to use "hitDistCurrent" - float hitDist = hitDistNorm * hitDistScale; - float hitDistVirtual = specHistoryVirtual * hitDistScale; - float hitDistDelta = abs( hitDistVirtual - hitDist ); // TODO: sigma can worsen! useful for high roughness only? - float hitDistMax = max( hitDistVirtual, hitDist ); - hitDistDelta /= hitDistMax + viewZ + 1e-6; // TODO: + roughnessModified? - float virtualMotionHitDistWeights = 1.0 - STL::Math::SmoothStep( 0.0, 0.25, STL::Math::Sqrt01( hitDistDelta ) * SaturateParallax( parallax * REBLUR_TS_SIGMA_AMPLITUDE ) ); - virtualMotionHitDistWeights = lerp( 1.0, virtualMotionHitDistWeights, Xvirtual.w ); - virtualMotionFootprintWeights *= virtualMotionHitDistWeights; - - // Accumulation acceleration - float specAccumSpeedVirtual = specMaxAccumSpeed * specHistoryConfidence; - float specMinAccumSpeed = min( specAccumSpeedVirtual, GetMipLevel( roughnessModified ) ); - float specAccumSpeedScale = 1.0 - STL::Math::SmoothStep01( dot( hitDistDelta, 0.25 ) * SaturateParallax( parallax * REBLUR_TS_SIGMA_AMPLITUDE ) ); - specAccumSpeedVirtual = lerp( specMinAccumSpeed, specAccumSpeedVirtual, specAccumSpeedScale ); + float hitDistFocused = ApplyThinLensEquation( hitDistNorm * hitDistScale, realCurvature ); + float hitDistVirtualFocused = ApplyThinLensEquation( specHistoryVirtual * hitDistScale, realCurvature ); + float hitDistDelta = abs( hitDistVirtualFocused - hitDistFocused ); // TODO: sigma can worsen! useful for high roughness only? + float hitDistMax = max( abs( hitDistVirtualFocused ), abs( hitDistFocused ) ); + hitDistDelta /= hitDistMax + viewZ * 0.01 + 1e-6; // "viewZ" is already taken into account in "parallax", but use 1% to decrease sensitivity to low values + float virtualMotionHitDistWeight = 1.0 - STL::Math::SmoothStep( 0.0, 0.25, STL::Math::Sqrt01( hitDistDelta ) * SaturateParallax( parallax * REBLUR_TS_SIGMA_AMPLITUDE ) ); + virtualHistoryConfidence *= virtualMotionHitDistWeight; + + // Normal weight ( with fixing trails if radiance on a flat surface is taken from a sloppy surface ) + float lobeHalfAngle = STL::ImportanceSampling::GetSpecularLobeHalfAngle( roughnessModified ); + lobeHalfAngle += NRD_ENCODING_ERRORS.x + STL::Math::DegToRad( 1.5 ); // TODO: tune better? + + float parallaxInPixels = GetParallaxInPixels( parallaxOrig, gUnproject ); + float pixelSizeOverCurvatureRadius = curvature * NoV; // defines angle per 1 pixel + float tana = pixelSizeOverCurvatureRadius * ( lerp( parallaxInPixels, 0.0, roughness ) + 2.0 ); + float avgCurvatureAngle = STL::Math::AtanApprox( abs( tana ) ); - // Fix trails if radiance on a flat surface is taken from a sloppy surface - float2 pixelUvDelta = pixelUvVirtualPrev - pixelUvPrev; - float trailConfidence = 1.0; + float magicScale = lerp( 10.0, 1.0, saturate( parallaxInPixels / 5.0 ) ); + float2 virtualMotionDelta = pixelUvVirtualPrev - pixelUvPrev; + virtualMotionDelta *= gOrthoMode == 0 ? magicScale : 1.0; + float virtualMotionNormalWeight = 1.0; [unroll] - for( uint i = 0; i < 2; i++ ) + for( uint i = 0; i < REBLUR_VIRTUAL_MOTION_NORMAL_WEIGHT_ITERATION_NUM; i++ ) { - float2 pixelUvVirtualPrevPrev = pixelUvVirtualPrev + pixelUvDelta * ( 2.0 + i ); + float t = i + ( REBLUR_VIRTUAL_MOTION_NORMAL_WEIGHT_ITERATION_NUM < 3 ? 1.0 : 0.0 ); + float2 pixelUvVirtualPrevPrev = pixelUvVirtualPrev + virtualMotionDelta * t; - uint p = gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds[ uint2( pixelUvVirtualPrevPrev * gRectSizePrev ) ].y; - float3 n = UnpackNormalRoughness( p ).xyz; + #if( REBLUR_USE_BILINEAR_FOR_VIRTUAL_NORMAL_WEIGHT == 1 ) + STL::Filtering::Bilinear bilinearFilterAtPrevPrevVirtualPos = STL::Filtering::GetBilinearFilter( saturate( pixelUvVirtualPrevPrev ), gRectSizePrev ); + float2 gatherUvVirtualPrevPrev = ( bilinearFilterAtPrevPrevVirtualPos.origin + 1.0 ) * gInvScreenSize; + uint4 p = gIn_Prev_Normal_SpecAccumSpeed.GatherRed( gNearestClamp, gatherUvVirtualPrevPrev ).wzxy; - float cosa = dot( N, n ); - float angle = STL::Math::AcosApprox( saturate( cosa ) ); + float3 n00 = UnpackPrevNormal( p.x ); + float3 n10 = UnpackPrevNormal( p.y ); + float3 n01 = UnpackPrevNormal( p.z ); + float3 n11 = UnpackPrevNormal( p.w ); - trailConfidence *= _ComputeWeight( float2( specNormalParams, -0.001 ), angle ); + float3 n = STL::Filtering::ApplyBilinearFilter( n00, n10, n01, n11, bilinearFilterAtPrevPrevVirtualPos ); + n = normalize( n ); + #else + uint p = gIn_Prev_Normal_SpecAccumSpeed[ uint2( pixelUvVirtualPrevPrev * gRectSizePrev ) ]; + float3 n = UnpackPrevNormal( p ); + #endif + + float maxAngle = lobeHalfAngle + avgCurvatureAngle * ( 1.0 + t ); + virtualMotionNormalWeight *= IsInScreen( pixelUvVirtualPrevPrev ) ? GetEncodingAwareNormalWeight( N, n, maxAngle ) : 1.0; } - trailConfidence = lerp( 1.0, trailConfidence, Xvirtual.w ); + float virtualMotionLengthInPixels = length( virtualMotionDelta * gRectSizePrev ); + virtualMotionNormalWeight = lerp( 1.0, virtualMotionNormalWeight, saturate( virtualMotionLengthInPixels / 0.5 ) ); - // Virtual history clamping - float virtualHistoryConfidence = STL::Filtering::ApplyBilinearFilter( virtualMotionFootprintWeights.x, virtualMotionFootprintWeights.y, virtualMotionFootprintWeights.z, virtualMotionFootprintWeights.w, bilinearFilterAtPrevVirtualPos ); - virtualHistoryConfidence *= trailConfidence; + virtualHistoryConfidence *= virtualMotionNormalWeight; + virtualHistoryAmount *= lerp( 0.333, 1.0, virtualMotionNormalWeight ); // TODO: should depend on virtualHistoryAmount and accumSpeed? - float smc = GetSpecMagicCurve( roughnessModified ); + // Virtual motion - accumulation acceleration + float responsiveAccumulationAmount = GetResponsiveAccumulationAmount( roughness ); + float specAccumSpeedVirtual = GetSpecAccumSpeed( specAccumSpeedUpperBound, lerp( 1.0, roughnessModified, responsiveAccumulationAmount ), 0.99999, 0.0 ); + + float specMipLevel = GetMipLevel( roughnessModified ); + float specMinAccumSpeed = min( specAccumSpeedVirtual, specMipLevel ); + float fpsScaler = lerp( saturate( gFramerateScale * gFramerateScale ), 1.0, virtualHistoryConfidence ); + + float specAccumSpeedScale = lerp( 0.7, 1.0, virtualMotionHitDistWeight ); + specAccumSpeedScale *= lerp( 0.7, 1.0, virtualMotionNormalWeight ); + specAccumSpeedScale *= fpsScaler; + + specAccumSpeedVirtual = lerp( specMinAccumSpeed, specAccumSpeedVirtual, specAccumSpeedScale ); + + // Virtual history clamping float sigmaScale = lerp( 1.0, 3.0, smc ) * ( 1.0 + 2.0 * smc * REBLUR_TS_SIGMA_AMPLITUDE * virtualHistoryConfidence ); float specHistoryVirtualClamped = STL::Color::Clamp( specM1, specSigma * sigmaScale, specHistoryVirtual ); float unclampedVirtualHistoryAmount = lerp( virtualHistoryConfidence, 1.0, smc * STL::Math::SmoothStep( 0.2, 0.4, roughnessModified ) ); + unclampedVirtualHistoryAmount *= lerp( 1.0, smc * 0.5 + 0.5, responsiveAccumulationAmount ); float specHistoryVirtualMixed = lerp( specHistoryVirtualClamped, specHistoryVirtual, unclampedVirtualHistoryAmount ); // Final composition float specAccumSpeed = InterpolateAccumSpeeds( specAccumSpeedSurface, specAccumSpeedVirtual, virtualHistoryAmount ); - float specAccumSpeedNonLinear = 1.0 / ( min( specAccumSpeed, gSpecMaxAccumulatedFrameNum ) + 1.0 ); + float specAccumSpeedNonLinear = 1.0 / ( min( specAccumSpeed, gMaxAccumulatedFrameNum ) + 1.0 ); float specHistory = MixSurfaceAndVirtualMotion( specHistorySurface.xxxx, specHistoryVirtualMixed.xxxx, virtualHistoryAmount, hitDistFactor ).w; float specResult = MixHistoryAndCurrent( specHistory.xxxx, spec.xxxx, specAccumSpeedNonLinear, roughnessModified ).w; @@ -504,13 +541,14 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : gOut_Spec[ pixelPos ] = float2( specResult, scaledViewZ ); - fbits += floor( GetMipLevel( roughnessModified ) ); - fbits += virtualOcclusionAvg * 16.0; + fbits += floor( specMipLevel ); + fbits += float( isCatRomAllowedForVirtualMotion ) * 16.0; virtualHistoryConfidence = lerp( 1.0, virtualHistoryConfidence, virtualHistoryAmount ); + virtualHistoryConfidence = lerp( virtualHistoryConfidence, 1.0, specAccumSpeedNonLinear ); float specError = GetColorErrorForAdaptiveRadiusScale( specResult, specHistory, specAccumSpeedNonLinear, roughnessModified, 0 ); - float specAccumSpeedFinal = min( specMaxAccumSpeed, max( specAccumSpeed, GetMipLevel( roughnessModified ) ) ); + float specAccumSpeedFinal = min( specMaxAccumSpeedNoConfidence, max( specAccumSpeed, specMipLevel ) ); #else float virtualHistoryAmount = 0; float virtualHistoryConfidence = 0; diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.resources.hlsli similarity index 53% rename from Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.resources.hlsli rename to Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.resources.hlsli index e209c19..33b8328 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.resources.hlsli +++ b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.resources.hlsli @@ -11,10 +11,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "REBLUR_Config.hlsli" #if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) + #if( defined REBLUR_PROVIDED_CONFIDENCE ) #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_DiffConfidence, t, 8 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecConfidence, t, 9 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_DiffConfidence, t, 10 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecConfidence, t, 11 ) #else #define EXTRA_INPUTS #endif @@ -23,11 +24,13 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ObjectMotion, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_History_Diff, t, 5 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 6 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_History_Spec, t, 7 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_DiffAccumSpeed, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Normal_SpecAccumSpeed, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Roughness, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 6 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_History_Diff, t, 7 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 8 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_History_Spec, t, 9 ) \ EXTRA_INPUTS #define NRD_DECLARE_OUTPUT_TEXTURES \ @@ -36,26 +39,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 2 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 3 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToViewPrev ) \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4x4, gWorldToClip ) \ - NRD_CONSTANT( float4, gFrustumPrev ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ - NRD_CONSTANT( float, gDisocclusionThreshold ) \ - NRD_CONSTANT( float, gJitterDelta ) \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANTS_END #elif( defined REBLUR_DIFFUSE ) + #if( defined REBLUR_PROVIDED_CONFIDENCE ) #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_DiffConfidence, t, 6 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_DiffConfidence, t, 7 ) #else #define EXTRA_INPUTS #endif @@ -64,33 +52,22 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ObjectMotion, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_History_Diff, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_DiffAccumSpeed, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Normal_SpecAccumSpeed, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_History_Diff, t, 6 ) \ EXTRA_INPUTS #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_InternalData, u, 0 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Error, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 2 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToViewPrev ) \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4, gFrustumPrev ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ - NRD_CONSTANT( float, gDisocclusionThreshold ) \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANTS_END + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 2 ) + #else + #if( defined REBLUR_PROVIDED_CONFIDENCE ) #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecConfidence, t, 6 ) + NRD_INPUT_TEXTURE( Texture2D, gIn_SpecConfidence, t, 8 ) #else #define EXTRA_INPUTS #endif @@ -99,9 +76,11 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_ObjectMotion, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_Normal_Roughness_AccumSpeeds, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_History_Spec, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_ViewZ_DiffAccumSpeed, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Normal_SpecAccumSpeed, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Prev_Roughness, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 6 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_History_Spec, t, 7 ) \ EXTRA_INPUTS #define NRD_DECLARE_OUTPUT_TEXTURES \ @@ -109,21 +88,23 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Error, u, 1 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToViewPrev ) \ - NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ - NRD_CONSTANT( float4x4, gViewToWorld ) \ - NRD_CONSTANT( float4x4, gWorldToClip ) \ - NRD_CONSTANT( float4, gFrustumPrev ) \ - NRD_CONSTANT( float4, gCameraDelta ) \ - NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ - NRD_CONSTANT( float, gDisocclusionThreshold ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANTS_END #endif +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + REBLUR_SHARED_CB_DATA \ + NRD_CONSTANT( float4x4, gWorldToViewPrev ) \ + NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ + NRD_CONSTANT( float4x4, gViewToWorld ) \ + NRD_CONSTANT( float4x4, gWorldToClip ) \ + NRD_CONSTANT( float4, gFrustumPrev ) \ + NRD_CONSTANT( float4, gCameraDelta ) \ + NRD_CONSTANT( float2, gMotionVectorScale ) \ + NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ + NRD_CONSTANT( float, gDisocclusionThreshold ) \ + NRD_CONSTANT( uint, gDiffCheckerboard ) \ + NRD_CONSTANT( uint, gSpecCheckerboard ) \ + NRD_CONSTANTS_END + #define NRD_DECLARE_SAMPLERS \ NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_Blur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_Blur.resources.hlsli deleted file mode 100644 index 57368bd..0000000 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_Blur.resources.hlsli +++ /dev/null @@ -1,77 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "REBLUR_Config.hlsli" - -#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float3, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadius ) \ - NRD_CONSTANT( float, gSpecBlurRadiusScale ) \ - NRD_CONSTANT( float, gDiffBlurRadius ) \ - NRD_CONSTANT( float, gDiffBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#elif( defined REBLUR_DIFFUSE ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float, gDiffBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#else - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float4, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#endif - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ - EXTRA_INPUTS - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ - EXTRA_OUTPUTS - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_PostBlur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_PostBlur.resources.hlsli deleted file mode 100644 index 7afaa7a..0000000 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecularOcclusion_PostBlur.resources.hlsli +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "REBLUR_Config.hlsli" - -#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 2 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 3 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float3, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadius ) \ - NRD_CONSTANT( float, gSpecBlurRadiusScale ) \ - NRD_CONSTANT( float, gDiffBlurRadius ) \ - NRD_CONSTANT( float, gDiffBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#elif( defined REBLUR_DIFFUSE ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 2 ) \ - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float, gDiffBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#else - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float4, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#endif - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ - EXTRA_INPUTS - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ViewZ_Normal_Roughness_AccumSpeeds, u, 1 ) \ - EXTRA_OUTPUTS - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_Blur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular_Blur.resources.hlsli deleted file mode 100644 index 1661c85..0000000 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_Blur.resources.hlsli +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "REBLUR_Config.hlsli" - -#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 4 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float3, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadius ) \ - NRD_CONSTANT( float, gSpecBlurRadiusScale ) \ - NRD_CONSTANT( float, gDiffBlurRadius ) \ - NRD_CONSTANT( float, gDiffBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#elif( defined REBLUR_DIFFUSE ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 3 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float, gDiffBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#else - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float4, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#endif - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 2 ) \ - EXTRA_INPUTS - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ - EXTRA_OUTPUTS - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_PostBlur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular_PostBlur.resources.hlsli deleted file mode 100644 index 1661c85..0000000 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_PostBlur.resources.hlsli +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "REBLUR_Config.hlsli" - -#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 4 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 2 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float3, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadius ) \ - NRD_CONSTANT( float, gSpecBlurRadiusScale ) \ - NRD_CONSTANT( float, gDiffBlurRadius ) \ - NRD_CONSTANT( float, gDiffBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#elif( defined REBLUR_DIFFUSE ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 3 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) \ - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float, gDiffBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#else - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float4, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadiusScale ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#endif - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_InternalData, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_ScaledViewZ, t, 2 ) \ - EXTRA_INPUTS - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gInOut_Error, u, 0 ) \ - EXTRA_OUTPUTS - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_PreBlur.resources.hlsli b/Source/Shaders/Include/REBLUR_DiffuseSpecular_PreBlur.resources.hlsli deleted file mode 100644 index 9c45b52..0000000 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_PreBlur.resources.hlsli +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "REBLUR_Config.hlsli" - -#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 3 ) - - #ifdef REBLUR_SPATIAL_REUSE - #define SPATIAL_REUSE_EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_DiffDirectionPdf, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecDirectionPdf, t, 5 ) - #else - #define SPATIAL_REUSE_EXTRA_INPUTS - #endif - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float3, gSpecTrimmingParams ) \ - NRD_CONSTANT( float, gSpecBlurRadius ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( float, gDiffBlurRadius ) \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( uint, gSpatialFiltering ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#elif( defined REBLUR_DIFFUSE ) - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) - - #ifdef REBLUR_SPATIAL_REUSE - #define SPATIAL_REUSE_EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_DiffDirectionPdf, t, 3 ) - #else - #define SPATIAL_REUSE_EXTRA_INPUTS - #endif - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( uint, gSpatialFiltering ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#else - #define EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) - - #ifdef REBLUR_SPATIAL_REUSE - #define SPATIAL_REUSE_EXTRA_INPUTS \ - NRD_INPUT_TEXTURE( Texture2D, gIn_SpecDirectionPdf, t, 3 ) - #else - #define SPATIAL_REUSE_EXTRA_INPUTS - #endif - - #define EXTRA_OUTPUTS \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) - - #define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( float4x4, gWorldToView ) \ - NRD_CONSTANT( float4, gRotator ) \ - NRD_CONSTANT( float4, gSpecTrimmingParams ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( uint, gSpatialFiltering ) \ - NRD_CONSTANT( float, gNormalWeightStrictness ) \ - NRD_CONSTANTS_END -#endif - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 1 ) \ - EXTRA_INPUTS \ - SPATIAL_REUSE_EXTRA_INPUTS - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - EXTRA_OUTPUTS - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/REFERENCE_Accumulate.resources.hlsli b/Source/Shaders/Include/REFERENCE/REFERENCE_Accumulate.resources.hlsli similarity index 100% rename from Source/Shaders/Include/REFERENCE_Accumulate.resources.hlsli rename to Source/Shaders/Include/REFERENCE/REFERENCE_Accumulate.resources.hlsli diff --git a/Source/Shaders/Include/REFERENCE_SplitScreen.resources.hlsli b/Source/Shaders/Include/REFERENCE/REFERENCE_SplitScreen.resources.hlsli similarity index 100% rename from Source/Shaders/Include/REFERENCE_SplitScreen.resources.hlsli rename to Source/Shaders/Include/REFERENCE/REFERENCE_SplitScreen.resources.hlsli diff --git a/Source/Shaders/Include/RELAX_Common.hlsli b/Source/Shaders/Include/RELAX_Common.hlsli index c4a8cbe..30092d4 100644 --- a/Source/Shaders/Include/RELAX_Common.hlsli +++ b/Source/Shaders/Include/RELAX_Common.hlsli @@ -13,6 +13,7 @@ float4 UnpackPrevNormalRoughness(float4 packedData) float4 result; result.rgb = normalize(packedData.rgb * 2.0 - 1.0); result.a = packedData.a; + return result; } @@ -21,6 +22,7 @@ float4 PackPrevNormalRoughness(float4 normalRoughness) float4 result; result.rgb = normalRoughness.xyz * 0.5 + 0.5; result.a = normalRoughness.a; + return result; } @@ -50,6 +52,7 @@ float4 BicubicFloat4(Texture2D tex, SamplerState samp, float2 samplePos, tex.SampleLevel(samp, float2(tc12.x, tc12.y), 0).rgba * (w12.x * w12.y) + tex.SampleLevel(samp, float2(tc12.x, tc3.y), 0).rgba * (w12.x * w3.y) + tex.SampleLevel(samp, float2(tc3.x, tc12.y), 0).rgba * (w3.x * w12.y); + return result / ((w0.x * w12.y) + (w12.x * w0.y) + (w12.x * w12.y) + (w12.x * w3.y) + (w3.x * w12.y)); } @@ -107,6 +110,7 @@ float BilinearWithBinaryWeightsFloat(Texture2D tex, int2 bilinearOrigin, float r = STL::Filtering::ApplyBilinearFilter(s00, s10, s01, s11, bilinear); r /= interpolatedBinaryWeight; + return r; } @@ -126,6 +130,7 @@ float2 BilinearWithBinaryWeightsFloat2(Texture2D tex, int2 bilinearOrigi float2 r = STL::Filtering::ApplyBilinearFilter(s00, s10, s01, s11, bilinear); r /= interpolatedBinaryWeight; + return r; } @@ -145,6 +150,7 @@ float4 BilinearWithBinaryWeightsFloat4(Texture2D tex, int2 bilinearOrigi float4 r = STL::Filtering::ApplyBilinearFilter(s00, s10, s01, s11, bilinear); r /= interpolatedBinaryWeight; + return r; } @@ -160,6 +166,7 @@ float BilinearWithBinaryWeightsImmediateFloat(float s00, float s10, float s01, f float r = STL::Filtering::ApplyBilinearFilter(s00, s10, s01, s11, bilinear); r /= interpolatedBinaryWeight; + return r; } @@ -175,6 +182,7 @@ float3 BilinearWithBinaryWeightsImmediateFloat3(float3 s00, float3 s10, float3 s float3 r = STL::Filtering::ApplyBilinearFilter(s00, s10, s01, s11, bilinear); r /= interpolatedBinaryWeight; + return r; } @@ -190,56 +198,47 @@ float4 BilinearWithBinaryWeightsImmediateFloat4(float4 s00, float4 s10, float4 s float4 r = STL::Filtering::ApplyBilinearFilter(s00, s10, s01, s11, bilinear); r /= interpolatedBinaryWeight; + return r; } -float3 GetCurrentWorldPos(int2 pixelPos, float depth) +float3 GetCurrentWorldPosFromPixelPos(int2 pixelPos, float viewZ) { float2 clipSpaceXY = ((float2)pixelPos + float2(0.5, 0.5)) * gInvRectSize * 2.0 - 1.0; - return (gIsOrtho == 0) ? - depth * (gFrustumForward.xyz + gFrustumRight.xyz * clipSpaceXY.x - gFrustumUp.xyz * clipSpaceXY.y) : - depth * gFrustumForward.xyz + gFrustumRight.xyz * clipSpaceXY.x - gFrustumUp.xyz * clipSpaceXY.y; + + return (gOrthoMode == 0) ? + viewZ * (gFrustumForward.xyz + gFrustumRight.xyz * clipSpaceXY.x - gFrustumUp.xyz * clipSpaceXY.y) : + viewZ * gFrustumForward.xyz + gFrustumRight.xyz * clipSpaceXY.x - gFrustumUp.xyz * clipSpaceXY.y; } -float3 GetCurrentWorldPos(float2 clipSpaceXY, float depth) +float3 GetCurrentWorldPosFromClipSpaceXY(float2 clipSpaceXY, float viewZ) { - return (gIsOrtho == 0) ? - depth * (gFrustumForward.xyz + gFrustumRight.xyz * clipSpaceXY.x - gFrustumUp.xyz * clipSpaceXY.y) : - depth * gFrustumForward.xyz + gFrustumRight.xyz * clipSpaceXY.x - gFrustumUp.xyz * clipSpaceXY.y; + return (gOrthoMode == 0) ? + viewZ * (gFrustumForward.xyz + gFrustumRight.xyz * clipSpaceXY.x - gFrustumUp.xyz * clipSpaceXY.y) : + viewZ * gFrustumForward.xyz + gFrustumRight.xyz * clipSpaceXY.x - gFrustumUp.xyz * clipSpaceXY.y; } -float3 GetPreviousWorldPos(int2 pixelPos, float depth) +float3 GetPreviousWorldPosFromPixelPos(int2 pixelPos, float viewZ) { float2 clipSpaceXY = ((float2)pixelPos + float2(0.5, 0.5)) * (1.0 / gRectSizePrev) * 2.0 - 1.0; - return (gIsOrtho == 0) ? - depth * (gPrevFrustumForward.xyz + gPrevFrustumRight.xyz * clipSpaceXY.x - gPrevFrustumUp.xyz * clipSpaceXY.y) : - depth * gPrevFrustumForward.xyz + gPrevFrustumRight.xyz * clipSpaceXY.x - gPrevFrustumUp.xyz * clipSpaceXY.y; + + return (gOrthoMode == 0) ? + viewZ * (gPrevFrustumForward.xyz + gPrevFrustumRight.xyz * clipSpaceXY.x - gPrevFrustumUp.xyz * clipSpaceXY.y) : + viewZ * gPrevFrustumForward.xyz + gPrevFrustumRight.xyz * clipSpaceXY.x - gPrevFrustumUp.xyz * clipSpaceXY.y; } -float3 GetPreviousWorldPos(float2 clipSpaceXY, float depth) +float3 GetPreviousWorldPosFromClipSpaceXY(float2 clipSpaceXY, float viewZ) { - return (gIsOrtho == 0) ? - depth * (gPrevFrustumForward.xyz + gPrevFrustumRight.xyz * clipSpaceXY.x - gPrevFrustumUp.xyz * clipSpaceXY.y) : - depth * gPrevFrustumForward.xyz + gPrevFrustumRight.xyz * clipSpaceXY.x - gPrevFrustumUp.xyz * clipSpaceXY.y; + return (gOrthoMode == 0) ? + viewZ * (gPrevFrustumForward.xyz + gPrevFrustumRight.xyz * clipSpaceXY.x - gPrevFrustumUp.xyz * clipSpaceXY.y) : + viewZ * gPrevFrustumForward.xyz + gPrevFrustumRight.xyz * clipSpaceXY.x - gPrevFrustumUp.xyz * clipSpaceXY.y; } float GetPlaneDistanceWeight(float3 centerWorldPos, float3 centerNormal, float centerViewZ, float3 sampleWorldPos, float threshold) { float distanceToCenterPointPlane = abs(dot(sampleWorldPos - centerWorldPos, centerNormal)); - return 1.0 - STL::Math::SmoothStep(threshold, threshold * 2.0, distanceToCenterPointPlane / centerViewZ); -} -float GetDiffuseNormalWeight_ATrous(float3 centerNormal, float3 sampleNormal, float phiNormal) -{ - return phiNormal == 0.0f ? 1.0f : pow(saturate(dot(centerNormal, sampleNormal)), phiNormal); -} - -float GetSpecularLobeHalfAngle_ATrous(float roughness) -{ - // Defines a cone angle, where micro-normals are distributed - float r2 = roughness * roughness; - float r3 = roughness * r2; - return 3.141592 * r2 / (1.0 + 0.5 * r2 + r3); + return 1.0 - STL::Math::SmoothStep(threshold, threshold * 2.0, distanceToCenterPointPlane / centerViewZ); } float2 GetNormalWeightParams_ATrous(float roughness, float numFramesInHistory, float specularReprojectionConfidence, float normalEdgeStoppingRelaxation, float specularLobeAngleFraction) @@ -251,31 +250,84 @@ float2 GetNormalWeightParams_ATrous(float roughness, float numFramesInHistory, f float f = 0.9 + 0.1 * relaxation; // This is the main parameter - cone angle - float angle = specularLobeAngleFraction * GetSpecularLobeHalfAngle_ATrous(roughness); + float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle(roughness, specularLobeAngleFraction); // Increasing angle ~10x to relax rejection of the neighbors if specular reprojection confidence is low angle *= 10.0 - 9.0 * relaxation; - angle = min(0.5 * 3.141592, angle); + angle = min(STL::Math::Pi(0.5), angle); return float2(angle, f); } -float GetSpecularVWeight_ATrous(float2 params0, float specularLobeAngleSlack, float3 v0, float3 v) +float GetSpecularNormalWeight_ATrous(float2 params0, float specularLobeAngleSlack, float3 n0, float3 n) { - float cosa = saturate(dot(v0, v)); - float a = STL::Math::AcosApprox(cosa) * 0.5; + float cosa = saturate(dot(n0, n)); + float a = STL::Math::AcosApprox(cosa); params0.x += specularLobeAngleSlack; a = 1.0 - STL::Math::SmoothStep(0.0, params0.x, a); return saturate(1.0 + (a - 1.0) * params0.y); } -float GetSpecularNormalWeight_ATrous(float2 params0, float specularLobeAngleSlack, float3 n0, float3 n) +float GetNormalWeightParams(float roughness, float angleFraction = 0.75) +{ + // This is the main parameter - cone angle + float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle(roughness, angleFraction); + angle = 1.0 / max(angle, NRD_ENCODING_ERRORS.x); + + return angle; +} + +float GetNormalWeight(float params0, float3 n0, float3 n) { float cosa = saturate(dot(n0, n)); - float a = STL::Math::AcosApprox(cosa); - params0.x += specularLobeAngleSlack; - a = 1.0 - STL::Math::SmoothStep(0.0, params0.x, a); - return saturate(1.0 + (a - 1.0) * params0.y); + float angle = STL::Math::AcosApprox(cosa); + + return _ComputeWeight(float2(params0, -0.001), angle); +} + +float GetEncodingAwareNormalWeight(float3 Ncurr, float3 Nprev, float maxAngle) +{ + float a = 1.0 / maxAngle; + float cosa = saturate(dot(Ncurr, Nprev)); + float d = STL::Math::AcosApprox(cosa); + + return STL::Math::SmoothStep01(1.0 - (d - RELAX_NORMAL_ULP) * a); +} + +float2 GetRoughnessWeightParams(float roughness, float percentOfRoughness = 0.05) +{ + // IMPORTANT: too small values of "percentOfRoughness" can ruin contact shadowing even if neighboring roughness is absolutely same due to re-packing imprecision problems. + float a = 1.0 / (roughness * percentOfRoughness * 0.99 + 0.01); + float b = roughness * a; + + return float2(a, -b); +} + +float GetNormHitDist(float hitDist, float viewZ, float4 hitDistParams = float4(3.0, 0.1, 10.0, -25.0), float linearRoughness = 1.0) +{ + float f = _REBLUR_GetHitDistanceNormalization(viewZ, hitDistParams, linearRoughness); + + return saturate(hitDist / f); +} + +float2 GetHitDistanceWeightParams(float normHitDist, float nonLinearAccumSpeed, float roughness = 1.0) +{ + float threshold = exp2(-17.0 * roughness * roughness); // TODO: not in line with other weights + float scale = lerp(threshold, 1.0, nonLinearAccumSpeed); + + float a = rcp(normHitDist * scale * 0.99 + 0.01); + float b = normHitDist * a; + + return float2(a, -b); +} + +float EstimateCurvature(float3 Ni, float3 Vi, float3 N, float3 X) +{ + float3 Xi = 0 + Vi * dot(X - 0, N) / dot(Vi, N); + float3 edge = Xi - X; + float curvature = dot(Ni - N, edge) * rsqrt(STL::Math::LengthSquared(edge)); + + return curvature; } // Altered (2,0) Pade approximation for exp(), good for negative arguments, max error 0.04 at a = -0.721 diff --git a/Source/Shaders/Include/RELAX_Config.hlsli b/Source/Shaders/Include/RELAX_Config.hlsli index 424ae62..7405af0 100644 --- a/Source/Shaders/Include/RELAX_Config.hlsli +++ b/Source/Shaders/Include/RELAX_Config.hlsli @@ -8,18 +8,18 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#define RELAX_BLACK_OUT_INF_PIXELS 1 // can be used to avoid killing INF pixels during composition -#define RELAX_SPEC_ACCUM_BASE_POWER 0.5 // previously was 0.66 (less agressive accumulation, but virtual reprojection works well on flat surfaces and fixes the issue) -#define RELAX_MAX_ACCUM_FRAME_NUM 63 -#define RELAX_SPEC_ACCUM_CURVE 1.0 // aggressiveness of history rejection depending on viewing angle (1 - low, 0.66 - medium, 0.5 - high) -#define RELAX_PARALLAX_COMPRESSION_STRENGTH 0 // TODO: 0.1? -#define RELAX_PARALLAX_NORMALIZATION 30 -#define RELAX_HIT_DIST_MIN_ACCUM_SPEED( r ) lerp( 0.1, 0.2, STL::Math::Sqrt01( r ) ) -#define RELAX_SPEC_DOMINANT_DIRECTION STL_SPECULAR_DOMINANT_DIRECTION_G2 -#define RELAX_SPEC_BASIS_ROUGHNESS_THRESHOLD 0.8 -#define RELAX_USE_ANISOTROPIC_KERNEL 1 -#define RELAX_USE_BICUBIC_FOR_FAST_HISTORY 1 // Improves sharpness for diffuse and specular at some performance cost -#define RELAX_USE_BICUBIC_FOR_VIRTUAL_MOTION_SPECULAR 1 // Improves sharpness for specular at low roughness at some performance cost +#define RELAX_BLACK_OUT_INF_PIXELS 1 // can be used to avoid killing INF pixels during composition +#define RELAX_SPEC_ACCUM_BASE_POWER 0.5 // previously was 0.66 (less agressive accumulation, but virtual reprojection works well on flat surfaces and fixes the issue) +#define RELAX_MAX_ACCUM_FRAME_NUM 63 +#define RELAX_SPEC_ACCUM_CURVE 1.0 // aggressiveness of history rejection depending on viewing angle (1 - low, 0.66 - medium, 0.5 - high) +#define RELAX_PARALLAX_NORMALIZATION 30 +#define RELAX_HIT_DIST_MIN_ACCUM_SPEED( r ) lerp( 0.1, 0.2, STL::Math::Sqrt01( r ) ) +#define RELAX_SPEC_DOMINANT_DIRECTION STL_SPECULAR_DOMINANT_DIRECTION_G2 +#define RELAX_SPEC_BASIS_ROUGHNESS_THRESHOLD 0.8 +#define RELAX_USE_ANISOTROPIC_KERNEL 1 +#define RELAX_USE_BICUBIC_FOR_FAST_HISTORY 1 // Improves sharpness for diffuse and specular at some performance cost +#define RELAX_USE_BICUBIC_FOR_VIRTUAL_MOTION_SPECULAR 1 // Improves sharpness for specular at low roughness at some performance cost +#define RELAX_NORMAL_ULP STL::Math::DegToRad( 0.05 ) // Shared constants common to all ReLAX denoisers #define RELAX_SHARED_CB_DATA \ @@ -31,7 +31,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_CONSTANT( float4, gPrevFrustumRight ) \ NRD_CONSTANT( float4, gPrevFrustumUp ) \ NRD_CONSTANT( float4, gPrevFrustumForward ) \ - NRD_CONSTANT( float4, gPrevCameraPositionAndJitterDelta ) \ + NRD_CONSTANT( float4, gPrevCameraPosition ) \ NRD_CONSTANT( float2, gResolutionScale) \ NRD_CONSTANT( uint2, gRectOrigin ) \ NRD_CONSTANT( float2, gRectOffset ) \ @@ -40,11 +40,20 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_CONSTANT( float2, gInvRectSize ) \ NRD_CONSTANT( float2, gRectSizePrev ) \ NRD_CONSTANT( float2, gMotionVectorScale ) \ - NRD_CONSTANT( uint, gIsWorldSpaceMotion ) \ - NRD_CONSTANT( uint, gIsCameraStatic ) \ - NRD_CONSTANT( float, gIsOrtho ) \ + NRD_CONSTANT( uint, gIsWorldSpaceMotionEnabled ) \ + NRD_CONSTANT( float, gDebug ) \ + NRD_CONSTANT( float, gOrthoMode ) \ NRD_CONSTANT( float, gUnproject ) \ NRD_CONSTANT( uint, gFrameIndex ) \ NRD_CONSTANT( float, gDenoisingRange ) \ NRD_CONSTANT( float, gFramerateScale ) \ - NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed) + NRD_CONSTANT( float, gCheckerboardResolveAccumSpeed ) \ + NRD_CONSTANT( float, gJitterDelta ) \ + NRD_CONSTANT( uint, gDiffMaterialMask ) \ + NRD_CONSTANT( uint, gSpecMaterialMask ) \ + NRD_CONSTANT( float, gUnused1 ) + +#if( !defined RELAX_DIFFUSE && !defined RELAX_SPECULAR ) + #define RELAX_DIFFUSE + #define RELAX_SPECULAR +#endif \ No newline at end of file diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.hlsli new file mode 100644 index 0000000..1517cf4 --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.hlsli @@ -0,0 +1,373 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "NRD.hlsli" +#include "STL.hlsli" +#include "RELAX_DiffuseSpecular_ATrousShmem.resources.hlsli" + +NRD_DECLARE_CONSTANTS + +#define NRD_CTA_8X8 +#define NRD_USE_BORDER_2 + +#include "NRD_Common.hlsli" + +NRD_DECLARE_SAMPLERS + +#include "RELAX_Common.hlsli" + + +NRD_DECLARE_INPUT_TEXTURES +NRD_DECLARE_OUTPUT_TEXTURES + +#if( defined RELAX_DIFFUSE) +groupshared float4 sharedDiffuse[BUFFER_X][BUFFER_Y]; +#endif +#if( defined RELAX_SPECULAR) +groupshared float4 sharedSpecular[BUFFER_X][BUFFER_Y]; +#endif +groupshared float4 sharedNormalRoughness[BUFFER_X][BUFFER_Y]; +groupshared float4 sharedWorldPos[BUFFER_X][BUFFER_Y]; +groupshared float sharedMaterialID[BUFFER_X][BUFFER_Y]; + +// Helper functions + +// computes a 3x3 gaussian blur of the variance, centered around +// the current pixel +void computeVariance( + int2 threadPos +#if( defined RELAX_SPECULAR ) + ,out float specularVariance +#endif +#if( defined RELAX_DIFFUSE ) + ,out float diffuseVariance +#endif +) +{ +#if( defined RELAX_SPECULAR ) + float4 specularSum = 0; +#endif +#if( defined RELAX_DIFFUSE ) + float4 diffuseSum = 0; +#endif + + static const float kernel[2][2] = + { + { 1.0 / 4.0, 1.0 / 8.0 }, + { 1.0 / 8.0, 1.0 / 16.0 } + }; + + const int radius = 1; + for (int yy = -radius; yy <= radius; yy++) + { + for (int xx = -radius; xx <= radius; xx++) + { + int2 sharedMemoryIndex = threadPos.xy + int2(xx + BORDER,yy + BORDER); + float k = kernel[abs(xx)][abs(yy)]; +#if( defined RELAX_SPECULAR ) + float4 specular = sharedSpecular[sharedMemoryIndex.y][sharedMemoryIndex.x]; + specularSum += specular * k; +#endif +#if( defined RELAX_DIFFUSE ) + float4 diffuse = sharedDiffuse[sharedMemoryIndex.y][sharedMemoryIndex.x]; + diffuseSum += diffuse * k; +#endif + } + } +#if( defined RELAX_SPECULAR ) + float specular1stMoment = STL::Color::Luminance(specularSum.rgb); + float specular2ndMoment = specularSum.a; + specularVariance = max(0, specular2ndMoment - specular1stMoment * specular1stMoment); +#endif +#if( defined RELAX_DIFFUSE ) + float diffuse1stMoment = STL::Color::Luminance(diffuseSum.rgb); + float diffuse2ndMoment = diffuseSum.a; + diffuseVariance = max(0, diffuse2ndMoment - diffuse1stMoment * diffuse1stMoment); +#endif +} + +void Preload(uint2 sharedPos, int2 globalPos) +{ + globalPos = clamp(globalPos, 0, gRectSize - 1.0); + +#if( defined RELAX_SPECULAR ) + sharedSpecular[sharedPos.y][sharedPos.x] = gSpecularIlluminationAnd2ndMoment[globalPos]; +#endif + +#if( defined RELAX_DIFFUSE ) + sharedDiffuse[sharedPos.y][sharedPos.x] = gDiffuseIlluminationAnd2ndMoment[globalPos]; +#endif + float materialID; + sharedNormalRoughness[sharedPos.y][sharedPos.x] = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[globalPos], materialID); + + float viewZ = gViewZFP16[globalPos] / NRD_FP16_VIEWZ_SCALE; + sharedWorldPos[sharedPos.y][sharedPos.x] = float4(GetCurrentWorldPosFromPixelPos(globalPos, viewZ), viewZ); + + sharedMaterialID[sharedPos.y][sharedPos.x] = materialID; +} + + +[numthreads(GROUP_X, GROUP_Y, 1)] +NRD_EXPORT void NRD_CS_MAIN(int2 pixelPos : SV_DispatchThreadId, uint2 threadPos : SV_GroupThreadId, uint threadIndex : SV_GroupIndex) +{ + PRELOAD_INTO_SMEM; + // Shared memory is populated now and can be used for filtering + + uint2 sharedMemoryIndex = threadPos.xy + int2(BORDER, BORDER); + + // Repacking normal and roughness to prev normal roughness to be used in the next frame + float materialID; + float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[pixelPos], materialID); + gOutNormalRoughness[pixelPos] = PackPrevNormalRoughness(normalRoughness); +#if( NRD_USE_MATERIAL_ID == 1 ) + gOutMaterialID[pixelPos] = floor( materialID * 3.0 + 0.5 ) / 255.0; // IMPORTANT: properly repack 2-bits to 8-bits +#endif + + float4 centerWorldPosAndViewZ = sharedWorldPos[sharedMemoryIndex.y][sharedMemoryIndex.x]; + float3 centerWorldPos = centerWorldPosAndViewZ.xyz; + float centerViewZ = centerWorldPosAndViewZ.w; + + // Early out if linearZ is beyond denoising range + [branch] + if (centerViewZ > gDenoisingRange) + { + return; + } + + float3 centerNormal = normalRoughness.rgb; + float centerRoughness = normalRoughness.a; + +#if( defined RELAX_SPECULAR ) + float2 roughnessWeightParams = GetRoughnessWeightParams(centerRoughness, gRoughnessFraction); +#endif + +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + float historyLength = 255.0 * gHistoryLength[pixelPos].y; +#else + float historyLength = 255.0 * gHistoryLength[pixelPos]; +#endif + + float centerMaterialID = sharedMaterialID[sharedMemoryIndex.y][sharedMemoryIndex.x]; + + [branch] + if (historyLength >= float(gHistoryThreshold)) // Running Atrous 3x3 + { + // Calculating variance, filtered using 3x3 gaussin blur +#if( defined RELAX_SPECULAR ) + float centerSpecularVar; +#endif +#if( defined RELAX_DIFFUSE ) + float centerDiffuseVar; +#endif + computeVariance( + threadPos.xy +#if( defined RELAX_SPECULAR ) + , centerSpecularVar +#endif +#if( defined RELAX_DIFFUSE ) + , centerDiffuseVar +#endif + ); + +#if( defined RELAX_SPECULAR ) + float specularReprojectionConfidence = gSpecularReprojectionConfidence[pixelPos]; + float2 normalWeightParams = GetNormalWeightParams_ATrous(centerRoughness, historyLength, specularReprojectionConfidence, gNormalEdgeStoppingRelaxation, gSpecularLobeAngleFraction); + + float centerSpecularLuminance = STL::Color::Luminance(sharedSpecular[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb); + float specularPhiLIllumination = gSpecularPhiLuminance * max(1.0e-4, sqrt(centerSpecularVar)); + float sumWSpecular = 0; + float4 sumSpecularIlluminationAnd2ndMoment = 0; +#endif +#if( defined RELAX_DIFFUSE ) + float centerDiffuseLuminance = STL::Color::Luminance(sharedDiffuse[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb); + float diffusePhiLIllumination = gDiffusePhiLuminance * max(1.0e-4, sqrt(centerDiffuseVar)); + float sumWDiffuse = 0; + float4 sumDiffuseIlluminationAnd2ndMoment = 0; +#endif + + static const float kernelWeightGaussian3x3[2] = { 0.44198, 0.27901 }; + + [unroll] + for (int cy = -1; cy <= 1; cy++) + { + [unroll] + for (int cx = -1; cx <= 1; cx++) + { + const float kernel = kernelWeightGaussian3x3[abs(cx)] * kernelWeightGaussian3x3[abs(cy)]; + const int2 p = pixelPos + int2(cx, cy); + const bool isInside = all(p >= int2(0, 0)) && all(p < int2(gResourceSize)); + const bool isCenter = ((cx == 0) && (cy == 0)); + + int2 sampleSharedMemoryIndex = threadPos.xy + int2(BORDER + cx, BORDER + cy); + + float4 sampleNormalRoughness = sharedNormalRoughness[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; + float3 sampleNormal = sampleNormalRoughness.rgb; + float sampleRoughness = sampleNormalRoughness.a; + float3 sampleWorldPos = sharedWorldPos[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x].rgb; + + float sampleMaterialID = sharedMaterialID[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; +#if( defined RELAX_SPECULAR ) + float4 sampleSpecularIlluminationAnd2ndMoment = sharedSpecular[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; + float sampleSpecularLuminance = STL::Color::Luminance(sampleSpecularIlluminationAnd2ndMoment.rgb); +#endif +#if( defined RELAX_DIFFUSE ) + float4 sampleDiffuseIlluminationAnd2ndMoment = sharedDiffuse[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; + float sampleDiffuseLuminance = STL::Color::Luminance(sampleDiffuseIlluminationAnd2ndMoment.rgb); +#endif + + // Calculating geometry and normal weights + float geometryW = GetPlaneDistanceWeight( + centerWorldPos, + centerNormal, + gOrthoMode == 0 ? centerViewZ : 1.0, + sampleWorldPos, + gDepthThreshold); + + float diffuseNormalWeightParams = GetNormalWeightParams(1.0, gDiffuseLobeAngleFraction); + float normalWDiffuse = GetNormalWeight(diffuseNormalWeightParams, centerNormal, sampleNormal); + +#if( defined RELAX_SPECULAR ) + float normalWSpecular = GetSpecularNormalWeight_ATrous(normalWeightParams, gSpecularLobeAngleSlack, centerNormal, sampleNormal); + float specularRoughnessW = GetRoughnessWeight(roughnessWeightParams, sampleRoughness); + float specularLuminanceW = abs(centerSpecularLuminance - sampleSpecularLuminance) / specularPhiLIllumination; + float relaxation = lerp(1.0, specularReprojectionConfidence, gLuminanceEdgeStoppingRelaxation); + specularLuminanceW *= relaxation; + specularLuminanceW = min(gMaxLuminanceRelativeDifference, specularLuminanceW); + float wSpecular = geometryW * exp_approx(-specularLuminanceW); + wSpecular *= gRoughnessEdgeStoppingEnabled ? (normalWSpecular * specularRoughnessW) : normalWDiffuse; + wSpecular = kernel * wSpecular; + wSpecular = isCenter ? kernel : wSpecular; + wSpecular *= isInside ? 1.0 : 0.0; + wSpecular *= CompareMaterials(sampleMaterialID, centerMaterialID, gSpecMaterialMask); + + sumWSpecular += wSpecular; + sumSpecularIlluminationAnd2ndMoment += wSpecular * sampleSpecularIlluminationAnd2ndMoment; +#endif +#if( defined RELAX_DIFFUSE ) + float diffuseLuminanceW = abs(centerDiffuseLuminance - sampleDiffuseLuminance) / diffusePhiLIllumination; + diffuseLuminanceW = min(gMaxLuminanceRelativeDifference, diffuseLuminanceW); + float wDiffuse = geometryW * kernel * normalWDiffuse * exp_approx(-diffuseLuminanceW); + wDiffuse = isCenter ? kernel : wDiffuse; + wDiffuse *= isInside ? 1.0 : 0.0; + wDiffuse *= CompareMaterials(sampleMaterialID, centerMaterialID, gDiffMaterialMask); + + sumWDiffuse += wDiffuse; + sumDiffuseIlluminationAnd2ndMoment += wDiffuse * sampleDiffuseIlluminationAnd2ndMoment; +#endif + } + } +#if( defined RELAX_SPECULAR ) + sumWSpecular = max(sumWSpecular, 1e-6f); + sumSpecularIlluminationAnd2ndMoment /= sumWSpecular; + float specular1stMoment = STL::Color::Luminance(sumSpecularIlluminationAnd2ndMoment.rgb); + float specular2ndMoment = sumSpecularIlluminationAnd2ndMoment.a; + float specularVariance = max(0, specular2ndMoment - specular1stMoment * specular1stMoment); + float4 filteredSpecularIlluminationAndVariance = float4(sumSpecularIlluminationAnd2ndMoment.rgb, specularVariance); + gOutSpecularIlluminationAndVariance[pixelPos] = filteredSpecularIlluminationAndVariance; +#endif +#if( defined RELAX_DIFFUSE ) + sumWDiffuse = max(sumWDiffuse, 1e-6f); + sumDiffuseIlluminationAnd2ndMoment /= sumWDiffuse; + float diffuse1stMoment = STL::Color::Luminance(sumDiffuseIlluminationAnd2ndMoment.rgb); + float diffuse2ndMoment = sumDiffuseIlluminationAnd2ndMoment.a; + float diffuseVariance = max(0, diffuse2ndMoment - diffuse1stMoment * diffuse1stMoment); + float4 filteredDiffuseIlluminationAndVariance = float4(sumDiffuseIlluminationAnd2ndMoment.rgb, diffuseVariance); + gOutDiffuseIlluminationAndVariance[pixelPos] = filteredDiffuseIlluminationAndVariance; +#endif + } + else + // Running spatial variance estimation + { +#if( defined RELAX_SPECULAR ) + float sumWSpecularIllumination = 0; + float3 sumSpecularIllumination = 0; + float sumSpecular1stMoment = 0; + float sumSpecular2ndMoment = 0; +#endif + +#if( defined RELAX_DIFFUSE ) + float sumWDiffuseIllumination = 0; + float3 sumDiffuseIllumination = 0; + float sumDiffuse1stMoment = 0; + float sumDiffuse2ndMoment = 0; +#endif + + // Compute first and second moment spatially. This code also applies cross-bilateral + // filtering on the input illumination. + [unroll] + for (int cy = -2; cy <= 2; cy++) + { + [unroll] + for (int cx = -2; cx <= 2; cx++) + { + int2 sharedMemoryIndex = threadPos.xy + int2(BORDER + cx, BORDER + cy); + + float3 sampleNormal = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; + float sampleMaterialID = sharedMaterialID[sharedMemoryIndex.y][sharedMemoryIndex.x]; + + // Calculating weights + float depthW = 1.0;// TODO: should we take in account depth here? + float diffuseNormalWeightParams = GetNormalWeightParams(1.0, gDiffuseLobeAngleFraction); + float normalW = GetNormalWeight(diffuseNormalWeightParams, centerNormal, sampleNormal); + +#if( defined RELAX_SPECULAR ) + float4 sampleSpecular = sharedSpecular[sharedMemoryIndex.y][sharedMemoryIndex.x]; + float3 sampleSpecularIllumination = sampleSpecular.rgb; + float sampleSpecular1stMoment = STL::Color::Luminance(sampleSpecularIllumination); + float sampleSpecular2ndMoment = sampleSpecular.a; + float specularW = normalW * depthW; + specularW *= CompareMaterials(sampleMaterialID, centerMaterialID, gSpecMaterialMask); + + sumWSpecularIllumination += specularW; + sumSpecularIllumination += sampleSpecularIllumination.rgb * specularW; + sumSpecular1stMoment += sampleSpecular1stMoment * specularW; + sumSpecular2ndMoment += sampleSpecular2ndMoment * specularW; +#endif + +#if( defined RELAX_DIFFUSE ) + float4 sampleDiffuse = sharedDiffuse[sharedMemoryIndex.y][sharedMemoryIndex.x]; + float3 sampleDiffuseIllumination = sampleDiffuse.rgb; + float sampleDiffuse1stMoment = STL::Color::Luminance(sampleDiffuseIllumination); + float sampleDiffuse2ndMoment = sampleDiffuse.a; + float diffuseW = normalW * depthW; + diffuseW *= CompareMaterials(sampleMaterialID, centerMaterialID, gDiffMaterialMask); + + sumWDiffuseIllumination += diffuseW; + sumDiffuseIllumination += sampleDiffuseIllumination.rgb * diffuseW; + sumDiffuse1stMoment += sampleDiffuse1stMoment * diffuseW; + sumDiffuse2ndMoment += sampleDiffuse2ndMoment * diffuseW; +#endif + } + } + + float boost = max(1.0, 4.0 / (historyLength + 1.0)); + +#if( defined RELAX_SPECULAR ) + sumWSpecularIllumination = max(sumWSpecularIllumination, 1e-6f); + sumSpecularIllumination /= sumWSpecularIllumination; + sumSpecular1stMoment /= sumWSpecularIllumination; + sumSpecular2ndMoment /= sumWSpecularIllumination; + float specularVariance = max(0, sumSpecular2ndMoment - sumSpecular1stMoment * sumSpecular1stMoment); + specularVariance *= boost; + gOutSpecularIlluminationAndVariance[pixelPos] = float4(sumSpecularIllumination, specularVariance); +#endif + +#if( defined RELAX_DIFFUSE ) + sumWDiffuseIllumination = max(sumWDiffuseIllumination, 1e-6f); + sumDiffuseIllumination /= sumWDiffuseIllumination; + sumDiffuse1stMoment /= sumWDiffuseIllumination; + sumDiffuse2ndMoment /= sumWDiffuseIllumination; + float diffuseVariance = max(0, sumDiffuse2ndMoment - sumDiffuse1stMoment * sumDiffuse1stMoment); + diffuseVariance *= boost; + gOutDiffuseIlluminationAndVariance[pixelPos] = float4(sumDiffuseIllumination, diffuseVariance); +#endif + } + +} diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.resources.hlsli new file mode 100644 index 0000000..94c3d3e --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.resources.hlsli @@ -0,0 +1,109 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_Config.hlsli" +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationAnd2ndMoment, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationAnd2ndMoment, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularReprojectionConfidence, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 5 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutNormalRoughness, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutMaterialID, u, 3) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( uint2, gResourceSize ) \ + NRD_CONSTANT( uint, gHistoryThreshold ) \ + NRD_CONSTANT( float, gSpecularPhiLuminance ) \ + NRD_CONSTANT( float, gDiffusePhiLuminance ) \ + NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gDiffuseLobeAngleFraction ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANT( float, gSpecularLobeAngleFraction ) \ + NRD_CONSTANT( float, gSpecularLobeAngleSlack ) \ + NRD_CONSTANT( uint, gStepSize ) \ + NRD_CONSTANT( uint, gRoughnessEdgeStoppingEnabled ) \ + NRD_CONSTANT( float, gRoughnessEdgeStoppingRelaxation ) \ + NRD_CONSTANT( float, gNormalEdgeStoppingRelaxation ) \ + NRD_CONSTANT( float, gLuminanceEdgeStoppingRelaxation ) \ + NRD_CONSTANTS_END + +#elif( defined RELAX_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationAnd2ndMoment, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutNormalRoughness, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutMaterialID, u, 2 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( uint2, gResourceSize ) \ + NRD_CONSTANT( uint, gHistoryThreshold ) \ + NRD_CONSTANT( float, gDiffusePhiLuminance ) \ + NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gDiffuseLobeAngleFraction ) \ + NRD_CONSTANT( uint, gStepSize ) \ + NRD_CONSTANTS_END + +#elif( defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationAnd2ndMoment, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularReprojectionConfidence, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 4 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutNormalRoughness, u, 1 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutMaterialID, u, 2 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( uint2, gResourceSize ) \ + NRD_CONSTANT( uint, gHistoryThreshold ) \ + NRD_CONSTANT( float, gSpecularPhiLuminance ) \ + NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gDiffuseLobeAngleFraction ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANT( float, gSpecularLobeAngleFraction ) \ + NRD_CONSTANT( float, gSpecularLobeAngleSlack ) \ + NRD_CONSTANT( uint, gStepSize ) \ + NRD_CONSTANT( uint, gRoughnessEdgeStoppingEnabled ) \ + NRD_CONSTANT( float, gRoughnessEdgeStoppingRelaxation ) \ + NRD_CONSTANT( float, gNormalEdgeStoppingRelaxation ) \ + NRD_CONSTANT( float, gLuminanceEdgeStoppingRelaxation ) \ + NRD_CONSTANTS_END + +#endif + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/RELAX_DiffuseSpecular_ATrousStandard.cs.hlsl b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.hlsli similarity index 62% rename from Source/Shaders/RELAX_DiffuseSpecular_ATrousStandard.cs.hlsl rename to Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.hlsli index 60764a8..6febbe3 100644 --- a/Source/Shaders/RELAX_DiffuseSpecular_ATrousStandard.cs.hlsl +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.hlsli @@ -14,87 +14,95 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_DECLARE_CONSTANTS +// Default CTA size is 16x16 + #include "NRD_Common.hlsli" + NRD_DECLARE_SAMPLERS + #include "RELAX_Common.hlsli" NRD_DECLARE_INPUT_TEXTURES NRD_DECLARE_OUTPUT_TEXTURES -// Helper functions -float2 getRoughnessWeightParams(float roughness0, float specularReprojectionConfidence) +[numthreads(GROUP_X, GROUP_Y, 1)] +NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId) { - float a = 1.0 / (0.001 + 0.999 * roughness0 * (0.333 + gRoughnessEdgeStoppingRelaxation * (1.0 - specularReprojectionConfidence))); - float b = roughness0 * a; - return float2(a, b); -} - -float getRoughnessWeight(float2 params0, float roughness) -{ - return saturate(1.0 - abs(params0.y - roughness * params0.x)); -} - -[numthreads(16, 16, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId) -{ - uint centerMaterialType; - float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos], centerMaterialType); - float3 centerNormal = centerNormalRoughness.rgb; - float centerRoughness = centerNormalRoughness.a; - - float centerViewZ = gViewZFP16[ipos] / NRD_FP16_VIEWZ_SCALE; + float centerMaterialID; + float centerViewZ = gViewZFP16[pixelPos] / NRD_FP16_VIEWZ_SCALE; // Early out if linearZ is beyond denoising range [branch] if (centerViewZ > gDenoisingRange) { #if( RELAX_BLACK_OUT_INF_PIXELS == 1 ) - gOutSpecularIlluminationAndVariance[ipos] = 0; - gOutDiffuseIlluminationAndVariance[ipos] = 0; +#if( defined RELAX_SPECULAR ) + gOutSpecularIlluminationAndVariance[pixelPos] = 0; +#endif +#if( defined RELAX_DIFFUSE ) + gOutDiffuseIlluminationAndVariance[pixelPos] = 0; +#endif #endif return; } - float4 centerSpecularIlluminationAndVariance = gSpecularIlluminationAndVariance[ipos]; - float centerSpecularLuminance = STL::Color::Luminance(centerSpecularIlluminationAndVariance.rgb); + float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[pixelPos], centerMaterialID); + float3 centerNormal = centerNormalRoughness.rgb; + float centerRoughness = centerNormalRoughness.a; + float historyLength; +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + // If both RELAX_DIFFUSE and RELAX_SPECULAR are defined, then history length texture is 2-channel + historyLength = 255.0 * gHistoryLength[pixelPos].y; +#else + historyLength = 255.0 * gHistoryLength[pixelPos]; +#endif - float4 centerDiffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[ipos]; - float centerDiffuseLuminance = STL::Color::Luminance(centerDiffuseIlluminationAndVariance.rgb); - float specularReprojectionConfidence = gSpecularReprojectionConfidence[ipos]; +#if( defined RELAX_SPECULAR ) + float4 centerSpecularIlluminationAndVariance = gSpecularIlluminationAndVariance[pixelPos]; + float centerSpecularLuminance = STL::Color::Luminance(centerSpecularIlluminationAndVariance.rgb); + float centerSpecularVar = centerSpecularIlluminationAndVariance.a; + float specularReprojectionConfidence = gSpecularReprojectionConfidence[pixelPos]; float specularLuminanceWeightRelaxation = 1.0; if (gStepSize <= 4) { specularLuminanceWeightRelaxation = lerp(1.0, specularReprojectionConfidence, gLuminanceEdgeStoppingRelaxation); } - // Variance, NOT filtered using 3x3 gaussin blur, as we don't need this in other than 1st Atrous pass - float centerSpecularVar = centerSpecularIlluminationAndVariance.a; - float centerDiffuseVar = centerDiffuseIlluminationAndVariance.a; - - float2 roughnessWeightParams = getRoughnessWeightParams(centerRoughness, specularReprojectionConfidence); - float2 normalWeightParams = GetNormalWeightParams_ATrous(centerRoughness, 255.0 * gHistoryLength[ipos].y, specularReprojectionConfidence, gNormalEdgeStoppingRelaxation, gSpecularLobeAngleFraction); - - float3 centerWorldPos = GetCurrentWorldPos(ipos, centerViewZ); - float3 centerV = normalize(centerWorldPos); - - float specularPhiLIllumination = 1.0e-4 + gSpecularPhiLuminance * sqrt(max(0.0, centerSpecularVar)); - float diffusePhiLIllumination = 1.0e-4 + gDiffusePhiLuminance * sqrt(max(0.0, centerDiffuseVar)); - float depthThreshold = gDepthThreshold; +#if( defined RELAX_SPECULAR ) + float specularPhiLIllumination = gSpecularPhiLuminance * max(1.0e-4, sqrt(centerSpecularVar)); + float2 roughnessWeightParams = GetRoughnessWeightParams(centerRoughness, gRoughnessFraction); +#endif - static const float kernelWeightGaussian3x3[2] = { 0.44198, 0.27901 }; + float2 normalWeightParams = GetNormalWeightParams_ATrous(centerRoughness, historyLength, specularReprojectionConfidence, gNormalEdgeStoppingRelaxation, gSpecularLobeAngleFraction); float sumWSpecular = 0.44198 * 0.44198; float4 sumSpecularIlluminationAndVariance = centerSpecularIlluminationAndVariance * float4(sumWSpecular.xxx, sumWSpecular * sumWSpecular); +#endif + +#if( defined RELAX_DIFFUSE ) + float4 centerDiffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[pixelPos]; + float centerDiffuseLuminance = STL::Color::Luminance(centerDiffuseIlluminationAndVariance.rgb); + float centerDiffuseVar = centerDiffuseIlluminationAndVariance.a; + float diffusePhiLIllumination = gDiffusePhiLuminance * max(1.0e-4, sqrt(centerDiffuseVar)); float sumWDiffuse = 0.44198 * 0.44198; float4 sumDiffuseIlluminationAndVariance = centerDiffuseIlluminationAndVariance * float4(sumWDiffuse.xxx, sumWDiffuse * sumWDiffuse); +#endif + + float3 centerWorldPos = GetCurrentWorldPosFromPixelPos(pixelPos, centerViewZ); + + // Normal weight strictness is higher as the Atrous step size increases + float diffuseLobeAngleFraction = gDiffuseLobeAngleFraction / sqrt(gStepSize); + diffuseLobeAngleFraction = lerp(0.99, diffuseLobeAngleFraction, saturate(historyLength / 5.0)); + + static const float kernelWeightGaussian3x3[2] = { 0.44198, 0.27901 }; // Adding random offsets to minimize "ringing" at large A-Trous steps uint2 offset = 0; if (gStepSize > 4) { - STL::Rng::Initialize(ipos, gFrameIndex); + STL::Rng::Initialize(pixelPos, gFrameIndex); offset = int2(gStepSize.xx * 0.5 * (STL::Rng::GetFloat2() - 0.5)); } @@ -104,51 +112,42 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId) [unroll] for (int xx = -1; xx <= 1; xx++) { - int2 p = ipos + offset + int2(xx, yy) * gStepSize; - bool isInside = all(p >= int2(0, 0)) && all(p < int2(gRectSize)); + int2 p = pixelPos + offset + int2(xx, yy) * gStepSize; bool isCenter = ((xx == 0) && (yy == 0)); if (isCenter) continue; - float kernel = kernelWeightGaussian3x3[abs(xx)] * kernelWeightGaussian3x3[abs(yy)]; - - // Discarding out of screen samples - float wSpecular = isInside ? kernel : 0.0; - float wDiffuse = isInside ? kernel : 0.0; + bool isInside = all(p >= int2(0, 0)) && all(p < int2(gRectSize)); + float kernel = isInside ? kernelWeightGaussian3x3[abs(xx)] * kernelWeightGaussian3x3[abs(yy)] : 0.0; // Fetching normal, roughness, linear Z - uint sampleMaterialType; - float4 sampleNormalRoughnes = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[p], sampleMaterialType); + float sampleMaterialID; + float4 sampleNormalRoughnes = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[p], sampleMaterialID); float3 sampleNormal = sampleNormalRoughnes.rgb; float sampleRoughness = sampleNormalRoughnes.a; float sampleViewZ = gViewZFP16[p] / NRD_FP16_VIEWZ_SCALE; // Calculating sample world position - float3 sampleWorldPos = GetCurrentWorldPos(p, sampleViewZ); + float3 sampleWorldPos = GetCurrentWorldPosFromPixelPos(p, sampleViewZ); // Calculating geometry weight for diffuse and specular float geometryW = GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - depthThreshold); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - geometryW *= (sampleMaterialType == centerMaterialType) ? 1.0 : 0.0; -#endif - - // Calculating normal weights for diffuse and specular - float normalWSpecular = GetSpecularNormalWeight_ATrous(normalWeightParams, gSpecularLobeAngleSlack, centerNormal, sampleNormal); - float normalWDiffuse = GetDiffuseNormalWeight_ATrous(centerNormal, sampleNormal, gPhiNormal); + centerWorldPos, + centerNormal, + gOrthoMode == 0 ? centerViewZ : 1.0, + sampleWorldPos, + gDepthThreshold); - // Calculating roughness weight for specular - float roughnessWSpecular = getRoughnessWeight(roughnessWeightParams, sampleRoughness); + float diffuseNormalWeightParams = GetNormalWeightParams(1.0, diffuseLobeAngleFraction); + float normalWDiffuse = GetNormalWeight(diffuseNormalWeightParams, centerNormal, sampleNormal); - // Applying all the weights except luminance weights - wDiffuse *= geometryW * normalWDiffuse; - wSpecular *= geometryW * (gRoughnessEdgeStoppingEnabled ? (normalWSpecular * roughnessWSpecular) : normalWDiffuse); +#if( defined RELAX_SPECULAR ) + // Calculating weights for specular + float normalWSpecular = GetSpecularNormalWeight_ATrous(normalWeightParams, gSpecularLobeAngleSlack, centerNormal, sampleNormal); + float roughnessWSpecular = GetRoughnessWeight(roughnessWeightParams, sampleRoughness); // Summing up specular + float wSpecular = kernel * geometryW * (gRoughnessEdgeStoppingEnabled ? (normalWSpecular * roughnessWSpecular) : normalWDiffuse); + wSpecular *= CompareMaterials(sampleMaterialID, centerMaterialID, gSpecMaterialMask); if (wSpecular > 1e-4) { float4 sampleSpecularIlluminationAndVariance = gSpecularIlluminationAndVariance[p]; @@ -163,8 +162,12 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId) sumSpecularIlluminationAndVariance += float4(wSpecular.xxx, wSpecular * wSpecular) * sampleSpecularIlluminationAndVariance; sumWSpecular += wSpecular; } +#endif +#if( defined RELAX_DIFFUSE ) // Summing up diffuse + float wDiffuse = kernel * geometryW * normalWDiffuse; + wDiffuse *= CompareMaterials(sampleMaterialID, centerMaterialID, gDiffMaterialMask); if (wDiffuse > 1e-4) { float4 sampleDiffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[p]; @@ -177,12 +180,18 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId) sumDiffuseIlluminationAndVariance += float4(wDiffuse.xxx, wDiffuse * wDiffuse) * sampleDiffuseIlluminationAndVariance; sumWDiffuse += wDiffuse; } +#endif } } + +#if( defined RELAX_SPECULAR ) float4 filteredSpecularIlluminationAndVariance = float4(sumSpecularIlluminationAndVariance / float4(sumWSpecular.xxx, sumWSpecular * sumWSpecular)); - float4 filteredDiffuseIlluminationAndVariance = float4(sumDiffuseIlluminationAndVariance / float4(sumWDiffuse.xxx, sumWDiffuse * sumWDiffuse)); + gOutSpecularIlluminationAndVariance[pixelPos] = filteredSpecularIlluminationAndVariance; +#endif - gOutSpecularIlluminationAndVariance[ipos] = filteredSpecularIlluminationAndVariance; - gOutDiffuseIlluminationAndVariance[ipos] = filteredDiffuseIlluminationAndVariance; +#if( defined RELAX_DIFFUSE ) + float4 filteredDiffuseIlluminationAndVariance = float4(sumDiffuseIlluminationAndVariance / float4(sumWDiffuse.xxx, sumWDiffuse * sumWDiffuse)); + gOutDiffuseIlluminationAndVariance[pixelPos] = filteredDiffuseIlluminationAndVariance; +#endif } diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.resources.hlsli new file mode 100644 index 0000000..3e8e40a --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.resources.hlsli @@ -0,0 +1,97 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_Config.hlsli" +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationAndVariance, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationAndVariance, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularReprojectionConfidence, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 5 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 1 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gSpecularPhiLuminance ) \ + NRD_CONSTANT( float, gDiffusePhiLuminance ) \ + NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gDiffuseLobeAngleFraction ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANT( float, gSpecularLobeAngleFraction ) \ + NRD_CONSTANT( float, gSpecularLobeAngleSlack ) \ + NRD_CONSTANT( uint, gStepSize ) \ + NRD_CONSTANT( uint, gRoughnessEdgeStoppingEnabled ) \ + NRD_CONSTANT( float, gRoughnessEdgeStoppingRelaxation ) \ + NRD_CONSTANT( float, gNormalEdgeStoppingRelaxation ) \ + NRD_CONSTANT( float, gLuminanceEdgeStoppingRelaxation ) \ + NRD_CONSTANTS_END + +#elif( defined RELAX_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationAndVariance, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 0 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gDiffusePhiLuminance ) \ + NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gDiffuseLobeAngleFraction ) \ + NRD_CONSTANT( uint, gStepSize ) \ + NRD_CONSTANTS_END + +#elif( defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationAndVariance, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularReprojectionConfidence, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 4 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gSpecularPhiLuminance ) \ + NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gDiffuseLobeAngleFraction ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANT( float, gSpecularLobeAngleFraction ) \ + NRD_CONSTANT( float, gSpecularLobeAngleSlack ) \ + NRD_CONSTANT( uint, gStepSize ) \ + NRD_CONSTANT( uint, gRoughnessEdgeStoppingEnabled ) \ + NRD_CONSTANT( float, gRoughnessEdgeStoppingRelaxation ) \ + NRD_CONSTANT( float, gNormalEdgeStoppingRelaxation ) \ + NRD_CONSTANT( float, gLuminanceEdgeStoppingRelaxation ) \ + NRD_CONSTANTS_END + +#endif + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/RELAX_DiffuseSpecular_DisocclusionFix.cs.hlsl b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.hlsli similarity index 51% rename from Source/Shaders/RELAX_DiffuseSpecular_DisocclusionFix.cs.hlsl rename to Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.hlsli index f0f4e2e..bbc9786 100644 --- a/Source/Shaders/RELAX_DiffuseSpecular_DisocclusionFix.cs.hlsl +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.hlsli @@ -14,8 +14,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_DECLARE_CONSTANTS +#define NRD_CTA_8X8 + #include "NRD_Common.hlsli" + NRD_DECLARE_SAMPLERS + #include "RELAX_Common.hlsli" NRD_DECLARE_INPUT_TEXTURES @@ -27,44 +31,20 @@ float getDiffuseNormalWeight(float3 centerNormal, float3 pointNormal) return pow(max(0.01, dot(centerNormal, pointNormal)), max(gDisocclusionFixEdgeStoppingNormalPower, 0.01)); } -float GetRadius(float numFramesInHistory) +float getRadius(float numFramesInHistory) { return gMaxRadius / (numFramesInHistory + 1.0); } -float getSpecularLobeHalfAngle(float roughness) -{ - // Defines a cone angle, where micro-normals are distributed - float r2 = roughness * roughness; - float r3 = roughness * r2; - return 3.141592 * r2 / (1.0 + 0.5 * r2 + r3); -} - -float2 getNormalWeightParams(float roughness, float numFramesInHistory) -{ - // This is the main parameter - cone angle - float angle = 0.33 * getSpecularLobeHalfAngle(roughness); - return float2(angle, 1.0); -} - -float getSpecularRWeight(float2 params0, float3 v0, float3 v) -{ - float cosa = saturate(dot(v0, v)); - float a = STL::Math::AcosApprox(cosa); - a = 1.0 - STL::Math::SmoothStep(0.0, params0.x, a); - return saturate(1.0 + (a - 1.0) * params0.y); -} - // // Main // -[numthreads(8, 8, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId) +[numthreads(GROUP_X, GROUP_Y, 1)] +NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId) { - const int2 ipos = int2(dispatchThreadId.xy); - float centerViewZ = gViewZFP16[ipos] / NRD_FP16_VIEWZ_SCALE; + float centerViewZ = gViewZFP16[pixelPos] / NRD_FP16_VIEWZ_SCALE; // Early out if linearZ is beyond denoising range [branch] @@ -73,40 +53,58 @@ NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId) return; } - float historyLength = 255.0 * gSpecularAndDiffuseHistoryLength[ipos].g; // Using diffuse history length to control disocclusion fix - float4 specularIlluminationAnd2ndMoment = gSpecularIllumination[ipos]; - float4 diffuseIlluminationAnd2ndMoment = gDiffuseIllumination[ipos]; - float4 specularIlluminationResponsive = gSpecularIlluminationResponsive[ipos]; - float4 diffuseIlluminationResponsive = gDiffuseIlluminationResponsive[ipos]; +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + // If both RELAX_DIFFUSE and RELAX_SPECULAR are defined, then history length texture is 2-channel + // Using diffuse history length to control disocclusion fix + float historyLength = 255.0 * gHistoryLength[pixelPos].y; +#else + float historyLength = 255.0 * gHistoryLength[pixelPos]; +#endif + +#if( defined RELAX_DIFFUSE ) + float4 diffuseIlluminationAnd2ndMoment = gDiffuseIllumination[pixelPos]; + float4 diffuseIlluminationResponsive = gDiffuseIlluminationResponsive[pixelPos]; +#endif +#if( defined RELAX_SPECULAR ) + float4 specularIlluminationAnd2ndMoment = gSpecularIllumination[pixelPos]; + float4 specularIlluminationResponsive = gSpecularIlluminationResponsive[pixelPos]; +#endif + // Pass through the input data if no disocclusion detected [branch] if (historyLength > gFramesToFix) { - gOutSpecularIllumination[ipos] = specularIlluminationAnd2ndMoment; - gOutDiffuseIllumination[ipos] = diffuseIlluminationAnd2ndMoment; - gOutSpecularIlluminationResponsive[ipos] = specularIlluminationResponsive; - gOutDiffuseIlluminationResponsive[ipos] = diffuseIlluminationResponsive; +#if( defined RELAX_DIFFUSE ) + gOutDiffuseIllumination[pixelPos] = diffuseIlluminationAnd2ndMoment; + gOutDiffuseIlluminationResponsive[pixelPos] = diffuseIlluminationResponsive; +#endif +#if( defined RELAX_SPECULAR ) + gOutSpecularIllumination[pixelPos] = specularIlluminationAnd2ndMoment; + gOutSpecularIlluminationResponsive[pixelPos] = specularIlluminationResponsive; +#endif return; } - // Unpacking the rest of center data - float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos]); + // Loading center data + float centerMaterialID; + float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[pixelPos], centerMaterialID); float3 centerNormal = centerNormalRoughness.rgb; float centerRoughness = centerNormalRoughness.a; - float3 centerWorldPos = GetCurrentWorldPos(ipos, centerViewZ); - float3 centerV = normalize(centerWorldPos); - float3 centerR = reflect(centerV, centerNormal); - float2 normalWeightParams = getNormalWeightParams(centerRoughness, historyLength); + float3 centerWorldPos = GetCurrentWorldPosFromPixelPos(pixelPos, centerViewZ); + float normalWeightParams = GetNormalWeightParams(centerRoughness, 0.33); // Running sparse cross-bilateral filter - float4 specularIlluminationAnd2ndMomentSum = specularIlluminationAnd2ndMoment; +#if( defined RELAX_DIFFUSE ) float4 diffuseIlluminationAnd2ndMomentSum = diffuseIlluminationAnd2ndMoment; - float diffuseWSum = 1; +#endif +#if( defined RELAX_SPECULAR ) + float4 specularIlluminationAnd2ndMomentSum = specularIlluminationAnd2ndMoment; float specularWSum = 1; +#endif - float r = GetRadius(historyLength); + float r = getRadius(historyLength); [unroll] for (int j = -2; j <= 2; j++) @@ -116,60 +114,62 @@ NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId) int dx = (int)(i * r); int dy = (int)(j * r); - int2 samplePosInt = (int2)ipos + int2(dx, dy); + int2 samplePosInt = (int2)pixelPos + int2(dx, dy); bool isInside = all(samplePosInt >= int2(0, 0)) && all(samplePosInt < (int2)gRectSize); if ((i == 0) && (j == 0)) continue; - float3 sampleNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[samplePosInt]).rgb; + float sampleMaterialID; + float3 sampleNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[samplePosInt], sampleMaterialID).rgb; float sampleViewZ = gViewZFP16[samplePosInt] / NRD_FP16_VIEWZ_SCALE; - - // Edge stopping functions: - // ..normal - float diffuseW = getDiffuseNormalWeight(centerNormal, sampleNormal); - - // ..geometry - float3 sampleWorldPos = GetCurrentWorldPos(samplePosInt, sampleViewZ); + float3 sampleWorldPos = GetCurrentWorldPosFromPixelPos(samplePosInt, sampleViewZ); float geometryWeight = GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - gDepthThreshold); - float specularW = geometryWeight; - diffuseW *= geometryWeight; - diffuseW *= isInside ? 1.0 : 0; - - // ..specular lobe - float3 sampleV = normalize(sampleWorldPos); - float3 sampleR = reflect(sampleV, sampleNormal); - specularW *= getSpecularRWeight(normalWeightParams, sampleR, centerR); - specularW *= isInside ? 1.0 : 0; + centerWorldPos, + centerNormal, + gOrthoMode == 0 ? centerViewZ : 1.0, + sampleWorldPos, + gDepthThreshold); +#if( defined RELAX_DIFFUSE ) // Summing up diffuse result + float diffuseW = geometryWeight; + diffuseW *= getDiffuseNormalWeight(centerNormal, sampleNormal); + diffuseW = isInside ? diffuseW : 0; + diffuseW *= CompareMaterials(sampleMaterialID, centerMaterialID, gDiffMaterialMask); + if (diffuseW > 1e-4) { float4 sampleDiffuseIlluminationAnd2ndMoment = gDiffuseIllumination[samplePosInt]; diffuseIlluminationAnd2ndMomentSum += sampleDiffuseIlluminationAnd2ndMoment * diffuseW; diffuseWSum += diffuseW; } - +#endif +#if( defined RELAX_SPECULAR ) // Summing up specular result + float specularW = geometryWeight; + specularW *= GetNormalWeight(normalWeightParams, centerNormal, sampleNormal); + specularW = isInside ? specularW : 0; + specularW *= CompareMaterials(sampleMaterialID, centerMaterialID, gSpecMaterialMask); + if (specularW > 1e-4) { float4 sampleSpecularIlluminationAnd2ndMoment = gSpecularIllumination[samplePosInt]; specularIlluminationAnd2ndMomentSum += sampleSpecularIlluminationAnd2ndMoment * specularW; specularWSum += specularW; } +#endif } - float4 outSpecularIlluminationAnd2ndMoment = specularIlluminationAnd2ndMomentSum / specularWSum; +#if( defined RELAX_DIFFUSE ) float4 outDiffuseIlluminationAnd2ndMoment = diffuseIlluminationAnd2ndMomentSum / diffuseWSum; + gOutDiffuseIllumination[pixelPos] = outDiffuseIlluminationAnd2ndMoment; + gOutDiffuseIlluminationResponsive[pixelPos] = outDiffuseIlluminationAnd2ndMoment; +#endif - // Writing out the results - gOutSpecularIllumination[ipos] = outSpecularIlluminationAnd2ndMoment; - gOutDiffuseIllumination[ipos] = outDiffuseIlluminationAnd2ndMoment; - gOutSpecularIlluminationResponsive[ipos] = outSpecularIlluminationAnd2ndMoment; - gOutDiffuseIlluminationResponsive[ipos] = outDiffuseIlluminationAnd2ndMoment; +#if( defined RELAX_SPECULAR ) + float4 outSpecularIlluminationAnd2ndMoment = specularIlluminationAnd2ndMomentSum / specularWSum; + gOutSpecularIllumination[pixelPos] = outSpecularIlluminationAnd2ndMoment; + gOutSpecularIlluminationResponsive[pixelPos] = outSpecularIlluminationAnd2ndMoment; +#endif } diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.resources.hlsli new file mode 100644 index 0000000..2a6ee76 --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.resources.hlsli @@ -0,0 +1,66 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_Config.hlsli" +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationResponsive, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationResponsive, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 6 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationResponsive, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationResponsive, u, 3 ) + +#elif( defined RELAX_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationResponsive, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 4 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationResponsive, u, 1 ) + +#elif( defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationResponsive, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 4 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationResponsive, u, 1 ) +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gDisocclusionFixEdgeStoppingNormalPower ) \ + NRD_CONSTANT( float, gMaxRadius ) \ + NRD_CONSTANT( int, gFramesToFix ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.hlsli new file mode 100644 index 0000000..6c66ad4 --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.hlsli @@ -0,0 +1,246 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "NRD.hlsli" +#include "STL.hlsli" +#include "RELAX_DiffuseSpecular_Firefly.resources.hlsli" + +NRD_DECLARE_CONSTANTS + +// Default CTA size is 16x16 +#define NRD_USE_BORDER_1 + +#include "NRD_Common.hlsli" + +NRD_DECLARE_SAMPLERS + +#include "RELAX_Common.hlsli" + +NRD_DECLARE_INPUT_TEXTURES +NRD_DECLARE_OUTPUT_TEXTURES + +#if( defined RELAX_SPECULAR ) + groupshared float4 sharedSpecular[BUFFER_X][BUFFER_Y]; +#endif + +#if( defined RELAX_DIFFUSE ) + groupshared float4 sharedDiffuse[BUFFER_X][BUFFER_Y]; +#endif + +groupshared float4 sharedNormalAndViewZ[BUFFER_X][BUFFER_Y]; + +// Helper functions +float edgeStoppingDepth(float centerViewZ, float sampleViewZ) +{ + return (abs(centerViewZ - sampleViewZ) / (centerViewZ + 1e-6)) < 0.1 ? 1.0 : 0.0; +} + +void Preload(uint2 sharedPos, int2 globalPos) +{ + globalPos = clamp(globalPos, 0, gRectSize - 1.0); + +#if( defined RELAX_SPECULAR ) + sharedSpecular[sharedPos.y][sharedPos.x] = gSpecularIllumination[globalPos]; +#endif + +#if( defined RELAX_DIFFUSE ) + sharedDiffuse[sharedPos.y][sharedPos.x] = gDiffuseIllumination[globalPos]; +#endif + + float3 normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[globalPos]).rgb; + float viewZ = gViewZFP16[globalPos] / NRD_FP16_VIEWZ_SCALE; + sharedNormalAndViewZ[sharedPos.y][sharedPos.x] = float4(normal, viewZ); +} + + + +// Cross bilateral Rank-Conditioned Rank-Selection (RCRS) filter +void runRCRS( + int2 pixelPos, + int2 threadPos, + float3 centerNormal, + float centerViewZ +#if( defined RELAX_SPECULAR ) + ,out float4 outSpecular +#endif +#if( defined RELAX_DIFFUSE ) + ,out float4 outDiffuse +#endif + ) +{ + // Fetching center data + uint2 sharedMemoryIndex = threadPos + int2(BORDER, BORDER); + +#if( defined RELAX_SPECULAR ) + float4 s = sharedSpecular[sharedMemoryIndex.y][sharedMemoryIndex.x]; + float3 specularIlluminationCenter = s.rgb; + float specular2ndMomentCenter = s.a; + float specularLuminanceCenter = STL::Color::Luminance(specularIlluminationCenter); + + float maxSpecularLuminance = -1.0; + float minSpecularLuminance = 1.0e6; + int2 maxSpecularLuminanceCoords = sharedMemoryIndex; + int2 minSpecularLuminanceCoords = sharedMemoryIndex; +#endif + +#if( defined RELAX_DIFFUSE ) + float4 d = sharedDiffuse[sharedMemoryIndex.y][sharedMemoryIndex.x]; + float3 diffuseIlluminationCenter = d.rgb; + float diffuse2ndMomentCenter = d.a; + float diffuseLuminanceCenter = STL::Color::Luminance(diffuseIlluminationCenter); + + float maxDiffuseLuminance = -1.0; + float minDiffuseLuminance = 1.0e6; + int2 maxDiffuseLuminanceCoords = sharedMemoryIndex; + int2 minDiffuseLuminanceCoords = sharedMemoryIndex; +#endif + + [unroll] + for (int yy = -1; yy <= 1; yy++) + { + [unroll] + for (int xx = -1; xx <= 1; xx++) + { + int2 p = pixelPos + int2(xx, yy); + int2 sharedMemoryIndexSample = threadPos + int2(BORDER, BORDER) + int2(xx,yy); + + if ((xx == 0) && (yy == 0)) continue; + if (any(p < int2(0, 0)) || any(p >= (int2)gRectSize)) continue; + + // Fetching sample data + float4 v = sharedNormalAndViewZ[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x]; + float3 sampleNormal = v.xyz; + float sampleViewZ = v.w; + +#if( defined RELAX_SPECULAR ) + float3 specularIlluminationSample = sharedSpecular[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x].rgb; + float specularLuminanceSample = STL::Color::Luminance(specularIlluminationSample); +#endif + +#if( defined RELAX_DIFFUSE ) + float3 diffuseIlluminationSample = sharedDiffuse[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x].rgb; + float diffuseLuminanceSample = STL::Color::Luminance(diffuseIlluminationSample); +#endif + + // Applying weights + // ..normal weight + float weight = dot(centerNormal, sampleNormal) > 0.99 ? 1.0 : 0.0; + + // ..depth weight + weight *= edgeStoppingDepth(centerViewZ, sampleViewZ); + + if(weight > 0) + { +#if( defined RELAX_SPECULAR ) + if(specularLuminanceSample > maxSpecularLuminance) + { + maxSpecularLuminance = specularLuminanceSample; + maxSpecularLuminanceCoords = sharedMemoryIndexSample; + } + if(specularLuminanceSample < minSpecularLuminance) + { + minSpecularLuminance = specularLuminanceSample; + minSpecularLuminanceCoords = sharedMemoryIndexSample; + } +#endif + +#if( defined RELAX_DIFFUSE ) + if(diffuseLuminanceSample > maxDiffuseLuminance) + { + maxDiffuseLuminance = diffuseLuminanceSample; + maxDiffuseLuminanceCoords = sharedMemoryIndexSample; + } + if(diffuseLuminanceSample < minDiffuseLuminance) + { + minDiffuseLuminance = diffuseLuminanceSample; + minDiffuseLuminanceCoords = sharedMemoryIndexSample; + } +#endif + + } + } + } + + // Replacing current value with min or max in the neighborhood if outside min..max range, + // or leaving sample as it is if it's within the range +#if( defined RELAX_SPECULAR ) + int2 specularCoords = sharedMemoryIndex; + if(specularLuminanceCenter > maxSpecularLuminance) + { + specularCoords = maxSpecularLuminanceCoords; + } + if(specularLuminanceCenter < minSpecularLuminance) + { + specularCoords = minSpecularLuminanceCoords; + } + outSpecular = float4(sharedSpecular[specularCoords.y][specularCoords.x].rgb, specular2ndMomentCenter); +#endif + +#if( defined RELAX_DIFFUSE ) + int2 diffuseCoords = sharedMemoryIndex; + if(diffuseLuminanceCenter > maxDiffuseLuminance) + { + diffuseCoords = maxDiffuseLuminanceCoords; + } + if(diffuseLuminanceCenter < minDiffuseLuminance) + { + diffuseCoords = minDiffuseLuminanceCoords; + } + outDiffuse = float4(sharedDiffuse[diffuseCoords.y][diffuseCoords.x].rgb, diffuse2ndMomentCenter); +#endif +} + +[numthreads(GROUP_X, GROUP_Y, 1)] +NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPos : SV_GroupThreadId, uint threadIndex : SV_GroupIndex) +{ + PRELOAD_INTO_SMEM; + + // Shared memory is populated now and can be used for filtering + float4 v = sharedNormalAndViewZ[threadPos.y + BORDER][threadPos.x + BORDER]; + float3 centerNormal = v.xyz; + float centerViewZ = v.w; + + // Early out if linearZ is beyond denoising range + [branch] + if (centerViewZ > gDenoisingRange) + { + return; + } + + // Running firefly filter +#if( defined RELAX_SPECULAR ) + float4 outSpecularIlluminationAnd2ndMoment; +#endif + +#if( defined RELAX_DIFFUSE ) + float4 outDiffuseIlluminationAnd2ndMoment; +#endif + + runRCRS( + pixelPos.xy, + threadPos.xy, + centerNormal, + centerViewZ +#if( defined RELAX_SPECULAR ) + ,outSpecularIlluminationAnd2ndMoment +#endif +#if( defined RELAX_DIFFUSE ) + ,outDiffuseIlluminationAnd2ndMoment +#endif + ); + +#if( defined RELAX_SPECULAR ) + gOutSpecularIllumination[pixelPos.xy] = outSpecularIlluminationAnd2ndMoment; +#endif + +#if( defined RELAX_DIFFUSE ) + gOutDiffuseIllumination[pixelPos.xy] = outDiffuseIlluminationAnd2ndMoment; +#endif +} diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.resources.hlsli new file mode 100644 index 0000000..36a99f2 --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.resources.hlsli @@ -0,0 +1,52 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_Config.hlsli" +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) + +#elif( defined RELAX_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 1 ) \ + NRD_INPUT_TEXTURE(Texture2D, gViewZFP16, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) + +#elif( defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) + +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.hlsli new file mode 100644 index 0000000..15104f1 --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.hlsli @@ -0,0 +1,159 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "NRD.hlsli" +#include "STL.hlsli" +#include "RELAX_DiffuseSpecular_HistoryClamping.resources.hlsli" + +NRD_DECLARE_CONSTANTS + +// Default CTA size is 16x16 +#define NRD_USE_BORDER_2 + +#include "NRD_Common.hlsli" + +NRD_DECLARE_SAMPLERS + +#include "RELAX_Common.hlsli" + +NRD_DECLARE_INPUT_TEXTURES +NRD_DECLARE_OUTPUT_TEXTURES + +#if( defined RELAX_SPECULAR ) + groupshared float4 sharedSpecular[GROUP_Y + BORDER * 2][GROUP_X + BORDER * 2]; +#endif + +#if( defined RELAX_DIFFUSE ) + groupshared float4 sharedDiffuse[GROUP_Y + BORDER * 2][GROUP_X + BORDER * 2]; +#endif + +void Preload(uint2 sharedPos, int2 globalPos) +{ + globalPos = clamp(globalPos, 0, gRectSize - 1.0); + + #if( defined RELAX_SPECULAR ) + float3 specularResponsive = gSpecularIlluminationResponsive[globalPos].rgb; + sharedSpecular[sharedPos.y][sharedPos.x] = float4(STL::Color::LinearToYCoCg(specularResponsive), 0); + #endif + + #if( defined RELAX_DIFFUSE ) + float3 diffuseResponsive = gDiffuseIlluminationResponsive[globalPos].rgb; + sharedDiffuse[sharedPos.y][sharedPos.x] = float4(STL::Color::LinearToYCoCg(diffuseResponsive), 0); + #endif +} + +[numthreads(GROUP_X, GROUP_Y, 1)] +NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPos : SV_GroupThreadId, uint threadIndex : SV_GroupIndex) +{ + PRELOAD_INTO_SMEM; + // Shared memory is populated with responsive history now and can be used for history clamping + + // Reading history length +#if( defined RELAX_SPECULAR && defined RELAX_DIFFUSE) + float2 specularAndDiffuseHistoryLength = gSpecularAndDiffuseHistoryLength[pixelPos]; +#elif( defined RELAX_SPECULAR ) + float specularHistoryLength = gSpecularHistoryLength[pixelPos]; +#else + float diffuseHistoryLength = gDiffuseHistoryLength[pixelPos]; +#endif + + // Reading normal history +#if( defined RELAX_SPECULAR ) + float4 specularIlluminationAnd2ndMoment = gSpecularIllumination[pixelPos]; + float3 specularYCoCg = STL::Color::LinearToYCoCg(specularIlluminationAnd2ndMoment.rgb); + float3 specularFirstMoment = 0; + float3 specularSecondMoment = 0; +#endif + +#if( defined RELAX_DIFFUSE ) + float4 diffuseIlluminationAnd2ndMoment = gDiffuseIllumination[pixelPos]; + float3 diffuseYCoCg = STL::Color::LinearToYCoCg(diffuseIlluminationAnd2ndMoment.rgb); + float3 diffuseFirstMoment = 0; + float3 diffuseSecondMoment = 0; +#endif + + // Running history clamping + uint2 sharedMemoryIndex = threadPos.xy + int2(BORDER, BORDER); + [unroll] + for (int dy = -2; dy <= 2; dy++) + { + [unroll] + for (int dx = -2; dx <= 2; dx++) + { + uint2 sharedMemoryIndexP = sharedMemoryIndex + int2(dx, dy); + int2 p = pixelPos.xy + int2(dx, dy); + if (any(p < int2(0, 0)) || any(p >= (int2)gRectSize)) sharedMemoryIndexP = sharedMemoryIndex; + +#if( defined RELAX_SPECULAR ) + float3 specularP = sharedSpecular[sharedMemoryIndexP.y][sharedMemoryIndexP.x].rgb; + specularFirstMoment += specularP; + specularSecondMoment += specularP * specularP; +#endif + +#if( defined RELAX_DIFFUSE ) + float3 diffuseP = sharedDiffuse[sharedMemoryIndexP.y][sharedMemoryIndexP.x].rgb; + diffuseFirstMoment += diffuseP; + diffuseSecondMoment += diffuseP * diffuseP; +#endif + } + } + +#if( defined RELAX_SPECULAR ) + // Calculating color box + specularFirstMoment /= 25.0; + specularSecondMoment /= 25.0; + float3 specularSigma = sqrt(max(0.0f, specularSecondMoment - specularFirstMoment * specularFirstMoment)); + float3 specularColorMin = specularFirstMoment - gColorBoxSigmaScale * specularSigma; + float3 specularColorMax = specularFirstMoment + gColorBoxSigmaScale * specularSigma; + + // Expanding color box with color of the center pixel to minimize introduced bias + float3 specularCenter = sharedSpecular[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; + specularColorMin = min(specularColorMin, specularCenter); + specularColorMax = max(specularColorMax, specularCenter); + + // Color clamping + specularYCoCg = clamp(specularYCoCg, specularColorMin, specularColorMax); + float3 clampedSpecular = STL::Color::YCoCgToLinear(specularYCoCg); + + // Writing out the results + gOutSpecularIllumination[pixelPos.xy] = float4(clampedSpecular, specularIlluminationAnd2ndMoment.a); +#endif + +#if( defined RELAX_DIFFUSE ) + // Calculating color box + diffuseFirstMoment /= 25.0; + diffuseSecondMoment /= 25.0; + float3 diffuseSigma = sqrt(max(0.0f, diffuseSecondMoment - diffuseFirstMoment * diffuseFirstMoment)); + float3 diffuseColorMin = diffuseFirstMoment - gColorBoxSigmaScale * diffuseSigma; + float3 diffuseColorMax = diffuseFirstMoment + gColorBoxSigmaScale * diffuseSigma; + + // Expanding color box with color of the center pixel to minimize introduced bias + float3 diffuseCenter = sharedDiffuse[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; + diffuseColorMin = min(diffuseColorMin, diffuseCenter); + diffuseColorMax = max(diffuseColorMax, diffuseCenter); + + // Color clamping + diffuseYCoCg = clamp(diffuseYCoCg, diffuseColorMin, diffuseColorMax); + float3 clampedDiffuse = STL::Color::YCoCgToLinear(diffuseYCoCg); + + // Writing out the results + gOutDiffuseIllumination[pixelPos.xy] = float4(clampedDiffuse, diffuseIlluminationAnd2ndMoment.a); +#endif + + // Writing out history length +#if( defined RELAX_SPECULAR && defined RELAX_DIFFUSE) + gOutSpecularAndDiffuseHistoryLength[pixelPos] = specularAndDiffuseHistoryLength; +#elif( defined RELAX_SPECULAR ) + gOutSpecularHistoryLength[pixelPos] = specularHistoryLength; +#elif( defined RELAX_DIFFUSE ) + gOutDiffuseHistoryLength[pixelPos] = diffuseHistoryLength; +#endif + +} diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.resources.hlsli new file mode 100644 index 0000000..ef55ac3 --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.resources.hlsli @@ -0,0 +1,58 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_Config.hlsli" + +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationResponsive, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationResponsive, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularAndDiffuseHistoryLength, t, 4 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularAndDiffuseHistoryLength, u, 2 ) + +#elif( defined RELAX_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationResponsive, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseHistoryLength, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseHistoryLength, u, 1 ) + +#elif( defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationResponsive, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularHistoryLength, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularHistoryLength, u, 1 ) + +#endif + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gColorBoxSigmaScale ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/RELAX_DiffuseSpecular_Prepass.cs.hlsl b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.hlsli similarity index 73% rename from Source/Shaders/RELAX_DiffuseSpecular_Prepass.cs.hlsl rename to Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.hlsli index ef9c8db..35d7dd2 100644 --- a/Source/Shaders/RELAX_DiffuseSpecular_Prepass.cs.hlsl +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.hlsli @@ -14,34 +14,20 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_DECLARE_CONSTANTS +// Default CTA size is 16x16 + #include "NRD_Common.hlsli" + NRD_DECLARE_SAMPLERS + #include "RELAX_Common.hlsli" +#define POISSON_SAMPLE_NUM 8 +#define POISSON_SAMPLES g_Poisson8 + NRD_DECLARE_INPUT_TEXTURES NRD_DECLARE_OUTPUT_TEXTURES -#define POISSON_SAMPLE_NUM 8 -#define POISSON_SAMPLES g_Poisson8 - -#define THREAD_GROUP_SIZE 16 - -float GetNormHitDist(float hitDist, float viewZ, float4 hitDistParams = float4(3.0, 0.1, 10.0, -25.0), float linearRoughness = 1.0) -{ - float f = _REBLUR_GetHitDistanceNormalization(viewZ, hitDistParams, linearRoughness); - return saturate(hitDist / f); -} - -float GetSpecMagicCurve(float roughness, float power = 0.25) -{ - // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtMl4oLTE1LjAqeCkiLCJjb2xvciI6IiNGMjE4MTgifSx7InR5cGUiOjAsImVxIjoiKDEtMl4oLTIwMCp4KngpKSooeF4wLjI1KSIsImNvbG9yIjoiIzIyRUQxNyJ9LHsidHlwZSI6MCwiZXEiOiIoMS0yXigtMjAwKngqeCkpKih4XjAuNSkiLCJjb2xvciI6IiMxNzE2MTYifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMSIsIjAiLCIxLjEiXSwic2l6ZSI6WzEwMDAsNTAwXX1d - - float f = 1.0 - exp2(-200.0 * roughness * roughness); - f *= STL::Math::Pow01(roughness, power); - - return f; -} - float GetBlurRadius(float radius, float roughness, float hitDist, float viewZ, float nonLinearAccumSpeed, float boost, float error, float radiusBias, float radiusScale) { // Modify by hit distance @@ -97,36 +83,18 @@ float2x3 GetKernelBasis(float3 X, float3 N, float worldRadius, float roughness = return float2x3(T, B); } - -float2 GetHitDistanceWeightParams(float normHitDist, float nonLinearAccumSpeed, float roughness = 1.0) -{ - float threshold = exp2(-17.0 * roughness * roughness); // TODO: not in line with other weights - float scale = lerp(threshold, 1.0, nonLinearAccumSpeed); - - float a = rcp(normHitDist * scale * 0.99 + 0.01); - float b = normHitDist * a; - - return float2(a, -b); -} - -float GetNormalWeightParams(float nonLinearAccumSpeed, float edge, float error, float roughness = 1.0, float strictness = 1.0) +float getNormalWeightParams(float nonLinearAccumSpeed, float roughness = 1.0, float strictness = 1.0) { float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle(roughness); - - // TODO: 0.15 can be different for blur passes - // TODO: curvature is needed to estimate initial scale - float s = lerp(0.04, 0.15, error); + float s = 0.15; s *= strictness; - - s = lerp(s, 1.0, edge); s = lerp(s, 1.0, nonLinearAccumSpeed); angle *= s; - - angle += STL::Math::DegToRad(0.625); - - return rcp(angle); + angle = 1.0 / max(angle, NRD_ENCODING_ERRORS.x); + return angle; } +#if( defined RELAX_DIFFUSE ) int2 DiffCheckerboard(int2 pos) { int2 result = pos; @@ -136,7 +104,9 @@ int2 DiffCheckerboard(int2 pos) } return result; } +#endif +#if( defined RELAX_SPECULAR ) int2 SpecCheckerboard(int2 pos) { int2 result = pos; @@ -146,6 +116,7 @@ int2 SpecCheckerboard(int2 pos) } return result; } +#endif float GetGaussianWeight(float r) { @@ -153,55 +124,17 @@ float GetGaussianWeight(float r) return exp(-0.66 * r * r); } -float GetNormalWeight(float params0, float3 n0, float3 n) -{ - float cosa = saturate(dot(n0, n)); - float angle = STL::Math::AcosApprox(cosa); - - return _ComputeWeight(float2(params0, -0.001), angle); -} - -#define GetHitDistanceWeight(p, value) _ComputeWeight(p, value) - -float2 GetRoughnessWeightParams(float roughness0) -{ - float a = rcp(roughness0 * 0.05 * 0.99 + 0.01); - float b = roughness0 * a; - - return float2(a, -b); -} - -float GetRoughnessWeight(float2 params0, float roughness) -{ - return STL::Math::SmoothStep01(1.0 - abs(roughness * params0.x + params0.y)); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] +[numthreads(GROUP_X, GROUP_Y, 1)] NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) { - // Calculating checkerboard fields - bool diffHasData = true; - bool specHasData = true; uint checkerboard = STL::Sequence::CheckerBoard(ipos, gFrameIndex); - if (gDiffuseCheckerboard != 2) - { - diffHasData = (checkerboard == gDiffuseCheckerboard); - } - - if (gSpecularCheckerboard != 2) - { - specHasData = (checkerboard == gSpecularCheckerboard); - } - // Reading center GBuffer data // Applying abs() to viewZ so it is positive down the denoising pipeline. // This ensures correct denoiser operation with different camera handedness. - float centerViewZ = abs(gViewZ[ipos + gRectOrigin]); - float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos + gRectOrigin]); - float3 centerNormal = centerNormalRoughness.xyz; - float centerRoughness = centerNormalRoughness.w; + // Also ensuring viewZ is not zero + float centerViewZ = max(1e-6, abs(gViewZ[ipos + gRectOrigin])); // Outputting ViewZ and scaled ViewZ to be used down the denoising pipeline gOutViewZ[ipos] = centerViewZ; @@ -215,12 +148,18 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId } float2 uv = ((float2)ipos + float2(0.5, 0.5)) * gInvRectSize; - float3 centerWorldPos = GetCurrentWorldPos(uv * 2.0 - 1.0, centerViewZ); + float3 centerWorldPos = GetCurrentWorldPosFromClipSpaceXY(uv * 2.0 - 1.0, centerViewZ); float4 rotator = GetBlurKernelRotation(NRD_FRAME, ipos, gRotator, gFrameIndex); // Checkerboard resolve weights float2 checkerboardResolveWeights = 1.0; +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) if ((gSpecularCheckerboard != 2) || (gDiffuseCheckerboard != 2)) +#elif( defined RELAX_DIFFUSE ) + if (gDiffuseCheckerboard != 2) +#elif( defined RELAX_SPECULAR ) + if (gSpecularCheckerboard != 2) +#endif { float viewZ0 = abs(gViewZ[ipos + int2(-1, 0) + gRectOrigin]); float viewZ1 = abs(gViewZ[ipos + int2(1, 0) + gRectOrigin]); @@ -229,15 +168,37 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId checkerboardResolveWeights *= STL::Math::PositiveRcp(checkerboardResolveWeights.x + checkerboardResolveWeights.y); } + float centerMaterialID; + float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos + gRectOrigin], centerMaterialID); + float3 centerNormal = centerNormalRoughness.xyz; + float centerRoughness = centerNormalRoughness.w; + +#if( defined RELAX_DIFFUSE ) // Reading diffuse & resolving diffuse checkerboard float4 diffuseIllumination = gDiffuseIllumination[DiffCheckerboard(ipos + gRectOrigin)]; + bool diffHasData = true; + if (gDiffuseCheckerboard != 2) + { + diffHasData = (checkerboard == gDiffuseCheckerboard); + } + if (!diffHasData) { float4 d0 = gDiffuseIllumination[DiffCheckerboard(ipos + int2(-1, 0) + gRectOrigin)]; float4 d1 = gDiffuseIllumination[DiffCheckerboard(ipos + int2(1, 0) + gRectOrigin)]; - diffuseIllumination *= saturate(1.0 - checkerboardResolveWeights.x - checkerboardResolveWeights.y); - diffuseIllumination += d0 * checkerboardResolveWeights.x + d1 * checkerboardResolveWeights.y; + float2 diffCheckerboardResolveWeights = checkerboardResolveWeights; +#if( NRD_USE_MATERIAL_ID == 1 ) + float materialID0; + float materialID1; + NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos + int2(-1, 0) + gRectOrigin], materialID0); + NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos + int2(1, 0) + gRectOrigin], materialID1); + diffCheckerboardResolveWeights.x *= CompareMaterials(centerMaterialID, materialID0, gDiffMaterialMask); + diffCheckerboardResolveWeights.y *= CompareMaterials(centerMaterialID, materialID1, gDiffMaterialMask); + diffCheckerboardResolveWeights *= STL::Math::PositiveRcp(diffCheckerboardResolveWeights.x + diffCheckerboardResolveWeights.y + 1.0e-4); +#endif + diffuseIllumination *= saturate(1.0 - diffCheckerboardResolveWeights.x - diffCheckerboardResolveWeights.y); + diffuseIllumination += d0 * diffCheckerboardResolveWeights.x + d1 * diffCheckerboardResolveWeights.y; } // Pre-blur for diffuse @@ -247,11 +208,11 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId float hitDist = GetNormHitDist(diffuseIllumination.w, centerViewZ); float blurRadius = GetBlurRadius(gDiffuseBlurRadius, 1.0, diffuseIllumination.w, centerViewZ, 1.0 / 9.0, 1.0, 1.0, 0, 1.0); - float worldBlurRadius = PixelRadiusToWorld(gUnproject, gIsOrtho, blurRadius, centerViewZ) * - min(gResolutionScale.x, gResolutionScale.y); + float worldBlurRadius = PixelRadiusToWorld(gUnproject, gOrthoMode, blurRadius, centerViewZ) * + min(gResolutionScale.x, gResolutionScale.y); float2x3 TvBv = GetKernelBasis(centerWorldPos, centerNormal, worldBlurRadius); - float normalWeightParams = GetNormalWeightParams(1.0 / 9.0, 0.0, 1.0, 1.0, 1.0); + float normalWeightParams = getNormalWeightParams(1.0 / 9.0, 1.0); float2 hitDistanceWeightParams = GetHitDistanceWeightParams(diffuseIllumination.w, 1.0 / 9.0); float weightSum = 1.0; @@ -273,28 +234,31 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId // Fetch data float2 uvScaled = uv * gResolutionScale; - float3 sampleNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0)).rgb; + + float sampleMaterialID; + float3 sampleNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0), sampleMaterialID).rgb; float2 checkerboardUvScaled = checkerboardUv * gResolutionScale + gRectOffset; float4 sampleDiffuseIllumination = gDiffuseIllumination.SampleLevel(gNearestMirror, checkerboardUvScaled, 0); float sampleViewZ = abs(gViewZ.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0)); - float3 sampleWorldPos = GetCurrentWorldPos(uv * 2.0 - 1.0, sampleViewZ); + float3 sampleWorldPos = GetCurrentWorldPosFromClipSpaceXY(uv * 2.0 - 1.0, sampleViewZ); // Sample weight float sampleWeight = IsInScreen(uv); sampleWeight *= GetGaussianWeight(offset.z); + sampleWeight *= CompareMaterials(centerMaterialID, sampleMaterialID, gDiffMaterialMask); float sampleNormalizedHitDist = GetNormHitDist(sampleDiffuseIllumination.w, sampleViewZ); float minHitDistanceWeight = 0.2; float hitDistanceWeight = GetHitDistanceWeight(hitDistanceWeightParams, sampleNormalizedHitDist); sampleWeight *= GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - gDepthThreshold); + centerWorldPos, + centerNormal, + gOrthoMode == 0 ? centerViewZ : 1.0, + sampleWorldPos, + gDepthThreshold); sampleWeight *= GetNormalWeight(normalWeightParams, centerNormal, sampleNormal); sampleWeight *= lerp(minHitDistanceWeight, 1.0, hitDistanceWeight); @@ -304,16 +268,34 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId diffuseIllumination /= weightSum; } gOutDiffuseIllumination[ipos] = clamp(diffuseIllumination, 0, NRD_FP16_MAX); +#endif +#if( defined RELAX_SPECULAR ) // Reading specular & resolving specular checkerboard float4 specularIllumination = gSpecularIllumination[SpecCheckerboard(ipos + gRectOrigin)]; + bool specHasData = true; + if (gSpecularCheckerboard != 2) + { + specHasData = (checkerboard == gSpecularCheckerboard); + } + if (!specHasData) { float4 s0 = gSpecularIllumination[SpecCheckerboard(ipos + int2(-1, 0) + gRectOrigin)]; float4 s1 = gSpecularIllumination[SpecCheckerboard(ipos + int2(1, 0) + gRectOrigin)]; - specularIllumination *= saturate(1.0 - checkerboardResolveWeights.x - checkerboardResolveWeights.y); - specularIllumination += s0 * checkerboardResolveWeights.x + s1 * checkerboardResolveWeights.y; + float2 specCheckerboardResolveWeights = checkerboardResolveWeights; +#if( NRD_USE_MATERIAL_ID == 1 ) + float materialID0; + float materialID1; + NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos + int2(-1, 0) + gRectOrigin], materialID0); + NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos + int2(1, 0) + gRectOrigin], materialID1); + specCheckerboardResolveWeights.x *= CompareMaterials(centerMaterialID, materialID0, gSpecMaterialMask); + specCheckerboardResolveWeights.y *= CompareMaterials(centerMaterialID, materialID1, gSpecMaterialMask); + specCheckerboardResolveWeights *= STL::Math::PositiveRcp(specCheckerboardResolveWeights.x + specCheckerboardResolveWeights.y + 1.0e-4); +#endif + specularIllumination *= saturate(1.0 - specCheckerboardResolveWeights.x - specCheckerboardResolveWeights.y); + specularIllumination += s0 * specCheckerboardResolveWeights.x + s1 * specCheckerboardResolveWeights.y; } specularIllumination.a = max(0.001, min(gDenoisingRange, specularIllumination.a)); @@ -330,14 +312,14 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId float hitDist = GetNormHitDist(specularIllumination.w, centerViewZ, float4(3.0, 0.1, 10.0, -25.0), centerRoughness); float blurRadius = GetBlurRadius(gSpecularBlurRadius, centerRoughness, specularIllumination.w, centerViewZ, 1.0 / 9.0, 1.0, 1.0, 0, 1.0); - float worldBlurRadius = PixelRadiusToWorld(gUnproject, gIsOrtho, blurRadius, centerViewZ) * - min(gResolutionScale.x, gResolutionScale.y); + float worldBlurRadius = PixelRadiusToWorld(gUnproject, gOrthoMode, blurRadius, centerViewZ) * + min(gResolutionScale.x, gResolutionScale.y); float anisoFade = 1.0 / 9.0; float2x3 TvBv = GetKernelBasis(centerWorldPos, centerNormal, worldBlurRadius, centerRoughness, anisoFade); - float normalWeightParams = GetNormalWeightParams(1.0 / 9.0, 0.0, 1.0, centerRoughness, 1.0); + float normalWeightParams = getNormalWeightParams(1.0 / 9.0, centerRoughness); float2 hitDistanceWeightParams = GetHitDistanceWeightParams(specularIllumination.w, 1.0 / 9.0, centerRoughness); - float2 roughnessWeightParams = GetRoughnessWeightParams(centerRoughness); + float2 roughnessWeightParams = GetRoughnessWeightParams(centerRoughness, gRoughnessFraction); float weightSum = 1.0; // Spatial blur @@ -358,7 +340,9 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId // Fetch data float2 uvScaled = uv * gResolutionScale; - float4 sampleNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0)); + + float sampleMaterialID; + float4 sampleNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0), sampleMaterialID); float3 sampleNormal = sampleNormalRoughness.rgb; float sampleRoughness = sampleNormalRoughness.a; @@ -367,25 +351,26 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId sampleSpecularIllumination.rgb = STL::Color::Compress(sampleSpecularIllumination.rgb, exposure); float sampleViewZ = abs(gViewZ.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0)); - float3 sampleWorldPos = GetCurrentWorldPos(uv * 2.0 - 1.0, sampleViewZ); + float3 sampleWorldPos = GetCurrentWorldPosFromClipSpaceXY(uv * 2.0 - 1.0, sampleViewZ); // Sample weight float sampleWeight = IsInScreen(uv); sampleWeight *= GetGaussianWeight(offset.z); + sampleWeight *= CompareMaterials(centerMaterialID, sampleMaterialID, gSpecMaterialMask); sampleWeight *= GetRoughnessWeight(roughnessWeightParams, sampleRoughness); float sampleNormalizedHitDist = GetNormHitDist(sampleSpecularIllumination.w, sampleViewZ); - float minHitDistanceWeight = 0.2; float hitDistanceWeight = GetHitDistanceWeight(hitDistanceWeightParams, sampleNormalizedHitDist); sampleWeight *= GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - gDepthThreshold); + centerWorldPos, + centerNormal, + gOrthoMode == 0 ? centerViewZ : 1.0, + sampleWorldPos, + gDepthThreshold); sampleWeight *= GetNormalWeight(normalWeightParams, centerNormal, sampleNormal); + float minHitDistanceWeight = 0.2; sampleWeight *= lerp(minHitDistanceWeight, 1.0, hitDistanceWeight); specularIllumination += sampleSpecularIllumination * sampleWeight; @@ -397,5 +382,6 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId specularIllumination.a = specularHitT; // No, we don't preblur specular HitT! } gOutSpecularIllumination[ipos] = clamp(specularIllumination, 0, NRD_FP16_MAX); +#endif } diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.resources.hlsli new file mode 100644 index 0000000..f8471de --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.resources.hlsli @@ -0,0 +1,89 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_Config.hlsli" + +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 3 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutViewZ, u, 2) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutScaledViewZ, u, 3 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float4, gRotator) \ + NRD_CONSTANT( uint, gDiffuseCheckerboard ) \ + NRD_CONSTANT( uint, gSpecularCheckerboard ) \ + NRD_CONSTANT( float, gDiffuseBlurRadius ) \ + NRD_CONSTANT( float, gSpecularBlurRadius ) \ + NRD_CONSTANT( float, gMeterToUnitsMultiplier ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANTS_END + +#elif( defined RELAX_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutViewZ, u, 1) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutScaledViewZ, u, 2 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float4, gRotator) \ + NRD_CONSTANT( uint, gDiffuseCheckerboard ) \ + NRD_CONSTANT( float, gDiffuseBlurRadius ) \ + NRD_CONSTANT( float, gMeterToUnitsMultiplier ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANTS_END + +#elif( defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 2 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutViewZ, u, 1) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutScaledViewZ, u, 2 ) + + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float4, gRotator) \ + NRD_CONSTANT( uint, gSpecularCheckerboard ) \ + NRD_CONSTANT( float, gSpecularBlurRadius ) \ + NRD_CONSTANT( float, gMeterToUnitsMultiplier ) \ + NRD_CONSTANT( float, gDepthThreshold ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANTS_END + +#endif + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/RELAX_DiffuseSpecular_Reproject.cs.hlsl b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.hlsli similarity index 72% rename from Source/Shaders/RELAX_DiffuseSpecular_Reproject.cs.hlsl rename to Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.hlsli index fe631bf..04f0757 100644 --- a/Source/Shaders/RELAX_DiffuseSpecular_Reproject.cs.hlsl +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.hlsli @@ -14,31 +14,25 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_DECLARE_CONSTANTS +#define NRD_CTA_8X8 +#define NRD_USE_BORDER_2 + #include "NRD_Common.hlsli" + NRD_DECLARE_SAMPLERS + #include "RELAX_Common.hlsli" NRD_DECLARE_INPUT_TEXTURES NRD_DECLARE_OUTPUT_TEXTURES -#define THREAD_GROUP_SIZE 8 -#define SKIRT 2 - -groupshared float4 sharedInSpecular[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalRoughness[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; +#if (defined RELAX_SPECULAR) +groupshared float4 sharedInSpecular[BUFFER_Y][BUFFER_X]; +#endif +groupshared float4 sharedNormalRoughness[BUFFER_Y][BUFFER_X]; // Helper functions - -float GetSpecMagicCurve(float roughness, float power = 0.25) -{ - // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtMl4oLTE1LjAqeCkiLCJjb2xvciI6IiNGMjE4MTgifSx7InR5cGUiOjAsImVxIjoiKDEtMl4oLTIwMCp4KngpKSooeF4wLjI1KSIsImNvbG9yIjoiIzIyRUQxNyJ9LHsidHlwZSI6MCwiZXEiOiIoMS0yXigtMjAwKngqeCkpKih4XjAuNSkiLCJjb2xvciI6IiMxNzE2MTYifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMSIsIjAiLCIxLjEiXSwic2l6ZSI6WzEwMDAsNTAwXX1d - - float f = 1.0 - exp2(-200.0 * roughness * roughness); - f *= STL::Math::Pow01(roughness, power); - - return f; -} - +#if (defined RELAX_SPECULAR) float GetSpecAccumulatedFrameNum(float roughness, float powerScale) { // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIzMSooeF4wLjY2KSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MCwiZXEiOiIzMSooMS0yXigtMjAwKngqeCkpKih4XjAuNSkiLCJjb2xvciI6IiNGQTBEMEQifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMSIsIjAiLCIzMSJdfV0- @@ -47,7 +41,6 @@ float GetSpecAccumulatedFrameNum(float roughness, float powerScale) return RELAX_MAX_ACCUM_FRAME_NUM * f; } - float GetSpecAccumSpeed(float maxAccumSpeed, float roughness, float NoV, float parallax) { float acos01sq = saturate(1.0 - NoV); // see AcosApprox() @@ -62,46 +55,11 @@ float GetSpecAccumSpeed(float maxAccumSpeed, float roughness, float NoV, float p return accumSpeed; } -float GetNormalWeight(float params0, float3 n0, float3 n) -{ - float cosa = saturate(dot(n0, n)); - float angle = STL::Math::AcosApprox(cosa); - return _ComputeWeight(float2(params0, -0.001), angle); -} - -float2 GetRoughnessWeightParams(float roughness0) -{ - float a = rcp(roughness0 * 0.05 * 0.99 + 0.01); - float b = roughness0 * a; - return float2(a, -b); -} - -#define GetRoughnessWeight _ComputeWeight - -float ComputeParallax(float3 X, float3 Xprev, float3 cameraDelta) -{ - float3 Xt = Xprev - cameraDelta; - float cosa = dot(X, Xt); - cosa *= STL::Math::Rsqrt(STL::Math::LengthSquared(Xt) * STL::Math::LengthSquared(X)); - cosa = saturate(cosa); - float parallax = STL::Math::Sqrt01(1.0 - cosa * cosa) * STL::Math::PositiveRcp(cosa); - parallax *= RELAX_PARALLAX_NORMALIZATION; - parallax /= 1.0 + RELAX_PARALLAX_COMPRESSION_STRENGTH * parallax; - return parallax; -} - -float GetParallaxInPixels(float parallax) -{ - parallax /= 1.0 - RELAX_PARALLAX_COMPRESSION_STRENGTH * parallax; - - float parallaxInPixels = parallax / (RELAX_PARALLAX_NORMALIZATION * gUnproject); - - return parallaxInPixels; -} +#endif // (defined RELAX_SPECULAR) float getJitterRadius(float jitterDelta, float linearZ) { - return jitterDelta * gUnproject * (gIsOrtho == 0 ? linearZ : 1.0); + return jitterDelta * gUnproject * (gOrthoMode == 0 ? linearZ : 1.0); } float isReprojectionTapValid(float3 currentWorldPos, float3 previousWorldPos, float3 currentNormal, float disocclusionThreshold) @@ -112,6 +70,12 @@ float isReprojectionTapValid(float3 currentWorldPos, float3 previousWorldPos, fl return maxPlaneDistance > disocclusionThreshold ? 0.0 : 1.0; } +#define CHECK_GEOMETRY \ + reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold) + +#define CHECK_MATERIAL_ID \ + reprojectionTapValid *= CompareMaterials(currentMaterialID, gPrevMaterialID[tapPos], materialIDMask) + // Returns reprojection search result based on surface motion: // 2 - reprojection found, bicubic footprint was used // 1 - reprojection found, bilinear footprint was used @@ -124,33 +88,49 @@ float loadSurfaceMotionBasedPrevData( float3 currentWorldPos, float3 currentNormal, float currentLinearZ, +#if( defined RELAX_SPECULAR) float currentReflectionHitT, +#endif float3 motionVector, - out float4 prevSpecularIllumAnd2ndMoment, + float currentMaterialID, + uint materialIDMask, + out float footprintQuality, +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + out float2 historyLength, +#else + out float historyLength, +#endif +#if( defined RELAX_DIFFUSE) out float4 prevDiffuseIllumAnd2ndMoment, - out float3 prevSpecularResponsiveIllum, out float3 prevDiffuseResponsiveIllum, +#endif +#if( defined RELAX_SPECULAR) + out float4 prevSpecularIllumAnd2ndMoment, + out float3 prevSpecularResponsiveIllum, out float3 prevWorldPos, - out float3 prevNormal, out float prevReflectionHitT, - out float2 historyLength, out float2 prevUV, - out float footprintQuality) +#endif + out float3 prevNormal +) { // Calculating jitter margin radius in world space - float jitterRadius = getJitterRadius(gPrevCameraPositionAndJitterDelta.w, currentLinearZ); - float disocclusionThreshold = (gDisocclusionDepthThreshold + jitterRadius) * (gIsOrtho == 0 ? currentLinearZ : 1.0); + float jitterRadius = getJitterRadius(gJitterDelta, currentLinearZ); + float disocclusionThreshold = (gDisocclusionDepthThreshold + jitterRadius) * (gOrthoMode == 0 ? currentLinearZ : 1.0); // Calculating previous pixel position and UV - float2 pixelUV = (pixelPosOnScreen + 0.5) * gInvRectSize; - prevUV = STL::Geometry::GetPrevUvFromMotion(pixelUV, currentWorldPos, gPrevWorldToClip, motionVector, gIsWorldSpaceMotion); + float2 uv = (pixelPosOnScreen + 0.5) * gInvRectSize; +#ifndef RELAX_SPECULAR + float2 prevUV; +#endif + prevUV = STL::Geometry::GetPrevUvFromMotion(uv, currentWorldPos, gPrevWorldToClip, motionVector, gIsWorldSpaceMotionEnabled); float2 prevPixelPosOnScreen = prevUV * gRectSizePrev; // 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. int2 prevPixelPosInt = int2(prevPixelPosOnScreen); bool isSmallMotion = all(prevPixelPosInt == pixelPosOnScreen); - bool skipReprojectionTest = gSkipReprojectionTestWithoutMotion && gIsCameraStatic && isSmallMotion; + bool skipReprojectionTest = gSkipReprojectionTestWithoutMotion && isSmallMotion; // Calculating footprint origin and weights int2 bilinearOrigin = int2(floor(prevPixelPosOnScreen - 0.5)); @@ -186,10 +166,10 @@ float loadSurfaceMotionBasedPrevData( // Adjusting worldspace position: // Applying worldspace motion first, - motionVector *= gIsWorldSpaceMotion > 0 ? 1.0 : 0.0; + motionVector *= gIsWorldSpaceMotionEnabled > 0 ? 1.0 : 0.0; // Then taking care of camera motion, because world space is always centered at camera position in NRD - currentWorldPos += motionVector - gPrevCameraPositionAndJitterDelta.xyz; + currentWorldPos += motionVector - gPrevCameraPosition.xyz; // Transforming bilinearOrigin to clip space coords to simplify previous world pos calculation float2 prevClipSpaceXY = ((float2)bilinearOrigin + float2(0.5, 0.5)) * (1.0 / gRectSizePrev) * 2.0 - 1.0; @@ -198,85 +178,97 @@ float loadSurfaceMotionBasedPrevData( // 1st row tapPos = bilinearOrigin + int2(0, -1); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, -1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(0.0, -1.0), prevViewZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; tapPos = bilinearOrigin + int2(1, -1); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, -1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(1.0, -1.0), prevViewZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; // 2nd row tapPos = bilinearOrigin + int2(-1, 0); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(-1.0, 0.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(-1.0, 0.0), prevViewZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; tapPos = bilinearOrigin + int2(0, 0); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 0.0), prevViewZInTap); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(0.0, 0.0), prevViewZInTap); prevWorldPos00 = prevWorldPosInTap; - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; bilinearTapsValid.x = reprojectionTapValid; tapPos = bilinearOrigin + int2(1, 0); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 0.0), prevViewZInTap); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(1.0, 0.0), prevViewZInTap); prevWorldPos10 = prevWorldPosInTap; - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; bilinearTapsValid.y = reprojectionTapValid; tapPos = bilinearOrigin + int2(2, 0); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(2.0, 0.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(2.0, 0.0), prevViewZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; // 3rd row tapPos = bilinearOrigin + int2(-1, 1); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(-1.0, 1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(-1.0, 1.0), prevViewZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; tapPos = bilinearOrigin + int2(0, 1); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 1.0), prevViewZInTap); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(0.0, 1.0), prevViewZInTap); prevWorldPos01 = prevWorldPosInTap; - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; bilinearTapsValid.z = reprojectionTapValid; tapPos = bilinearOrigin + int2(1, 1); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 1.0), prevViewZInTap); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(1.0, 1.0), prevViewZInTap); prevWorldPos11 = prevWorldPosInTap; - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; bilinearTapsValid.w = reprojectionTapValid; tapPos = bilinearOrigin + int2(2, 1); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(2.0, 1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(2.0, 1.0), prevViewZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; // 4th row tapPos = bilinearOrigin + int2(0, 2); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 2.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(0.0, 2.0), prevViewZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; tapPos = bilinearOrigin + int2(1, 2); prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 2.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromClipSpaceXY(prevClipSpaceXY + dXY * float2(1.0, 2.0), prevViewZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; bicubicFootprintValid *= reprojectionTapValid; bilinearTapsValid = skipReprojectionTest ? float4(1.0, 1.0, 1.0, 1.0) : bilinearTapsValid; @@ -311,15 +303,19 @@ float loadSurfaceMotionBasedPrevData( // Applying reprojection filters float reprojectionFound = 0; - prevSpecularIllumAnd2ndMoment = 0; + historyLength = 0; + footprintQuality = 0; + prevNormal = currentNormal; +#if( defined RELAX_DIFFUSE) prevDiffuseIllumAnd2ndMoment = 0; - prevSpecularResponsiveIllum = 0; prevDiffuseResponsiveIllum = 0; +#endif +#if( defined RELAX_SPECULAR) + prevSpecularIllumAnd2ndMoment = 0; + prevSpecularResponsiveIllum = 0; prevWorldPos = currentWorldPos; - prevNormal = currentNormal; prevReflectionHitT = currentReflectionHitT; - historyLength = 0; - footprintQuality = 0; +#endif if (any(bilinearTapsValid)) { @@ -327,6 +323,7 @@ float loadSurfaceMotionBasedPrevData( if (bicubicFootprintValid > 0) { // Bicubic for illumination and 2nd moments +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) BicubicFloat4x2( prevSpecularIllumAnd2ndMoment, prevDiffuseIllumAnd2ndMoment, @@ -335,12 +332,32 @@ float loadSurfaceMotionBasedPrevData( gLinearClamp, prevPixelPosOnScreen, gInvResourceSize); +#elif( defined RELAX_DIFFUSE) + prevDiffuseIllumAnd2ndMoment = BicubicFloat4( + gPrevDiffuseIllumination, + gLinearClamp, + prevPixelPosOnScreen, + gInvResourceSize); +#elif( defined RELAX_SPECULAR) + prevSpecularIllumAnd2ndMoment = BicubicFloat4( + gPrevSpecularIllumination, + gLinearClamp, + prevPixelPosOnScreen, + gInvResourceSize); +#endif + +#if(defined RELAX_SPECULAR ) prevSpecularIllumAnd2ndMoment = max(0, prevSpecularIllumAnd2ndMoment); +#endif +#if(defined RELAX_DIFFUSE ) prevDiffuseIllumAnd2ndMoment = max(0, prevDiffuseIllumAnd2ndMoment); +#endif #if( RELAX_USE_BICUBIC_FOR_FAST_HISTORY == 1 ) - float4 spec, diff; +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + float4 spec; + float4 diff; BicubicFloat4x2( spec, diff, @@ -351,10 +368,31 @@ float loadSurfaceMotionBasedPrevData( gInvResourceSize); prevSpecularResponsiveIllum = max(0, spec.rgb); prevDiffuseResponsiveIllum = max(0, diff.rgb); -#else - prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; +#elif( defined RELAX_DIFFUSE) + float4 diff = BicubicFloat4( + gPrevDiffuseIlluminationResponsive, + gLinearClamp, + prevPixelPosOnScreen, + gInvResourceSize); + prevDiffuseResponsiveIllum = max(0, diff.rgb); +#elif( defined RELAX_SPECULAR) + float4 spec = BicubicFloat4( + gPrevSpecularIlluminationResponsive, + gLinearClamp, + prevPixelPosOnScreen, + gInvResourceSize); + prevSpecularResponsiveIllum = max(0, spec.rgb); +#endif + +#else // #if( RELAX_USE_BICUBIC_FOR_FAST_HISTORY == 1 ) +#if( defined RELAX_DIFFUSE) prevDiffuseResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevDiffuseIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; #endif +#if( defined RELAX_SPECULAR) + prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; +#endif + +#endif // #if( RELAX_USE_BICUBIC_FOR_FAST_HISTORY == 1 ) footprintQuality = 1.0; reprojectionFound = 2.0; @@ -362,13 +400,18 @@ float loadSurfaceMotionBasedPrevData( else { // If no success with the bicubic, then do weighted bilinear - prevSpecularIllumAnd2ndMoment = - BilinearWithBinaryWeightsFloat4(gPrevSpecularIllumination, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); +#if( defined RELAX_DIFFUSE) prevDiffuseIllumAnd2ndMoment = BilinearWithBinaryWeightsFloat4(gPrevDiffuseIllumination, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; prevDiffuseResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevDiffuseIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; +#endif +#if( defined RELAX_SPECULAR) + prevSpecularIllumAnd2ndMoment = + BilinearWithBinaryWeightsFloat4(gPrevSpecularIllumination, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); + + prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; +#endif reprojectionFound = 1.0; } @@ -376,15 +419,21 @@ float loadSurfaceMotionBasedPrevData( // Calculating previous worldspace position // by applying weighted bilinear to worldspace positions in taps. // Also calculating history length by using weighted bilinear - prevWorldPos = BilinearWithBinaryWeightsImmediateFloat3( - prevWorldPos00, prevWorldPos10, prevWorldPos01, prevWorldPos11, - bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); + +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + historyLength = 255.0 * BilinearWithBinaryWeightsFloat2(gPrevHistoryLength, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); +#else + historyLength = 255.0 * BilinearWithBinaryWeightsFloat(gPrevHistoryLength, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); +#endif prevNormal = BilinearWithBinaryWeightsImmediateFloat3( prevNormal00, prevNormal10, prevNormal01, prevNormal11, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - historyLength = 255.0 * BilinearWithBinaryWeightsFloat2(gPrevSpecularAndDiffuseHistoryLength, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); +#if( defined RELAX_SPECULAR ) + prevWorldPos = BilinearWithBinaryWeightsImmediateFloat3( + prevWorldPos00, prevWorldPos10, prevWorldPos01, prevWorldPos11, + bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); float2 gatherOrigin = (bilinearOrigin + 1.0) * gInvResourceSize; float4 prevReflectionHitTs = gPrevReflectionHitT.GatherRed(gNearestClamp, gatherOrigin).wzxy; @@ -394,6 +443,7 @@ float loadSurfaceMotionBasedPrevData( bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); prevReflectionHitT = max(0.001, prevReflectionHitT); +#endif footprintQuality = interpolatedBinaryWeight; } @@ -401,6 +451,7 @@ float loadSurfaceMotionBasedPrevData( } // Returns specular reprojection search result based on virtual motion +#if( defined RELAX_SPECULAR) float loadVirtualMotionBasedPrevData( int2 pixelPosOnScreen, float3 currentWorldPos, @@ -410,6 +461,8 @@ float loadVirtualMotionBasedPrevData( float3 currentViewVector, float3 prevWorldPos, bool surfaceBicubicValid, + float currentMaterialID, + uint materialIDMask, out float4 prevSpecularIllumAnd2ndMoment, out float3 prevSpecularResponsiveIllum, out float3 prevNormal, @@ -418,8 +471,8 @@ float loadVirtualMotionBasedPrevData( out float2 prevUVVMB) { // Taking care of camera motion, because world space is always centered at camera position in NRD - prevWorldPos += gPrevCameraPositionAndJitterDelta.xyz; - currentWorldPos -= gPrevCameraPositionAndJitterDelta.xyz; + prevWorldPos += gPrevCameraPosition.xyz; + currentWorldPos -= gPrevCameraPosition.xyz; // Calculating previous worldspace virtual position based on reflection hitT float3 virtualViewVector = normalize(currentViewVector) * currentReflectionHitT; @@ -433,14 +486,14 @@ float loadVirtualMotionBasedPrevData( prevUVVMB = prevVirtualClipPos.xy * float2(0.5, -0.5) + float2(0.5, 0.5); float2 prevVirtualPixelPosOnScreen = prevUVVMB * gRectSizePrev; - float jitterRadius = getJitterRadius(gPrevCameraPositionAndJitterDelta.w, accumulatedSpecularVMBZ); - float disocclusionThreshold = (gDisocclusionDepthThreshold + jitterRadius) * (gIsOrtho == 0 ? currentLinearZ : 1.0); + float jitterRadius = getJitterRadius(gJitterDelta, accumulatedSpecularVMBZ); + float disocclusionThreshold = (gDisocclusionDepthThreshold + jitterRadius) * (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. int2 prevVirtualPixelPosInt = int2(prevVirtualPixelPosOnScreen); bool isSmallVirtualMotion = all(prevVirtualPixelPosInt == pixelPosOnScreen); - bool skipReprojectionTest = gSkipReprojectionTestWithoutMotion && gIsCameraStatic && isSmallVirtualMotion; + bool skipReprojectionTest = gSkipReprojectionTestWithoutMotion && isSmallVirtualMotion; // Calculating footprint origin and weights int2 bilinearOrigin = int2(floor(prevVirtualPixelPosOnScreen - 0.5)); @@ -450,6 +503,7 @@ float loadVirtualMotionBasedPrevData( float3 prevNormal00, prevNormal10, prevNormal01, prevNormal11; float prevRoughness00, prevRoughness10, prevRoughness01, prevRoughness11; int2 tapPos; + float reprojectionTapValid; float prevLinearZInTap; float3 prevWorldPosInTap; float4 bilinearTapsValid; @@ -463,32 +517,40 @@ float loadVirtualMotionBasedPrevData( prevNormal00 = prevNormalRoughness.rgb; prevRoughness00 = prevNormalRoughness.a; prevLinearZInTap = prevViewZs.x; - prevWorldPosInTap = GetPreviousWorldPos(tapPos, prevLinearZInTap); - bilinearTapsValid.x = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromPixelPos(tapPos, prevLinearZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; + bilinearTapsValid.x = reprojectionTapValid; tapPos = bilinearOrigin + int2(1, 0); prevNormalRoughness = UnpackPrevNormalRoughness(gPrevNormalRoughness[tapPos]); prevNormal10 = prevNormalRoughness.rgb; prevRoughness10 = prevNormalRoughness.a; prevLinearZInTap = prevViewZs.y; - prevWorldPosInTap = GetPreviousWorldPos(tapPos, prevLinearZInTap); - bilinearTapsValid.y = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromPixelPos(tapPos, prevLinearZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; + bilinearTapsValid.y = reprojectionTapValid; tapPos = bilinearOrigin + int2(0, 1); prevNormalRoughness = UnpackPrevNormalRoughness(gPrevNormalRoughness[tapPos]); prevNormal01 = prevNormalRoughness.rgb; prevRoughness01 = prevNormalRoughness.a; prevLinearZInTap = prevViewZs.z; - prevWorldPosInTap = GetPreviousWorldPos(tapPos, prevLinearZInTap); - bilinearTapsValid.z = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromPixelPos(tapPos, prevLinearZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; + bilinearTapsValid.z = reprojectionTapValid; tapPos = bilinearOrigin + int2(1, 1); prevNormalRoughness = UnpackPrevNormalRoughness(gPrevNormalRoughness[tapPos]); prevNormal11 = prevNormalRoughness.rgb; prevRoughness11 = prevNormalRoughness.a; prevLinearZInTap = prevViewZs.w; - prevWorldPosInTap = GetPreviousWorldPos(tapPos, prevLinearZInTap); - bilinearTapsValid.w = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); + prevWorldPosInTap = GetPreviousWorldPosFromPixelPos(tapPos, prevLinearZInTap); + CHECK_GEOMETRY; + CHECK_MATERIAL_ID; + bilinearTapsValid.w = reprojectionTapValid; bilinearTapsValid = skipReprojectionTest ? float4(1.0, 1.0, 1.0, 1.0) : bilinearTapsValid; @@ -513,7 +575,7 @@ float loadVirtualMotionBasedPrevData( prevSpecularResponsiveIllum = 0; prevNormal = currentNormal; prevRoughness = 0; - prevReflectionHitT = currentReflectionHitT; + prevReflectionHitT = gDenoisingRange; // Weighted bilinear (or bicubic optionally) for prev specular data based on virtual motion if (any(bilinearTapsValid)) @@ -560,133 +622,95 @@ float loadVirtualMotionBasedPrevData( } return reprojectionFound; } +#endif //#if( defined RELAX_SPECULAR) + + +void Preload(uint2 sharedPos, int2 globalPos) +{ + globalPos = clamp(globalPos, 0, gRectSize - 1.0); + +#if( defined RELAX_SPECULAR) + float4 inSpecularIllumination = gSpecularIllumination[globalPos + gRectOrigin]; + sharedInSpecular[sharedPos.y][sharedPos.x] = inSpecularIllumination; +#endif + + float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[globalPos + gRectOrigin]); + sharedNormalRoughness[sharedPos.y][sharedPos.x] = normalRoughness; +} // // Main // -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) +[numthreads(GROUP_X, GROUP_Y, 1)] +NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId, uint2 threadPos : SV_GroupThreadId, uint threadIndex : SV_GroupIndex) { + + PRELOAD_INTO_SMEM; + // Calculating checkerboard fields - bool diffHasData = true; - bool specHasData = true; - uint2 checkerboardPixelPos = ipos.xx; - uint checkerboard = STL::Sequence::CheckerBoard(ipos, gFrameIndex); + uint2 checkerboardPixelPos = pixelPos.xx; + uint checkerboard = STL::Sequence::CheckerBoard(pixelPos, gFrameIndex); +#if( defined RELAX_DIFFUSE) + bool diffHasData = true; if (gDiffCheckerboard != 2) { diffHasData = checkerboard == gDiffCheckerboard; checkerboardPixelPos.x >>= 1; } +#endif +#if( defined RELAX_SPECULAR) + bool specHasData = true; if (gSpecCheckerboard != 2) { specHasData = checkerboard == gSpecCheckerboard; checkerboardPixelPos.y >>= 1; } +#endif - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 inSpecularIllumination = 0; - float4 normalRoughness = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - inSpecularIllumination = gSpecularIllumination[int2(xx, yy) + gRectOrigin]; - normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy) + gRectOrigin]); - } - sharedInSpecular[oy][ox] = inSpecularIllumination; - sharedNormalRoughness[oy][ox] = normalRoughness; - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - inSpecularIllumination = 0; - normalRoughness = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - inSpecularIllumination = gSpecularIllumination[int2(xx, yy) + gRectOrigin]; - normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy) + gRectOrigin]); - } - sharedInSpecular[oy][ox] = inSpecularIllumination; - sharedNormalRoughness[oy][ox] = normalRoughness; - } - - // Third stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - inSpecularIllumination = 0; - normalRoughness = 0; + // Early out if linearZ is beyond denoising range + float currentLinearZ = gViewZ[pixelPos.xy + gRectOrigin]; - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) + [branch] + if (currentLinearZ > gDenoisingRange) { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - inSpecularIllumination = gSpecularIllumination[int2(xx, yy) + gRectOrigin]; - normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy) + gRectOrigin]); - } - sharedInSpecular[oy][ox] = inSpecularIllumination; - sharedNormalRoughness[oy][ox] = normalRoughness; + return; } - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); + uint2 sharedMemoryIndex = threadPos.xy + int2(BORDER, BORDER); // Center data - float3 diffuseIllumination = gDiffuseIllumination[ipos.xy + gRectOrigin].rgb; +#if( defined RELAX_DIFFUSE) + float3 diffuseIllumination = gDiffuseIllumination[pixelPos.xy + gRectOrigin].rgb; +#endif + +#if( defined RELAX_SPECULAR ) float4 specularIllumination = sharedInSpecular[sharedMemoryIndex.y][sharedMemoryIndex.x]; + specularIllumination.a = max(0.001, min(gDenoisingRange, specularIllumination.a)); +#endif - // Reading current GBuffer data and center/left/right viewZ + // Reading current GBuffer data float4 currentNormalRoughness = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x]; float3 currentNormal = currentNormalRoughness.xyz; float currentRoughness = currentNormalRoughness.w; - float currentLinearZ = gViewZ[ipos.xy + gRectOrigin]; - specularIllumination.a = max(0.001, min(gDenoisingRange, specularIllumination.a)); + // Handling materialID + // Combining logic is valid even if non-combined denoisers are used + // since undefined masks are zeroes in those cases + float currentMaterialID; + NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[gRectOrigin + pixelPos], currentMaterialID); + currentMaterialID = floor( currentMaterialID * 3.0 + 0.5 ) / 255.0; // IMPORTANT: properly repack 2-bits to 8-bits - // Early out if linearZ is beyond denoising range - [branch] - if (currentLinearZ > gDenoisingRange) - { - return; - } + // Getting current frame worldspace position and view vector for current pixel + float3 currentWorldPos = GetCurrentWorldPosFromPixelPos(pixelPos, currentLinearZ); + float3 currentViewVector = (gOrthoMode == 0) ? + currentWorldPos : + currentLinearZ * normalize(gFrustumForward.xyz); - // Calculating average normal, curvature, min hit dist and specular moments in 3x3 and 5x5 areas around current pixel - float3 currentNormalAveraged = currentNormal; +#if( defined RELAX_SPECULAR) float4 specM1 = specularIllumination; float4 specM2 = specM1 * specM1; - float curvature = 0; float minHitDist3x3 = gDenoisingRange; float minHitDist5x5 = gDenoisingRange; @@ -699,8 +723,6 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId // Skipping center pixel if ((i == 0) && (j == 0)) continue; - int2 p = ipos + int2(i, j); - float4 spec = sharedInSpecular[sharedMemoryIndex.y + j][sharedMemoryIndex.x + i]; specM1 += spec; specM2 += spec * spec; @@ -714,7 +736,13 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId specM1 /= 25.0; specM2 /= 25.0; float4 specSigma = GetStdDev(specM1, specM2); +#endif + float3 currentNormalAveraged = currentNormal; +#if( defined RELAX_SPECULAR ) + float curvature = 0; + float curvatureSum = 0; +#endif [unroll] for (int k = -1; k <= 1; k++) { @@ -723,73 +751,104 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId { // Skipping center pixel if ((k == 0) && (l == 0)) continue; - - int2 p = ipos + int2(k, l); float3 pNormal = sharedNormalRoughness[sharedMemoryIndex.y + k][sharedMemoryIndex.x + l].xyz; currentNormalAveraged += pNormal; - curvature += length(pNormal - currentNormal) * rsqrt(STL::Math::LengthSquared(float2(k, l))); +#if( defined RELAX_SPECULAR ) + int2 p = pixelPos + int2(l, k); + float3 x = GetCurrentWorldPosFromPixelPos(p, 1.0); + float3 v = normalize(gOrthoMode ? gFrustumForward.xyz : x); + float c = EstimateCurvature(pNormal, v, currentNormal, currentWorldPos); + + float w = exp2(-0.5 * STL::Math::LengthSquared(float2(k,l))); + curvature += c * w; + curvatureSum += w; +#endif } } currentNormalAveraged /= 9.0; - curvature /= 8.0; - // Only needed to mitigate banding - curvature = STL::Math::LinearStep(NRD_ENCODING_ERRORS.y, 1.0, curvature); - - // Calculating modified roughness that takes normal variation in account +#if( defined RELAX_SPECULAR ) + curvature /= curvatureSum; + curvature *= STL::Math::LinearStep(0.0, NRD_ENCODING_ERRORS.y, abs(curvature)); float currentRoughnessModified = STL::Filtering::GetModifiedRoughnessFromNormalVariance(currentRoughness, currentNormalAveraged); +#endif // Computing 2nd moments of luminance +#if( defined RELAX_SPECULAR ) float specular1stMoment = STL::Color::Luminance(specularIllumination.rgb); float specular2ndMoment = specular1stMoment * specular1stMoment; +#endif +#if( defined RELAX_DIFFUSE ) float diffuse1stMoment = STL::Color::Luminance(diffuseIllumination.rgb); float diffuse2ndMoment = diffuse1stMoment * diffuse1stMoment; - - // Getting current frame worldspace position and view vector for current pixel - float3 currentWorldPos = GetCurrentWorldPos(ipos, currentLinearZ); - float3 currentViewVector = (gIsOrtho == 0) ? - currentWorldPos : - currentLinearZ * normalize(gFrustumForward.xyz); +#endif // Reading motion vector - float3 motionVector = gMotion[gRectOrigin + ipos].xyz * gMotionVectorScale.xyy; + float3 motionVector = gMotion[gRectOrigin + pixelPos].xyz * gMotionVectorScale.xyy; // Loading previous data based on surface motion vectors - float4 prevSpecularIlluminationAnd2ndMomentSMB; + float3 prevNormalSMB; + float footprintQuality; +#if( defined RELAX_DIFFUSE ) float4 prevDiffuseIlluminationAnd2ndMomentSMB; - float3 prevSpecularIlluminationAnd2ndMomentSMBResponsive; float3 prevDiffuseIlluminationAnd2ndMomentSMBResponsive; +#endif +#if( defined RELAX_SPECULAR ) + float4 prevSpecularIlluminationAnd2ndMomentSMB; + float3 prevSpecularIlluminationAnd2ndMomentSMBResponsive; float prevReflectionHitTSMB; float3 prevWorldPosSMB; - float3 prevNormalSMB; - float2 historyLength; float2 prevUVSMB; - float footprintQuality; +#endif +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + float2 historyLength; +#else + float historyLength; +#endif float surfaceMotionBasedReprojectionFound = loadSurfaceMotionBasedPrevData( - ipos, + pixelPos, currentWorldPos, normalize(currentNormalAveraged), currentLinearZ, +#if( defined RELAX_SPECULAR) specularIllumination.a, +#endif motionVector, - prevSpecularIlluminationAnd2ndMomentSMB, + currentMaterialID, + gDiffMaterialMask | gSpecMaterialMask, // TODO: improve? + footprintQuality, + historyLength, +#if( defined RELAX_DIFFUSE) prevDiffuseIlluminationAnd2ndMomentSMB, - prevSpecularIlluminationAnd2ndMomentSMBResponsive, prevDiffuseIlluminationAnd2ndMomentSMBResponsive, +#endif +#if( defined RELAX_SPECULAR) + prevSpecularIlluminationAnd2ndMomentSMB, + prevSpecularIlluminationAnd2ndMomentSMBResponsive, prevWorldPosSMB, - prevNormalSMB, prevReflectionHitTSMB, - historyLength, prevUVSMB, - footprintQuality +#endif + prevNormalSMB ); - // History length is based on surface motion based disocclusion + // History length is based on surface motion based disocclusion historyLength = historyLength + 1.0; historyLength = min(100.0, historyLength); + + // Avoid footprint momentary stretching due to changed viewing angle + float3 prevWorldPos = currentWorldPos + motionVector * float(gIsWorldSpaceMotionEnabled != 0); + float3 Vprev = normalize(prevWorldPos - gPrevCameraPosition.xyz); + float VoNflat = abs(dot(currentNormalAveraged, normalize(currentViewVector))) + 1e-3; + float VoNflatprev = abs(dot(currentNormalAveraged, Vprev)) + 1e-3; + float sizeQuality = VoNflatprev / VoNflat; // this order because we need to fix stretching only, shrinking is OK + sizeQuality *= sizeQuality; + sizeQuality *= sizeQuality; + footprintQuality *= lerp(0.1, 1.0, saturate(sizeQuality + abs(gOrthoMode))); + // Minimize "getting stuck in history" effect when only fraction of bilinear footprint is valid // by shortening the history length if (footprintQuality < 1.0) @@ -801,6 +860,7 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId // Handling history reset if needed if (gResetHistory != 0) historyLength = 1.0; +#if( defined RELAX_DIFFUSE ) // DIFFUSE ACCUMULATION BELOW // // Temporal accumulation of diffuse illumination @@ -817,15 +877,21 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId if (gUseConfidenceInputs) { - float inDiffConfidence = gDiffConfidence[ipos]; + float inDiffConfidence = gDiffConfidence[pixelPos]; diffMaxAccumulatedFrameNum *= inDiffConfidence; diffMaxFastAccumulatedFrameNum *= inDiffConfidence; } - float diffuseAlpha = (surfaceMotionBasedReprojectionFound > 0) ? max(1.0 / (diffMaxAccumulatedFrameNum + 1.0), 1.0 / historyLength.y) : 1.0; - float diffuseAlphaResponsive = (surfaceMotionBasedReprojectionFound > 0) ? max(1.0 / (diffMaxFastAccumulatedFrameNum + 1.0), 1.0 / historyLength.y) : 1.0; +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + float diffHistoryLength = historyLength.y; +#else + float diffHistoryLength = historyLength; +#endif + + float diffuseAlpha = (surfaceMotionBasedReprojectionFound > 0) ? max(1.0 / (diffMaxAccumulatedFrameNum + 1.0), 1.0 / diffHistoryLength) : 1.0; + float diffuseAlphaResponsive = (surfaceMotionBasedReprojectionFound > 0) ? max(1.0 / (diffMaxFastAccumulatedFrameNum + 1.0), 1.0 / diffHistoryLength) : 1.0; - if ((!diffHasData) && (historyLength.y > 1.0)) + if ((!diffHasData) && (diffHistoryLength > 1.0)) { // Adjusting diffuse accumulation weights for checkerboard diffuseAlpha *= 1.0 - gCheckerboardResolveAccumSpeed; @@ -836,31 +902,38 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId float3 accumulatedDiffuseIlluminationResponsive = lerp(prevDiffuseIlluminationAnd2ndMomentSMBResponsive.rgb, diffuseIllumination.rgb, diffuseAlphaResponsive); // Write out the diffuse results - gOutDiffuseIllumination[ipos] = accumulatedDiffuseIlluminationAnd2ndMoment; - gOutDiffuseIlluminationResponsive[ipos] = float4(accumulatedDiffuseIlluminationResponsive, 0); + gOutDiffuseIllumination[pixelPos] = accumulatedDiffuseIlluminationAnd2ndMoment; + gOutDiffuseIlluminationResponsive[pixelPos] = float4(accumulatedDiffuseIlluminationResponsive, 0); +#endif - gOutSpecularAndDiffuseHistoryLength[ipos] = historyLength / 255.0; + gOutHistoryLength[pixelPos] = historyLength / 255.0; +#if( defined RELAX_SPECULAR ) // SPECULAR ACCUMULATION BELOW // float specMaxAccumulatedFrameNum = gSpecularMaxAccumulatedFrameNum; float specMaxFastAccumulatedFrameNum = gSpecularMaxFastAccumulatedFrameNum; if (gUseConfidenceInputs) { - float inSpecConfidence = gSpecConfidence[ipos]; + float inSpecConfidence = gSpecConfidence[pixelPos]; specMaxAccumulatedFrameNum *= inSpecConfidence; specMaxFastAccumulatedFrameNum *= inSpecConfidence; } - float specHistoryFrames = min(specMaxAccumulatedFrameNum, historyLength.x); - float specHistoryResponsiveFrames = min(specMaxFastAccumulatedFrameNum, historyLength.x); +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + float specHistoryLength = historyLength.x; +#else + float specHistoryLength = historyLength; +#endif + float specHistoryFrames = min(specMaxAccumulatedFrameNum, specHistoryLength); + float specHistoryResponsiveFrames = min(specMaxFastAccumulatedFrameNum, specHistoryLength); // Calculating surface parallax - float parallax = ComputeParallax(currentWorldPos, currentWorldPos + motionVector * (gIsWorldSpaceMotion != 0 ? 1.0 : 0.0), gPrevCameraPositionAndJitterDelta.xyz); + float parallax = ComputeParallax(currentWorldPos, currentWorldPos + motionVector * (gIsWorldSpaceMotionEnabled != 0 ? 1.0 : 0.0), gPrevCameraPosition, gOrthoMode != 0); float parallaxOrig = parallax; float hitDistToSurfaceRatio = saturate(prevReflectionHitTSMB / currentLinearZ); parallax *= hitDistToSurfaceRatio; - float parallaxInPixels = GetParallaxInPixels(max(0.01, parallaxOrig)); + float parallaxInPixels = GetParallaxInPixels(max(0.01, parallaxOrig), gUnproject); // Params required for surface motion based (SMB) specular reprojection float3 V = normalize(-currentViewVector); @@ -875,14 +948,11 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId float surfaceHistoryConfidence = saturate(specSurfaceFrames / (specHistoryFrames + 1.0)); - if (!specHasData) + if (!specHasData && (parallaxInPixels < 2.0)) { // Adjusting surface motion based specular accumulation weights for checkerboard - if ((gIsOrtho == 0) || ((gIsOrtho != 0) && (gIsCameraStatic != 0))) - { - specSurfaceAlpha *= 1.0 - gCheckerboardResolveAccumSpeed * (surfaceMotionBasedReprojectionFound > 0 ? 1.0 : 0.0); - specSurfaceResponsiveAlpha *= 1.0 - gCheckerboardResolveAccumSpeed * (surfaceMotionBasedReprojectionFound > 0 ? 1.0 : 0.0); - } + specSurfaceAlpha *= 1.0 - gCheckerboardResolveAccumSpeed * (surfaceMotionBasedReprojectionFound > 0 ? 1.0 : 0.0); + specSurfaceResponsiveAlpha *= 1.0 - gCheckerboardResolveAccumSpeed * (surfaceMotionBasedReprojectionFound > 0 ? 1.0 : 0.0); } float4 accumulatedSpecularSMB; @@ -893,16 +963,18 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId float accumulatedSpecularM2SMB = lerp(prevSpecularIlluminationAnd2ndMomentSMB.a, specular2ndMoment, specSurfaceAlpha); // Thin lens equation for adjusting reflection HitT - float pixelSize = PixelRadiusToWorld(gUnproject, gIsOrtho, 1.0, currentLinearZ); + float pixelSize = PixelRadiusToWorld(gUnproject, gOrthoMode, 1.0, currentLinearZ); curvature *= NoV / pixelSize; float hitDist = specularIllumination.a; hitDist = lerp(minHitDist3x3, minHitDist5x5, STL::Math::SmoothStep(0.04, 0.08, currentRoughnessModified)); hitDist = clamp(hitDist, specM1.a - specSigma.a * 3.0, specM1.a + specSigma.a * 3.0); float divider = 0.5 + curvature * hitDist; - float hitDistFocused = max(0.001, 0.5 * hitDist / (divider == 0 ? 1.0 : divider)); + float hitDistFocused = 0.5 * hitDist / (divider == 0 ? 0.5 : divider); // Limiting hitDist in ortho case to avoid extreme amounts of motion in reflection - if(gIsOrtho != 0) hitDistFocused = min(currentLinearZ, hitDistFocused); + if(gOrthoMode != 0) hitDistFocused = min(currentLinearZ, hitDistFocused); + + if(abs(hitDistFocused) < 0.001) hitDistFocused = 0.001; // Loading specular data based on virtual motion float4 prevSpecularIlluminationAnd2ndMomentVMB; @@ -913,7 +985,7 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId float2 prevUVVMB; float virtualHistoryConfidence = loadVirtualMotionBasedPrevData( - ipos, + pixelPos, currentWorldPos, currentNormal, currentLinearZ, @@ -921,6 +993,8 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId currentViewVector, prevWorldPosSMB, surfaceMotionBasedReprojectionFound == 2.0 ? true : false, + currentMaterialID, + gSpecMaterialMask, prevSpecularIlluminationAnd2ndMomentVMB, prevSpecularIlluminationAnd2ndMomentVMBResponsive, prevNormalVMB, @@ -931,12 +1005,11 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId // Normal weight for virtual history float fresnelFactor = STL::BRDF::Pow5(NoV); - float normalWeightRenorm = lerp(0.9, 1.0, STL::Math::LinearStep(0.0, 0.15, currentRoughnessModified)); // mitigate imprecision problems introduced by normals encoded with different precision (test #6 and #12) float virtualLobeScale = lerp(0.5, 1.0, fresnelFactor); - float specNormalParams = STL::ImportanceSampling::GetSpecularLobeHalfAngle(currentRoughnessModified); - specNormalParams *= virtualLobeScale; - specNormalParams = 1.0 / max(specNormalParams, STL::Math::DegToRad(1.5)); - float virtualNormalWeight = GetNormalWeight(specNormalParams, currentNormal, prevNormalVMB); + float lobeHalfAngle = STL::ImportanceSampling::GetSpecularLobeHalfAngle(currentRoughnessModified); + lobeHalfAngle *= virtualLobeScale; + lobeHalfAngle += NRD_ENCODING_ERRORS.x + STL::Math::DegToRad(1.5); // TODO: tune better? + float virtualNormalWeight = GetEncodingAwareNormalWeight(currentNormal, prevNormalVMB, lobeHalfAngle); virtualHistoryConfidence *= lerp(virtualNormalWeight, 1.0, saturate(fresnelFactor * parallax)); @@ -953,14 +1026,14 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId float virtualHistoryAmount = virtualHistoryConfidence * D.w; // Virtual history confidence & amount - roughness - float2 roughnessParams = GetRoughnessWeightParams(currentRoughness); + float2 roughnessParams = GetRoughnessWeightParams(currentRoughness, gRoughnessFraction); float rw = GetRoughnessWeight(roughnessParams, prevRoughnessVMB); float virtualRoughnessWeight = 0.75 + 0.25 * rw; virtualHistoryConfidence *= virtualRoughnessWeight; - virtualHistoryAmount *= (gIsOrtho == 0) ? rw * 0.9 + 0.1 : 1.0; + virtualHistoryAmount *= (gOrthoMode == 0) ? rw * 0.9 + 0.1 : 1.0; // Decreasing virtual history amount for ortho case - virtualHistoryAmount *= (gIsOrtho == 0) ? 1.0 : 0.5; + virtualHistoryAmount *= (gOrthoMode == 0) ? 1.0 : 0.5; // Virtual history confidence - hit distance float maxDist = max(prevReflectionHitTVMB, prevReflectionHitTSMB); @@ -969,21 +1042,28 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId virtualHistoryConfidence *= virtualHistoryHitDistConfidence; // "Looking back" 1 and 2 frames and applying normal weight to decrease lags + float pixelSizeOverCurvatureRadius = curvature * pixelSize; + float avgCurvatureAngle = STL::Math::AtanApprox(abs(2.5 * pixelSizeOverCurvatureRadius)); + float uvDiffScale = lerp(10.0, 1.0, saturate(parallaxInPixels / 5.0)) / 2.0; float2 uvDiff = prevUVVMB - prevUVSMB; - float2 backUV1 = prevUVVMB + 1.0 * uvDiff; - float2 backUV2 = prevUVVMB + 2.0 * uvDiff; + float2 backUV1 = prevUVVMB + 1.0 * uvDiff * uvDiffScale; + float2 backUV2 = prevUVVMB + 2.0 * uvDiff * uvDiffScale; backUV1 *= (gInvResourceSize * gRectSizePrev); // Taking in account resolution scale backUV2 *= (gInvResourceSize * gRectSizePrev); float3 backNormal1 = UnpackPrevNormalRoughness(gPrevNormalRoughness.SampleLevel(gLinearClamp, backUV1, 0)).rgb; float3 backNormal2 = UnpackPrevNormalRoughness(gPrevNormalRoughness.SampleLevel(gLinearClamp, backUV2, 0)).rgb; - float backNormalWeight1 = GetNormalWeight(specNormalParams, currentNormal, backNormal1); - float backNormalWeight2 = GetNormalWeight(specNormalParams, currentNormal, backNormal2); + float maxAngle1 = lobeHalfAngle + avgCurvatureAngle * 1.0; + float maxAngle2 = lobeHalfAngle + avgCurvatureAngle * 2.0; + float backNormalWeight1 = IsInScreen(backUV1) ? GetEncodingAwareNormalWeight(currentNormal, backNormal1, maxAngle1) : 1.0; + float backNormalWeight2 = IsInScreen(backUV2) ? GetEncodingAwareNormalWeight(currentNormal, backNormal2, maxAngle2) : 1.0; float backNormalWeight = backNormalWeight1 * backNormalWeight2; virtualHistoryConfidence *= backNormalWeight; + virtualHistoryAmount *= lerp(0.333, 1.0, backNormalWeight); + // Clamping specular virtual history to current specular signal float4 specHistoryVirtual = float4(prevSpecularIlluminationAnd2ndMomentVMB.rgb, prevReflectionHitTVMB); - + if(gVirtualHistoryClampingEnabled != 0) { float SMC = STL::Math::SmoothStep(0.15, 0.25, currentRoughnessModified); @@ -1004,13 +1084,13 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId float specM2VirtualClamped = STL::Color::Clamp(specular2ndMoment, max(max(specSigma.r, specSigma.g), specSigma.b) * sigmaScale * 2.0, prevSpecularIlluminationAnd2ndMomentVMB.a); prevSpecularIlluminationAnd2ndMomentVMB.a = lerp(specM2VirtualClamped, prevSpecularIlluminationAnd2ndMomentVMB.a, virtualUnclampedAmount); } - + // Current specular signal ( virtual motion ) float specVirtualFrames = specHistoryFrames * virtualRoughnessWeight * (0.1 + 0.9 * backNormalWeight); float specVirtualResponsiveFrames = specHistoryResponsiveFrames * virtualRoughnessWeight * (0.0 + 1.0 * backNormalWeight); // Artificially decreasing virtual history frames if FPS is lower than 60 and virtual confidence is low, to decrease lags - float fpsScaler = lerp(max(0.25, min(gFramerateScale * gFramerateScale, 1.0)), 1.0, virtualHistoryConfidence); + float fpsScaler = lerp(saturate(gFramerateScale * gFramerateScale), 1.0, virtualHistoryConfidence); specVirtualResponsiveFrames *= fpsScaler; specVirtualFrames *= fpsScaler; @@ -1043,9 +1123,10 @@ NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId if (accumulatedSpecular2ndMoment == 0) accumulatedSpecular2ndMoment = gSpecularVarianceBoost * (1.0 - specularHistoryConfidence); // Write out the results - gOutSpecularIllumination[ipos] = float4(accumulatedSpecularIllumination, accumulatedSpecular2ndMoment); - gOutSpecularIlluminationResponsive[ipos] = float4(accumulatedSpecularIlluminationResponsive, 0); + gOutSpecularIllumination[pixelPos] = float4(accumulatedSpecularIllumination, accumulatedSpecular2ndMoment); + gOutSpecularIlluminationResponsive[pixelPos] = float4(accumulatedSpecularIlluminationResponsive, 0); - gOutReflectionHitT[ipos] = accumulatedReflectionHitT; - gOutSpecularReprojectionConfidence[ipos] = specularHistoryConfidence; + gOutReflectionHitT[pixelPos] = accumulatedReflectionHitT; + gOutSpecularReprojectionConfidence[pixelPos] = specularHistoryConfidence; +#endif } diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.resources.hlsli new file mode 100644 index 0000000..e3c937f --- /dev/null +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.resources.hlsli @@ -0,0 +1,134 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_Config.hlsli" +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gMotion, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularIlluminationResponsive, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseIlluminationResponsive, t, 6 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularIllumination, t, 7 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseIllumination, t, 8 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevNormalRoughness, t, 9 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevViewZ, t, 10 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevReflectionHitT, t, 11 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevHistoryLength, t, 12 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevMaterialID, t, 13 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecConfidence, t, 14 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffConfidence, t, 15 ) \ + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationResponsive, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationResponsive, u, 3 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutReflectionHitT, u, 4 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutHistoryLength, u, 5 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularReprojectionConfidence, u, 6 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gSpecularMaxAccumulatedFrameNum ) \ + NRD_CONSTANT( float, gSpecularMaxFastAccumulatedFrameNum ) \ + NRD_CONSTANT( float, gDiffuseMaxAccumulatedFrameNum ) \ + NRD_CONSTANT( float, gDiffuseMaxFastAccumulatedFrameNum ) \ + NRD_CONSTANT( uint, gDiffCheckerboard ) \ + NRD_CONSTANT( uint, gSpecCheckerboard ) \ + NRD_CONSTANT( float, gDisocclusionDepthThreshold ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANT( float, gSpecularVarianceBoost ) \ + NRD_CONSTANT( uint, gVirtualHistoryClampingEnabled ) \ + NRD_CONSTANT( uint, gSkipReprojectionTestWithoutMotion ) \ + NRD_CONSTANT( uint, gResetHistory ) \ + NRD_CONSTANT( float, gRejectDiffuseHistoryNormalThreshold ) \ + NRD_CONSTANT( uint, gUseConfidenceInputs ) \ + NRD_CONSTANTS_END + +#elif( defined RELAX_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gMotion, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseIlluminationResponsive, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseIllumination, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevNormalRoughness, t, 6 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevViewZ, t, 7 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevHistoryLength, t, 8 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevMaterialID, t, 9 ) \ + NRD_INPUT_TEXTURE( Texture2D, gDiffConfidence, t, 10 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationResponsive, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutHistoryLength, u, 2 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gDiffuseMaxAccumulatedFrameNum ) \ + NRD_CONSTANT( float, gDiffuseMaxFastAccumulatedFrameNum ) \ + NRD_CONSTANT( uint, gDiffCheckerboard ) \ + NRD_CONSTANT( float, gDisocclusionDepthThreshold ) \ + NRD_CONSTANT( uint, gSkipReprojectionTestWithoutMotion ) \ + NRD_CONSTANT( uint, gResetHistory ) \ + NRD_CONSTANT( float, gRejectDiffuseHistoryNormalThreshold ) \ + NRD_CONSTANT( uint, gUseConfidenceInputs ) \ + NRD_CONSTANTS_END + +#elif( defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gMotion, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 3 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularIlluminationResponsive, t, 4 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularIllumination, t, 5 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevNormalRoughness, t, 6 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevViewZ, t, 7 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevReflectionHitT, t, 8 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevHistoryLength, t, 9 ) \ + NRD_INPUT_TEXTURE( Texture2D, gPrevMaterialID, t, 10 ) \ + NRD_INPUT_TEXTURE( Texture2D, gSpecConfidence, t, 11 ) + + #define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationResponsive, u, 1 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutReflectionHitT, u, 2 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutHistoryLength, u, 3 ) \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularReprojectionConfidence, u, 4 ) + + #define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gSpecularMaxAccumulatedFrameNum ) \ + NRD_CONSTANT( float, gSpecularMaxFastAccumulatedFrameNum ) \ + NRD_CONSTANT( uint, gSpecCheckerboard ) \ + NRD_CONSTANT( float, gDisocclusionDepthThreshold ) \ + NRD_CONSTANT( float, gRoughnessFraction ) \ + NRD_CONSTANT( float, gSpecularVarianceBoost ) \ + NRD_CONSTANT( uint, gVirtualHistoryClampingEnabled ) \ + NRD_CONSTANT( uint, gSkipReprojectionTestWithoutMotion ) \ + NRD_CONSTANT( uint, gResetHistory ) \ + NRD_CONSTANT( uint, gUseConfidenceInputs ) \ + NRD_CONSTANTS_END + +#endif + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/RELAX_Diffuse_SplitScreen.cs.hlsl b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.hlsli similarity index 58% rename from Source/Shaders/RELAX_Diffuse_SplitScreen.cs.hlsl rename to Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.hlsli index 51b4286..ed26d71 100644 --- a/Source/Shaders/RELAX_Diffuse_SplitScreen.cs.hlsl +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "RELAX_Diffuse_SplitScreen.resources.hlsli" +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -21,7 +21,7 @@ NRD_DECLARE_SAMPLERS NRD_DECLARE_INPUT_TEXTURES NRD_DECLARE_OUTPUT_TEXTURES -[numthreads( 16, 16, 1)] +[numthreads( GROUP_X, GROUP_Y, 1)] NRD_EXPORT void NRD_CS_MAIN( uint2 pixelPos : SV_DispatchThreadId) { float2 pixelUv = float2( pixelPos + 0.5 ) * gInvRectSize; @@ -31,10 +31,17 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 pixelPos : SV_DispatchThreadId) return; float viewZ = gIn_ViewZ[ pixelPosUser ]; - uint2 checkerboardPos = pixelPos; - checkerboardPos.x = pixelPos.x >> (gDiffuseCheckerboard != 2 ? 1 : 0); - float3 diffResult = gIn_Diff[gRectOrigin + checkerboardPos]; - gOut_Diff[pixelPos] = diffResult * float(viewZ < gDenoisingRange); + #if( defined RELAX_DIFFUSE ) + checkerboardPos.x = pixelPos.x >> ( gDiffCheckerboard != 2 ? 1 : 0 ); + float4 diffResult = gIn_Diff[ gRectOrigin + checkerboardPos ]; + gOut_Diff[ pixelPos ] = diffResult * float( viewZ < gDenoisingRange ); + #endif + + #if( defined RELAX_SPECULAR ) + checkerboardPos.x = pixelPos.x >> ( gSpecCheckerboard != 2 ? 1 : 0 ); + float4 specResult = gIn_Spec[ gRectOrigin + checkerboardPos ]; + gOut_Spec[ pixelPos ] = specResult * float( viewZ < gDenoisingRange ); + #endif } diff --git a/Source/Shaders/Include/REBLUR_DiffuseSpecular_SplitScreen.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.resources.hlsli similarity index 71% rename from Source/Shaders/Include/REBLUR_DiffuseSpecular_SplitScreen.resources.hlsli rename to Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.resources.hlsli index 4622860..3e4f1ef 100644 --- a/Source/Shaders/Include/REBLUR_DiffuseSpecular_SplitScreen.resources.hlsli +++ b/Source/Shaders/Include/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.resources.hlsli @@ -8,58 +8,60 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_Config.hlsli" +#include "RELAX_Config.hlsli" -#if( defined REBLUR_DIFFUSE && defined REBLUR_SPECULAR ) - #define EXTRA_INPUTS \ +#if( defined RELAX_DIFFUSE && defined RELAX_SPECULAR ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 2 ) - #define EXTRA_OUTPUTS \ + #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 1 ) #define NRD_DECLARE_CONSTANTS \ NRD_CONSTANTS_START \ - REBLUR_DIFF_SPEC_SHARED_CB_DATA \ + RELAX_SHARED_CB_DATA \ + NRD_CONSTANT( float, gSplitScreen ) \ NRD_CONSTANT( uint, gDiffCheckerboard ) \ NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( float, gSplitScreen ) \ NRD_CONSTANTS_END -#elif( defined REBLUR_DIFFUSE ) - #define EXTRA_INPUTS \ + +#elif( defined RELAX_DIFFUSE ) + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) - #define EXTRA_OUTPUTS \ + #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) \ #define NRD_DECLARE_CONSTANTS \ NRD_CONSTANTS_START \ - REBLUR_DIFF_SHARED_CB_DATA \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ + RELAX_SHARED_CB_DATA \ NRD_CONSTANT( float, gSplitScreen ) \ + NRD_CONSTANT( uint, gDiffCheckerboard ) \ NRD_CONSTANTS_END + #else - #define EXTRA_INPUTS \ + + #define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 1 ) - #define EXTRA_OUTPUTS \ + #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) #define NRD_DECLARE_CONSTANTS \ NRD_CONSTANTS_START \ - REBLUR_SPEC_SHARED_CB_DATA \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ + RELAX_SHARED_CB_DATA \ NRD_CONSTANT( float, gSplitScreen ) \ + NRD_CONSTANT( uint, gSpecCheckerboard ) \ NRD_CONSTANTS_END -#endif - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ - EXTRA_INPUTS -#define NRD_DECLARE_OUTPUT_TEXTURES \ - EXTRA_OUTPUTS +#endif #define NRD_DECLARE_SAMPLERS \ NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_ATrousShmem.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_ATrousShmem.resources.hlsli deleted file mode 100644 index 7802158..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_ATrousShmem.resources.hlsli +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationAndVariance, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationAndVariance, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularReprojectionConfidence, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 5) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 1 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( uint2, gResourceSize ) \ - NRD_CONSTANT( float, gSpecularPhiLuminance ) \ - NRD_CONSTANT( float, gDiffusePhiLuminance ) \ - NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( float, gSpecularLobeAngleFraction ) \ - NRD_CONSTANT( float, gSpecularLobeAngleSlack ) \ - NRD_CONSTANT( uint, gStepSize ) \ - NRD_CONSTANT( uint, gRoughnessEdgeStoppingEnabled ) \ - NRD_CONSTANT( float, gRoughnessEdgeStoppingRelaxation ) \ - NRD_CONSTANT( float, gNormalEdgeStoppingRelaxation ) \ - NRD_CONSTANT( float, gLuminanceEdgeStoppingRelaxation ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_ATrousStandard.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_ATrousStandard.resources.hlsli deleted file mode 100644 index 65d68fd..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_ATrousStandard.resources.hlsli +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationAndVariance, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationAndVariance, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularReprojectionConfidence, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 5) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 1 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gSpecularPhiLuminance ) \ - NRD_CONSTANT( float, gDiffusePhiLuminance ) \ - NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( float, gSpecularLobeAngleFraction ) \ - NRD_CONSTANT( float, gSpecularLobeAngleSlack ) \ - NRD_CONSTANT( uint, gStepSize ) \ - NRD_CONSTANT( uint, gRoughnessEdgeStoppingEnabled ) \ - NRD_CONSTANT( float, gRoughnessEdgeStoppingRelaxation ) \ - NRD_CONSTANT( float, gNormalEdgeStoppingRelaxation ) \ - NRD_CONSTANT( float, gLuminanceEdgeStoppingRelaxation ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_DisocclusionFix.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_DisocclusionFix.resources.hlsli deleted file mode 100644 index a730e38..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_DisocclusionFix.resources.hlsli +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationResponsive, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationResponsive, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularAndDiffuseHistoryLength, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 5 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 6) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationResponsive, u, 2 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationResponsive, u, 3 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gDisocclusionFixEdgeStoppingNormalPower ) \ - NRD_CONSTANT( float, gMaxRadius ) \ - NRD_CONSTANT( int, gFramesToFix ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_Firefly.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_Firefly.resources.hlsli deleted file mode 100644 index 18c3e63..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_Firefly.resources.hlsli +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 3 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_HistoryClamping.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_HistoryClamping.resources.hlsli deleted file mode 100644 index 24652a1..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_HistoryClamping.resources.hlsli +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationResponsive, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationResponsive, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularAndDiffuseHistoryLength, t, 4 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularAndDiffuseHistoryLength, u, 2 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gColorBoxSigmaScale ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_Prepass.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_Prepass.resources.hlsli deleted file mode 100644 index 61ef2e4..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_Prepass.resources.hlsli +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 3) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutViewZ, u, 2) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutScaledViewZ, u, 3) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float4, gRotator) \ - NRD_CONSTANT( uint, gDiffuseCheckerboard ) \ - NRD_CONSTANT( uint, gSpecularCheckerboard ) \ - NRD_CONSTANT( float, gDiffuseBlurRadius ) \ - NRD_CONSTANT( float, gSpecularBlurRadius ) \ - NRD_CONSTANT( float, gMeterToUnitsMultiplier ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_Reproject.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_Reproject.resources.hlsli deleted file mode 100644 index d9c948e..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_Reproject.resources.hlsli +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gMotion, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularIlluminationResponsive, t, 5 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseIlluminationResponsive, t, 6 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularIllumination, t, 7 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseIllumination, t, 8 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevNormalRoughness, t, 9 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevViewZ, t, 10 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevReflectionHitT, t, 11 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularAndDiffuseHistoryLength, t, 12) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecConfidence, t, 13 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffConfidence, t, 14 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationResponsive, u, 2 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationResponsive, u, 3 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutReflectionHitT, u, 4 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularAndDiffuseHistoryLength, u, 5 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularReprojectionConfidence, u, 6 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gSpecularMaxAccumulatedFrameNum ) \ - NRD_CONSTANT( float, gSpecularMaxFastAccumulatedFrameNum ) \ - NRD_CONSTANT( float, gDiffuseMaxAccumulatedFrameNum ) \ - NRD_CONSTANT( float, gDiffuseMaxFastAccumulatedFrameNum ) \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( float, gDisocclusionDepthThreshold ) \ - NRD_CONSTANT( float, gSpecularVarianceBoost ) \ - NRD_CONSTANT( uint, gVirtualHistoryClampingEnabled ) \ - NRD_CONSTANT( uint, gSkipReprojectionTestWithoutMotion ) \ - NRD_CONSTANT( uint, gResetHistory ) \ - NRD_CONSTANT( float, gRejectDiffuseHistoryNormalThreshold ) \ - NRD_CONSTANT( uint, gUseConfidenceInputs ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_SpatialVarianceEstimation.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_SpatialVarianceEstimation.resources.hlsli deleted file mode 100644 index a9abdea..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_SpatialVarianceEstimation.resources.hlsli +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 4) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutNormalRoughness, u, 2) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( uint, gHistoryThreshold ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_DiffuseSpecular_SplitScreen.resources.hlsli b/Source/Shaders/Include/RELAX_DiffuseSpecular_SplitScreen.resources.hlsli deleted file mode 100644 index 5ed37d3..0000000 --- a/Source/Shaders/Include/RELAX_DiffuseSpecular_SplitScreen.resources.hlsli +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 2 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 1 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( uint, gDiffuseCheckerboard ) \ - NRD_CONSTANT( uint, gSpecularCheckerboard ) \ - NRD_CONSTANT( float, gSplitScreen ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_ATrousShmem.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_ATrousShmem.resources.hlsli deleted file mode 100644 index 5035723..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_ATrousShmem.resources.hlsli +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationAndVariance, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE(Texture2D, gViewZFP16, t, 3) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 0 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( uint2, gResourceSize ) \ - NRD_CONSTANT( float, gDiffusePhiLuminance ) \ - NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( uint, gStepSize ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_ATrousStandard.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_ATrousStandard.resources.hlsli deleted file mode 100644 index a7d1b21..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_ATrousStandard.resources.hlsli +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationAndVariance, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE(Texture2D, gViewZFP16, t, 3) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 0 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDiffusePhiLuminance ) \ - NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( uint, gStepSize ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_DisocclusionFix.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_DisocclusionFix.resources.hlsli deleted file mode 100644 index 2dae0b3..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_DisocclusionFix.resources.hlsli +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIlluminationResponsive, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseHistoryLength, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ - NRD_INPUT_TEXTURE(Texture2D, gViewZFP16, t, 4) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationResponsive, u, 1 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gDisocclusionFixEdgeStoppingNormalPower ) \ - NRD_CONSTANT( float, gMaxRadius ) \ - NRD_CONSTANT( int, gFramesToFix ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_Firefly.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_Firefly.resources.hlsli deleted file mode 100644 index dc5c0b6..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_Firefly.resources.hlsli +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 1 ) \ - NRD_INPUT_TEXTURE(Texture2D, gViewZFP16, t, 2) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_HistoryClamping.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_HistoryClamping.resources.hlsli deleted file mode 100644 index f9a312e..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_HistoryClamping.resources.hlsli +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseResponsiveIllumination, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseHistoryLength, t, 2 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseHistoryLength, u, 1 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gColorBoxSigmaScale ) \ - NRD_CONSTANT( float, gDiffuseAntiLagSigmaScale ) \ - NRD_CONSTANT( float, gDiffuseAntiLagPower ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_Prepass.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_Prepass.resources.hlsli deleted file mode 100644 index 8a09a59..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_Prepass.resources.hlsli +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 2) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutViewZ, u, 1) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutScaledViewZ, u, 2) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float4, gRotator) \ - NRD_CONSTANT( uint, gDiffuseCheckerboard ) \ - NRD_CONSTANT( float, gDiffuseBlurRadius ) \ - NRD_CONSTANT( float, gMeterToUnitsMultiplier ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_Reproject.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_Reproject.resources.hlsli deleted file mode 100644 index dac3c8a..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_Reproject.resources.hlsli +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gMotion, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseIlluminationResponsive, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseIllumination, t, 5 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevNormalRoughness, t, 6 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevViewZ, t, 7 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevDiffuseHistoryLength, t, 8) \ - NRD_INPUT_TEXTURE( Texture2D, gDiffConfidence, t, 9) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationResponsive, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseHistoryLength, u, 2 ) - - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDiffuseMaxAccumulatedFrameNum ) \ - NRD_CONSTANT( float, gDiffuseMaxFastAccumulatedFrameNum ) \ - NRD_CONSTANT( uint, gDiffCheckerboard ) \ - NRD_CONSTANT( float, gDisocclusionDepthThreshold ) \ - NRD_CONSTANT( uint, gSkipReprojectionTestWithoutMotion ) \ - NRD_CONSTANT( uint, gResetHistory ) \ - NRD_CONSTANT( float, gRejectDiffuseHistoryNormalThreshold ) \ - NRD_CONSTANT( uint, gUseConfidenceInputs ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_SpatialVarianceEstimation.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_SpatialVarianceEstimation.resources.hlsli deleted file mode 100644 index 101cf8e..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_SpatialVarianceEstimation.resources.hlsli +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gDiffuseIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE(Texture2D, gViewZ, t, 3) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutDiffuseIlluminationAndVariance, u, 0 ) \ - NRD_OUTPUT_TEXTURE(RWTexture2D, gOutNormalRoughness, u, 1) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( uint, gHistoryThreshold ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Diffuse_SplitScreen.resources.hlsli b/Source/Shaders/Include/RELAX_Diffuse_SplitScreen.resources.hlsli deleted file mode 100644 index 50b28e7..0000000 --- a/Source/Shaders/Include/RELAX_Diffuse_SplitScreen.resources.hlsli +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Diff, t, 1 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Diff, u, 0 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( uint, gDiffuseCheckerboard ) \ - NRD_CONSTANT( float, gSplitScreen ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_ATrousShmem.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_ATrousShmem.resources.hlsli deleted file mode 100644 index 7c96722..0000000 --- a/Source/Shaders/Include/RELAX_Specular_ATrousShmem.resources.hlsli +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationAndVariance, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularReprojectionConfidence, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 4) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( uint2, gResourceSize ) \ - NRD_CONSTANT( float, gSpecularPhiLuminance ) \ - NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( float, gSpecularLobeAngleFraction ) \ - NRD_CONSTANT( float, gSpecularLobeAngleSlack ) \ - NRD_CONSTANT( uint, gStepSize ) \ - NRD_CONSTANT( uint, gRoughnessEdgeStoppingEnabled ) \ - NRD_CONSTANT( float, gRoughnessEdgeStoppingRelaxation ) \ - NRD_CONSTANT( float, gNormalEdgeStoppingRelaxation ) \ - NRD_CONSTANT( float, gLuminanceEdgeStoppingRelaxation ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_ATrousStandard.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_ATrousStandard.resources.hlsli deleted file mode 100644 index 298a1e5..0000000 --- a/Source/Shaders/Include/RELAX_Specular_ATrousStandard.resources.hlsli +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationAndVariance, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularReprojectionConfidence, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 4) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gSpecularPhiLuminance ) \ - NRD_CONSTANT( float, gMaxLuminanceRelativeDifference ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( float, gSpecularLobeAngleFraction ) \ - NRD_CONSTANT( float, gSpecularLobeAngleSlack ) \ - NRD_CONSTANT( uint, gStepSize ) \ - NRD_CONSTANT( uint, gRoughnessEdgeStoppingEnabled ) \ - NRD_CONSTANT( float, gRoughnessEdgeStoppingRelaxation ) \ - NRD_CONSTANT( float, gNormalEdgeStoppingRelaxation ) \ - NRD_CONSTANT( float, gLuminanceEdgeStoppingRelaxation ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_DisocclusionFix.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_DisocclusionFix.resources.hlsli deleted file mode 100644 index e7f8020..0000000 --- a/Source/Shaders/Include/RELAX_Specular_DisocclusionFix.resources.hlsli +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIlluminationResponsive, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularHistoryLength, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 4) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationResponsive, u, 1 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANT( float, gDisocclusionFixEdgeStoppingNormalPower ) \ - NRD_CONSTANT( float, gMaxRadius ) \ - NRD_CONSTANT( int, gFramesToFix ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_Firefly.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_Firefly.resources.hlsli deleted file mode 100644 index 7bca107..0000000 --- a/Source/Shaders/Include/RELAX_Specular_Firefly.resources.hlsli +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZFP16, t, 3 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_HistoryClamping.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_HistoryClamping.resources.hlsli deleted file mode 100644 index 197624a..0000000 --- a/Source/Shaders/Include/RELAX_Specular_HistoryClamping.resources.hlsli +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularResponsiveIllumination, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularHistoryLength, t, 2 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularHistoryLength, u, 1 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gColorBoxSigmaScale ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_Prepass.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_Prepass.resources.hlsli deleted file mode 100644 index 6303e1a..0000000 --- a/Source/Shaders/Include/RELAX_Specular_Prepass.resources.hlsli +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 2) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutViewZ, u, 1) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutScaledViewZ, u, 2) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float4, gRotator) \ - NRD_CONSTANT( uint, gSpecularCheckerboard ) \ - NRD_CONSTANT( float, gSpecularBlurRadius ) \ - NRD_CONSTANT( float, gMeterToUnitsMultiplier ) \ - NRD_CONSTANT( float, gDepthThreshold ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_Reproject.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_Reproject.resources.hlsli deleted file mode 100644 index f3e5c33..0000000 --- a/Source/Shaders/Include/RELAX_Specular_Reproject.resources.hlsli +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gMotion, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE( Texture2D, gViewZ, t, 3 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularIlluminationResponsive, t, 4 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularIllumination, t, 5 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevNormalRoughness, t, 6 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevViewZ, t, 7 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevReflectionHitT, t, 8 ) \ - NRD_INPUT_TEXTURE( Texture2D, gPrevSpecularHistoryLength, t, 9) \ - NRD_INPUT_TEXTURE( Texture2D, gSpecConfidence, t, 10 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIllumination, u, 0 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationResponsive, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutReflectionHitT, u, 2 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularHistoryLength, u, 3 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularReprojectionConfidence, u, 4 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gSpecularMaxAccumulatedFrameNum ) \ - NRD_CONSTANT( float, gSpecularMaxFastAccumulatedFrameNum ) \ - NRD_CONSTANT( uint, gSpecCheckerboard ) \ - NRD_CONSTANT( float, gDisocclusionDepthThreshold ) \ - NRD_CONSTANT( float, gSpecularVarianceBoost ) \ - NRD_CONSTANT( uint, gVirtualHistoryClampingEnabled ) \ - NRD_CONSTANT( uint, gSkipReprojectionTestWithoutMotion ) \ - NRD_CONSTANT( uint, gResetHistory ) \ - NRD_CONSTANT( uint, gUseConfidenceInputs ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_SpatialVarianceEstimation.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_SpatialVarianceEstimation.resources.hlsli deleted file mode 100644 index 4018cee..0000000 --- a/Source/Shaders/Include/RELAX_Specular_SpatialVarianceEstimation.resources.hlsli +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gSpecularIllumination, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gHistoryLength, t, 1 ) \ - NRD_INPUT_TEXTURE( Texture2D, gNormalRoughness, t, 2 ) \ - NRD_INPUT_TEXTURE(Texture2D, gViewZ, t, 3) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOutSpecularIlluminationAndVariance, u, 0 ) \ - NRD_OUTPUT_TEXTURE(RWTexture2D, gOutNormalRoughness, u, 1) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( float, gPhiNormal ) \ - NRD_CONSTANT( uint, gHistoryThreshold ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/RELAX_Specular_SplitScreen.resources.hlsli b/Source/Shaders/Include/RELAX_Specular_SplitScreen.resources.hlsli deleted file mode 100644 index aa21bc9..0000000 --- a/Source/Shaders/Include/RELAX_Specular_SplitScreen.resources.hlsli +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "RELAX_Config.hlsli" - -#define NRD_DECLARE_INPUT_TEXTURES \ - NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 0 ) \ - NRD_INPUT_TEXTURE( Texture2D, gIn_Spec, t, 1 ) - -#define NRD_DECLARE_OUTPUT_TEXTURES \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_Spec, u, 0 ) - -#define NRD_DECLARE_CONSTANTS \ - NRD_CONSTANTS_START \ - RELAX_SHARED_CB_DATA \ - NRD_CONSTANT( uint, gSpecularCheckerboard ) \ - NRD_CONSTANT( float, gSplitScreen ) \ - NRD_CONSTANTS_END - -#define NRD_DECLARE_SAMPLERS \ - NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/Include/SIGMA_Config.hlsli b/Source/Shaders/Include/SIGMA_Config.hlsli index 35af70d..4031302 100644 --- a/Source/Shaders/Include/SIGMA_Config.hlsli +++ b/Source/Shaders/Include/SIGMA_Config.hlsli @@ -38,13 +38,13 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_CONSTANT( float2, gResolutionScale ) \ NRD_CONSTANT( float2, gRectOffset ) \ NRD_CONSTANT( uint2, gRectOrigin ) \ - NRD_CONSTANT( float, gIsOrtho ) \ + NRD_CONSTANT( float, gOrthoMode ) \ NRD_CONSTANT( float, gUnproject ) \ NRD_CONSTANT( float, gDebug ) \ - NRD_CONSTANT( float, gInf ) \ + NRD_CONSTANT( float, gDenoisingRange ) \ NRD_CONSTANT( float, gPlaneDistSensitivity ) \ NRD_CONSTANT( float, gBlurRadiusScale ) \ NRD_CONSTANT( float, gUnused2 ) \ - NRD_CONSTANT( uint, gWorldSpaceMotion ) \ + NRD_CONSTANT( uint, gIsWorldSpaceMotionEnabled ) \ NRD_CONSTANT( uint, gFrameIndex ) \ NRD_CONSTANT( uint, gUnused1 ) diff --git a/Source/Shaders/Include/SIGMA_Shadow_Blur.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_Blur.hlsli similarity index 95% rename from Source/Shaders/Include/SIGMA_Shadow_Blur.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_Blur.hlsli index 199404a..e4d9b3e 100644 --- a/Source/Shaders/Include/SIGMA_Shadow_Blur.hlsli +++ b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_Blur.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "SIGMA_Shadow_Blur.resources.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_Blur.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -99,7 +99,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #endif [branch] - if( viewZ > gInf || centerHitDist == 0.0 || tileValue == 0.0 ) + if( viewZ > gDenoisingRange || centerHitDist == 0.0 || tileValue == 0.0 ) { gOut_Shadow_Translucency[ pixelPos ] = PackShadow( s_Shadow_Translucency[ smemPos.y ][ smemPos.x ] ); gOut_Hit_ViewZ[ pixelPos ] = float2( 0.0, viewZ * NRD_FP16_VIEWZ_SCALE ); @@ -115,7 +115,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #endif // Position - float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gIsOrtho ); + float3 Xv = STL::Geometry::ReconstructViewPosition( pixelUv, gFrustum, viewZ, gOrthoMode ); // Normal float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness( gIn_Normal_Roughness[ pixelPosUser ] ); @@ -164,7 +164,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : float worldRadius = hitDist * innerShadowRadiusScale * outerShadowRadiusScale * gBlurRadiusScale; worldRadius *= tileValue; - float unprojectZ = PixelRadiusToWorld( gUnproject, gIsOrtho, 1.0, viewZ ); + float unprojectZ = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); float pixelRadius = worldRadius * STL::Math::PositiveRcp( unprojectZ ); pixelRadius = min( pixelRadius, SIGMA_MAX_PIXEL_RADIUS ); worldRadius = pixelRadius * unprojectZ; @@ -183,7 +183,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Denoising sum = 1.0; - float frustumHeight = PixelRadiusToWorld( gUnproject, gIsOrtho, gRectSize.y, viewZ ); + float frustumHeight = PixelRadiusToWorld( gUnproject, gOrthoMode, gRectSize.y, viewZ ); float2 geometryWeightParams = GetGeometryWeightParams( gPlaneDistSensitivity, frustumHeight, Xv, Nv, SIGMA_PLANE_DISTANCE_SCALE ); [unroll] @@ -216,7 +216,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : #endif // Sample weight - float3 samplePos = STL::Geometry::ReconstructViewPosition( uv, gFrustum, z, gIsOrtho ); + float3 samplePos = STL::Geometry::ReconstructViewPosition( uv, gFrustum, z, gOrthoMode ); float w = GetGeometryWeight( geometryWeightParams, Nv, samplePos ); w *= saturate( 1.0 - abs( centerSignNoL - signNoL ) ); w *= IsInScreen( uv ); diff --git a/Source/Shaders/Include/SIGMA_Shadow_Blur.resources.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_Blur.resources.hlsli similarity index 100% rename from Source/Shaders/Include/SIGMA_Shadow_Blur.resources.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_Blur.resources.hlsli diff --git a/Source/Shaders/Include/SIGMA_Shadow_ClassifyTiles.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.hlsli similarity index 94% rename from Source/Shaders/Include/SIGMA_Shadow_ClassifyTiles.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.hlsli index 16efb5c..46a4f8e 100644 --- a/Source/Shaders/Include/SIGMA_Shadow_ClassifyTiles.hlsli +++ b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "SIGMA_Shadow_ClassifyTiles.resources.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -51,7 +51,7 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 threadPos : SV_GroupThreadId, uint2 tilePos : float viewZ = abs( data.y ) / NRD_FP16_VIEWZ_SCALE; - bool isInf = viewZ > gInf || data.x == 0; + bool isInf = viewZ > gDenoisingRange || data.x == 0; bool isLit = data.x == NRD_FP16_MAX; bool isOpaque = true; @@ -64,7 +64,7 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 threadPos : SV_GroupThreadId, uint2 tilePos : mask += ( ( ( !isLit && isOpaque ) || isInf ) ? 1 : 0 ) << 16; float worldRadius = ( isLit || isInf ) ? 0 : ( data.x * gBlurRadiusScale ); - float unprojectZ = PixelRadiusToWorld( gUnproject, gIsOrtho, 1.0, viewZ ); + float unprojectZ = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); float pixelRadius = worldRadius * STL::Math::PositiveRcp( unprojectZ ); pixelRadius = min( pixelRadius, SIGMA_MAX_PIXEL_RADIUS ); diff --git a/Source/Shaders/Include/SIGMA_Shadow_ClassifyTiles.resources.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.resources.hlsli similarity index 100% rename from Source/Shaders/Include/SIGMA_Shadow_ClassifyTiles.resources.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.resources.hlsli diff --git a/Source/Shaders/Include/SIGMA_Shadow_PreBlur.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_PreBlur.hlsli similarity index 90% rename from Source/Shaders/Include/SIGMA_Shadow_PreBlur.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_PreBlur.hlsli index 09d4f08..a92c424 100644 --- a/Source/Shaders/Include/SIGMA_Shadow_PreBlur.hlsli +++ b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_PreBlur.hlsli @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define SIGMA_FIRST_PASS -#include "SIGMA_Shadow_Blur.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_Blur.hlsli" diff --git a/Source/Shaders/Include/SIGMA_Shadow_SmoothTiles.resources.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_SmoothTiles.resources.hlsli similarity index 100% rename from Source/Shaders/Include/SIGMA_Shadow_SmoothTiles.resources.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_SmoothTiles.resources.hlsli diff --git a/Source/Shaders/Include/SIGMA_Shadow_SplitScreen.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_SplitScreen.hlsli similarity index 88% rename from Source/Shaders/Include/SIGMA_Shadow_SplitScreen.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_SplitScreen.hlsli index a34f126..c173f84 100644 --- a/Source/Shaders/Include/SIGMA_Shadow_SplitScreen.hlsli +++ b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_SplitScreen.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "SIGMA_Shadow_SplitScreen.resources.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_SplitScreen.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -40,5 +40,5 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 pixelPos : SV_DispatchThreadId) s = float( data.x == NRD_FP16_MAX ); #endif - gOut_Shadow_Translucency[ pixelPos ] = s * float( viewZ < gInf ); + gOut_Shadow_Translucency[ pixelPos ] = s * float( viewZ < gDenoisingRange ); } diff --git a/Source/Shaders/Include/SIGMA_Shadow_SplitScreen.resources.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_SplitScreen.resources.hlsli similarity index 100% rename from Source/Shaders/Include/SIGMA_Shadow_SplitScreen.resources.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_SplitScreen.resources.hlsli diff --git a/Source/Shaders/Include/SIGMA_Shadow_TemporalStabilization.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.hlsli similarity index 94% rename from Source/Shaders/Include/SIGMA_Shadow_TemporalStabilization.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.hlsli index 90055de..ac4b6a9 100644 --- a/Source/Shaders/Include/SIGMA_Shadow_TemporalStabilization.hlsli +++ b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.hlsli @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "SIGMA_Shadow_TemporalStabilization.resources.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.resources.hlsli" NRD_DECLARE_CONSTANTS @@ -60,7 +60,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Early out [branch] - if( viewZ > gInf || ( centerHitDist == 0.0 && SIGMA_SHOW_TILES == 0 ) ) + if( viewZ > gDenoisingRange || ( centerHitDist == 0.0 && SIGMA_SHOW_TILES == 0 ) ) { gOut_Shadow_Translucency[ pixelPos ] = PackShadow( s_Shadow_Translucency[ smemPos.y ][ smemPos.x ] ); return; @@ -119,10 +119,10 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Compute previous pixel position offseti -= BORDER; float2 offset = float2( offseti ) * gInvRectSize; - float3 Xvnearest = STL::Geometry::ReconstructViewPosition( pixelUv + offset, gFrustum, viewZnearest, gIsOrtho ); + float3 Xvnearest = STL::Geometry::ReconstructViewPosition( pixelUv + offset, gFrustum, viewZnearest, gOrthoMode ); float3 Xnearest = STL::Geometry::AffineTransform( gViewToWorld, Xvnearest ); float3 motionVector = gIn_ObjectMotion[ pixelPosUser + offseti ] * gMotionVectorScale.xyy; - float2 pixelUvPrev = STL::Geometry::GetPrevUvFromMotion( pixelUv + offset, Xnearest, gWorldToClipPrev, motionVector, gWorldSpaceMotion ); + float2 pixelUvPrev = STL::Geometry::GetPrevUvFromMotion( pixelUv + offset, Xnearest, gWorldToClipPrev, motionVector, gIsWorldSpaceMotionEnabled ); pixelUvPrev -= offset; float isInScreen = IsInScreen( pixelUvPrev ); @@ -166,7 +166,7 @@ NRD_EXPORT void NRD_CS_MAIN( int2 threadPos : SV_GroupThreadId, int2 pixelPos : // Reduce history in regions with hard shadows float worldRadius = centerHitDist * gBlurRadiusScale; - float unprojectZ = PixelRadiusToWorld( gUnproject, gIsOrtho, 1.0, viewZ ); + float unprojectZ = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); float pixelRadius = worldRadius * STL::Math::PositiveRcp( unprojectZ ); historyWeight *= STL::Math::LinearStep( 0.0, 3.0, pixelRadius ); diff --git a/Source/Shaders/Include/SIGMA_Shadow_TemporalStabilization.resources.hlsli b/Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.resources.hlsli similarity index 100% rename from Source/Shaders/Include/SIGMA_Shadow_TemporalStabilization.resources.hlsli rename to Source/Shaders/Include/SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.resources.hlsli diff --git a/Source/Shaders/Include/NRD_Clear_f.resources.hlsli b/Source/Shaders/Include/Shared/NRD_Clear_f.resources.hlsli similarity index 100% rename from Source/Shaders/Include/NRD_Clear_f.resources.hlsli rename to Source/Shaders/Include/Shared/NRD_Clear_f.resources.hlsli diff --git a/Source/Shaders/Include/NRD_Clear_ui.resources.hlsli b/Source/Shaders/Include/Shared/NRD_Clear_ui.resources.hlsli similarity index 100% rename from Source/Shaders/Include/NRD_Clear_ui.resources.hlsli rename to Source/Shaders/Include/Shared/NRD_Clear_ui.resources.hlsli diff --git a/Source/Shaders/Include/NRD_MipGeneration_Float2.resources.hlsli b/Source/Shaders/Include/Shared/NRD_MipGeneration_Float2.resources.hlsli similarity index 84% rename from Source/Shaders/Include/NRD_MipGeneration_Float2.resources.hlsli rename to Source/Shaders/Include/Shared/NRD_MipGeneration_Float2.resources.hlsli index 4d29832..ef011d4 100644 --- a/Source/Shaders/Include/NRD_MipGeneration_Float2.resources.hlsli +++ b/Source/Shaders/Include/Shared/NRD_MipGeneration_Float2.resources.hlsli @@ -14,13 +14,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define NRD_DECLARE_OUTPUT_TEXTURES \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x2, u, 0 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x4, u, 1 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x8, u, 2 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x16, u, 3 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x8, u, 2 ) #define NRD_DECLARE_CONSTANTS \ NRD_CONSTANTS_START \ NRD_CONSTANT( uint2, gRectSize ) \ - NRD_CONSTANT( float, gInf ) \ + NRD_CONSTANT( float, gDenoisingRange ) \ NRD_CONSTANT( float, gDebug ) \ NRD_CONSTANTS_END diff --git a/Source/Shaders/Include/NRD_MipGeneration_Float2_Float2.resources.hlsli b/Source/Shaders/Include/Shared/NRD_MipGeneration_Float2_Float2.resources.hlsli similarity index 83% rename from Source/Shaders/Include/NRD_MipGeneration_Float2_Float2.resources.hlsli rename to Source/Shaders/Include/Shared/NRD_MipGeneration_Float2_Float2.resources.hlsli index 2c42a10..4a4f026 100644 --- a/Source/Shaders/Include/NRD_MipGeneration_Float2_Float2.resources.hlsli +++ b/Source/Shaders/Include/Shared/NRD_MipGeneration_Float2_Float2.resources.hlsli @@ -18,14 +18,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x4, u, 2 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_B_x4, u, 3 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x8, u, 4 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_B_x8, u, 5 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x16, u, 6 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_B_x16, u, 7 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_B_x8, u, 5 ) #define NRD_DECLARE_CONSTANTS \ NRD_CONSTANTS_START \ NRD_CONSTANT( uint2, gRectSize ) \ - NRD_CONSTANT( float, gInf ) \ + NRD_CONSTANT( float, gDenoisingRange ) \ NRD_CONSTANT( float, gDebug ) \ NRD_CONSTANTS_END diff --git a/Source/Shaders/Include/NRD_MipGeneration_Float4_Float.resources.hlsli b/Source/Shaders/Include/Shared/NRD_MipGeneration_Float4_Float.resources.hlsli similarity index 86% rename from Source/Shaders/Include/NRD_MipGeneration_Float4_Float.resources.hlsli rename to Source/Shaders/Include/Shared/NRD_MipGeneration_Float4_Float.resources.hlsli index 252975b..f8118c2 100644 --- a/Source/Shaders/Include/NRD_MipGeneration_Float4_Float.resources.hlsli +++ b/Source/Shaders/Include/Shared/NRD_MipGeneration_Float4_Float.resources.hlsli @@ -18,14 +18,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x4, u, 2 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ScaledViewZ_x4, u, 3 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x8, u, 4 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ScaledViewZ_x8, u, 5 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x16, u, 6 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ScaledViewZ_x16, u, 7 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ScaledViewZ_x8, u, 5 ) #define NRD_DECLARE_CONSTANTS \ NRD_CONSTANTS_START \ NRD_CONSTANT( uint2, gRectSize ) \ - NRD_CONSTANT( float, gInf ) \ + NRD_CONSTANT( float, gDenoisingRange ) \ NRD_CONSTANT( float, gDebug ) \ NRD_CONSTANTS_END diff --git a/Source/Shaders/Include/NRD_MipGeneration_Float4_Float4_Float.resources.hlsli b/Source/Shaders/Include/Shared/NRD_MipGeneration_Float4_Float4_Float.resources.hlsli similarity index 85% rename from Source/Shaders/Include/NRD_MipGeneration_Float4_Float4_Float.resources.hlsli rename to Source/Shaders/Include/Shared/NRD_MipGeneration_Float4_Float4_Float.resources.hlsli index 3588903..4bcf8c5 100644 --- a/Source/Shaders/Include/NRD_MipGeneration_Float4_Float4_Float.resources.hlsli +++ b/Source/Shaders/Include/Shared/NRD_MipGeneration_Float4_Float4_Float.resources.hlsli @@ -22,15 +22,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ScaledViewZ_x4, u, 5 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x8, u, 6 ) \ NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_B_x8, u, 7 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ScaledViewZ_x8, u, 8 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_A_x16, u, 9 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_B_x16, u, 10 ) \ - NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ScaledViewZ_x16, u, 11 ) + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_ScaledViewZ_x8, u, 8 ) #define NRD_DECLARE_CONSTANTS \ NRD_CONSTANTS_START \ NRD_CONSTANT( uint2, gRectSize ) \ - NRD_CONSTANT( float, gInf ) \ + NRD_CONSTANT( float, gDenoisingRange ) \ NRD_CONSTANT( float, gDebug ) \ NRD_CONSTANTS_END diff --git a/Source/Shaders/Include/SpecularReflectionMv/SpecularReflectionMv_Compute.resources.hlsli b/Source/Shaders/Include/SpecularReflectionMv/SpecularReflectionMv_Compute.resources.hlsli new file mode 100644 index 0000000..1e7a156 --- /dev/null +++ b/Source/Shaders/Include/SpecularReflectionMv/SpecularReflectionMv_Compute.resources.hlsli @@ -0,0 +1,35 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define NRD_DECLARE_INPUT_TEXTURES \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ObjectMotion, t, 0 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_Normal_Roughness, t, 1 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_ViewZ, t, 2 ) \ + NRD_INPUT_TEXTURE( Texture2D, gIn_HitDist, t, 3 ) + +#define NRD_DECLARE_OUTPUT_TEXTURES \ + NRD_OUTPUT_TEXTURE( RWTexture2D, gOut_SpecularReflectionMv, u, 0 ) + +#define NRD_DECLARE_CONSTANTS \ + NRD_CONSTANTS_START \ + NRD_CONSTANT( float4x4, gViewToWorld ) \ + NRD_CONSTANT( float4x4, gWorldToClipPrev ) \ + NRD_CONSTANT( float4, gFrustum ) \ + NRD_CONSTANT( float4, gViewVectorWorld ) \ + NRD_CONSTANT( float2, gInvRectSize ) \ + NRD_CONSTANT( float2, gMotionVectorScale ) \ + NRD_CONSTANT( uint2, gRectOrigin ) \ + NRD_CONSTANT( float, gOrthoMode ) \ + NRD_CONSTANT( float, gUnproject ) \ + NRD_CONSTANT( uint, gIsWorldSpaceMotionEnabled ) \ + NRD_CONSTANTS_END + +#define NRD_DECLARE_SAMPLERS \ + NRD_COMMON_SAMPLERS diff --git a/Source/Shaders/REBLUR_Diffuse_AntiFirefly.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_AntiFirefly.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Diffuse_AntiFirefly.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_AntiFirefly.cs.hlsl index f65597a..b4fa57e 100644 --- a/Source/Shaders/REBLUR_Diffuse_AntiFirefly.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_AntiFirefly.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecular_AntiFirefly.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_Blur.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_Blur.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_Diffuse_Blur.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_Blur.cs.hlsl index 65607d1..74eb518 100644 --- a/Source/Shaders/REBLUR_Diffuse_Blur.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_Blur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecular_Blur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_HistoryFix.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Diffuse_HistoryFix.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_HistoryFix.cs.hlsl index b76c063..62ea2bf 100644 --- a/Source/Shaders/REBLUR_Diffuse_HistoryFix.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_HistoryFix.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecular_HistoryFix.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PostBlur.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Diffuse_PostBlur.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PostBlur.cs.hlsl index 7b704eb..e8ac1ea 100644 --- a/Source/Shaders/REBLUR_Diffuse_PostBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PostBlur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecular_PostBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_PreBlur.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PreBlur.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_Diffuse_PreBlur.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PreBlur.cs.hlsl index aad329e..722e461 100644 --- a/Source/Shaders/REBLUR_Diffuse_PreBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PreBlur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecular_PreBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_PreBlurAdvanced.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PreBlurAdvanced.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_Diffuse_PreBlurAdvanced.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PreBlurAdvanced.cs.hlsl index 63842c5..0a78337 100644 --- a/Source/Shaders/REBLUR_Diffuse_PreBlurAdvanced.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_PreBlurAdvanced.cs.hlsl @@ -11,4 +11,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE #define REBLUR_SPATIAL_REUSE -#include "REBLUR_DiffuseSpecular_PreBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_SplitScreen.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_SplitScreen.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Diffuse_SplitScreen.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_SplitScreen.cs.hlsl index e90155d..f07163d 100644 --- a/Source/Shaders/REBLUR_Diffuse_SplitScreen.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_SplitScreen.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecular_SplitScreen.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalAccumulation.cs.hlsl similarity index 84% rename from Source/Shaders/REBLUR_Diffuse_TemporalAccumulation.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalAccumulation.cs.hlsl index 2893f65..ab75404 100644 --- a/Source/Shaders/REBLUR_Diffuse_TemporalAccumulation.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalAccumulation.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl index 433d72b..14eae26 100644 --- a/Source/Shaders/REBLUR_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl @@ -11,4 +11,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE #define REBLUR_PROVIDED_CONFIDENCE -#include "REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse_TemporalStabilization.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalStabilization.cs.hlsl similarity index 83% rename from Source/Shaders/REBLUR_Diffuse_TemporalStabilization.cs.hlsl rename to Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalStabilization.cs.hlsl index 0a29dd5..f64c8e1 100644 --- a/Source/Shaders/REBLUR_Diffuse_TemporalStabilization.cs.hlsl +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Diffuse_TemporalStabilization.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_AntiFirefly.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_AntiFirefly.cs.hlsl new file mode 100644 index 0000000..6decceb --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_AntiFirefly.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_Blur.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_Blur.cs.hlsl new file mode 100644 index 0000000..cd378e8 --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_Blur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_HistoryFix.cs.hlsl new file mode 100644 index 0000000..c963357 --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_HistoryFix.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PostBlur.cs.hlsl new file mode 100644 index 0000000..237a460 --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PostBlur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PreBlur.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PreBlur.cs.hlsl new file mode 100644 index 0000000..c2865a1 --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PreBlur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PreBlurAdvanced.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PreBlurAdvanced.cs.hlsl new file mode 100644 index 0000000..915db6d --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_PreBlurAdvanced.cs.hlsl @@ -0,0 +1,15 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE +#define REBLUR_SPATIAL_REUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalAccumulation.cs.hlsl new file mode 100644 index 0000000..89ffee0 --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalAccumulation.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl new file mode 100644 index 0000000..2896bf9 --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalAccumulationWithConfidence.cs.hlsl @@ -0,0 +1,15 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE +#define REBLUR_PROVIDED_CONFIDENCE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalStabilization.cs.hlsl b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalStabilization.cs.hlsl new file mode 100644 index 0000000..5285d69 --- /dev/null +++ b/Source/Shaders/REBLUR_Diffuse/REBLUR_Perf_Diffuse_TemporalStabilization.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion_Blur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_Blur.cs.hlsl similarity index 83% rename from Source/Shaders/REBLUR_DiffuseOcclusion_Blur.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_Blur.cs.hlsl index 4533610..4fb9174 100644 --- a/Source/Shaders/REBLUR_DiffuseOcclusion_Blur.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_Blur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_HistoryFix.cs.hlsl similarity index 82% rename from Source/Shaders/REBLUR_DiffuseOcclusion_HistoryFix.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_HistoryFix.cs.hlsl index edef536..0838c4f 100644 --- a/Source/Shaders/REBLUR_DiffuseOcclusion_HistoryFix.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_HistoryFix.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_PostBlur.cs.hlsl similarity index 83% rename from Source/Shaders/REBLUR_DiffuseOcclusion_PostBlur.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_PostBlur.cs.hlsl index 774cdc3..a5c09a2 100644 --- a/Source/Shaders/REBLUR_DiffuseOcclusion_PostBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_PostBlur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion_SplitScreen.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_SplitScreen.cs.hlsl similarity index 82% rename from Source/Shaders/REBLUR_DiffuseOcclusion_SplitScreen.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_SplitScreen.cs.hlsl index 072ad26..6204541 100644 --- a/Source/Shaders/REBLUR_DiffuseOcclusion_SplitScreen.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_SplitScreen.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_TemporalAccumulation.cs.hlsl similarity index 81% rename from Source/Shaders/REBLUR_DiffuseOcclusion_TemporalAccumulation.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_TemporalAccumulation.cs.hlsl index 2c92339..1036ca0 100644 --- a/Source/Shaders/REBLUR_DiffuseOcclusion_TemporalAccumulation.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_TemporalAccumulation.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE -#include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl similarity index 82% rename from Source/Shaders/REBLUR_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl index 8e8fd95..1f89a57 100644 --- a/Source/Shaders/REBLUR_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl @@ -11,4 +11,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_DIFFUSE #define REBLUR_PROVIDED_CONFIDENCE -#include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_Blur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_Blur.cs.hlsl new file mode 100644 index 0000000..06b4579 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_Blur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_HistoryFix.cs.hlsl new file mode 100644 index 0000000..076dff3 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_HistoryFix.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_PostBlur.cs.hlsl new file mode 100644 index 0000000..4146fcd --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_PostBlur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_TemporalAccumulation.cs.hlsl new file mode 100644 index 0000000..b583a89 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_TemporalAccumulation.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl new file mode 100644 index 0000000..cd20143 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseOcclusion/REBLUR_Perf_DiffuseOcclusion_TemporalAccumulationWithConfidence.cs.hlsl @@ -0,0 +1,15 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_DIFFUSE +#define REBLUR_PROVIDED_CONFIDENCE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_AntiFirefly.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.cs.hlsl similarity index 84% rename from Source/Shaders/REBLUR_DiffuseSpecular_AntiFirefly.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.cs.hlsl index 889d81f..b93bdc5 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_AntiFirefly.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecular_AntiFirefly.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_Blur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_DiffuseSpecular_Blur.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.cs.hlsl index d94c3d6..7c3b3b8 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_Blur.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecular_Blur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.cs.hlsl similarity index 84% rename from Source/Shaders/REBLUR_DiffuseSpecular_HistoryFix.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.cs.hlsl index b4a62f9..f877127 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_HistoryFix.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecular_HistoryFix.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_DiffuseSpecular_PostBlur.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.cs.hlsl index 0246c62..e91dd1a 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_PostBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecular_PostBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_PreBlur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_DiffuseSpecular_PreBlur.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.cs.hlsl index a54e747..a3306ba 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_PreBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecular_PreBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_PreBlurAdvanced.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlurAdvanced.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_DiffuseSpecular_PreBlurAdvanced.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlurAdvanced.cs.hlsl index 6c9c27b..3e2761c 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_PreBlurAdvanced.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlurAdvanced.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPATIAL_REUSE -#include "REBLUR_DiffuseSpecular_PreBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_SplitScreen.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.cs.hlsl similarity index 84% rename from Source/Shaders/REBLUR_DiffuseSpecular_SplitScreen.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.cs.hlsl index fe333c2..b64aa56 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_SplitScreen.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecular_SplitScreen.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.cs.hlsl similarity index 83% rename from Source/Shaders/REBLUR_DiffuseSpecular_TemporalAccumulation.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.cs.hlsl index 2473c47..63ebc88 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_TemporalAccumulation.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl similarity index 84% rename from Source/Shaders/REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl index b4eee70..e6b1dac 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_PROVIDED_CONFIDENCE -#include "REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular_TemporalStabilization.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.cs.hlsl similarity index 83% rename from Source/Shaders/REBLUR_DiffuseSpecular_TemporalStabilization.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.cs.hlsl index a17a2f2..f7f0881 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecular_TemporalStabilization.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_AntiFirefly.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_AntiFirefly.cs.hlsl new file mode 100644 index 0000000..4e3687c --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_AntiFirefly.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_Blur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_Blur.cs.hlsl new file mode 100644 index 0000000..3e7f153 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_Blur.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_HistoryFix.cs.hlsl new file mode 100644 index 0000000..bdd37fe --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_HistoryFix.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PostBlur.cs.hlsl new file mode 100644 index 0000000..4c25112 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PostBlur.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PreBlur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PreBlur.cs.hlsl new file mode 100644 index 0000000..a269fd8 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PreBlur.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PreBlurAdvanced.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PreBlurAdvanced.cs.hlsl new file mode 100644 index 0000000..e40c6a7 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_PreBlurAdvanced.cs.hlsl @@ -0,0 +1,15 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_SPATIAL_REUSE + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalAccumulation.cs.hlsl new file mode 100644 index 0000000..f61c637 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalAccumulation.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl new file mode 100644 index 0000000..55f7f67 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalAccumulationWithConfidence.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_PROVIDED_CONFIDENCE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalStabilization.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalStabilization.cs.hlsl new file mode 100644 index 0000000..cdfdc52 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecular/REBLUR_Perf_DiffuseSpecular_TemporalStabilization.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_Blur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.cs.hlsl similarity index 82% rename from Source/Shaders/REBLUR_DiffuseSpecularOcclusion_Blur.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.cs.hlsl index 22eecf2..7ca9e9c 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_Blur.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl similarity index 81% rename from Source/Shaders/REBLUR_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl index b917400..3b9c5bd 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.cs.hlsl similarity index 82% rename from Source/Shaders/REBLUR_DiffuseSpecularOcclusion_PostBlur.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.cs.hlsl index 66f0a48..f418fc3 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_PostBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.hlsl similarity index 81% rename from Source/Shaders/REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.hlsl index 124c070..5e0b0db 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl similarity index 80% rename from Source/Shaders/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl index bdece5f..49f95be 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl similarity index 81% rename from Source/Shaders/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl rename to Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl index 982aa52..5cd278e 100644 --- a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_PROVIDED_CONFIDENCE -#include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_Blur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_Blur.cs.hlsl new file mode 100644 index 0000000..0e12842 --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_Blur.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl new file mode 100644 index 0000000..ba9cefd --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_HistoryFix.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_PostBlur.cs.hlsl new file mode 100644 index 0000000..60cad5d --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_PostBlur.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl new file mode 100644 index 0000000..3ab064d --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulation.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl new file mode 100644 index 0000000..05c695b --- /dev/null +++ b/Source/Shaders/REBLUR_DiffuseSpecularOcclusion/REBLUR_Perf_DiffuseSpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_PROVIDED_CONFIDENCE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_AntiFirefly.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_AntiFirefly.cs.hlsl new file mode 100644 index 0000000..3654899 --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_AntiFirefly.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_Blur.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_Blur.cs.hlsl new file mode 100644 index 0000000..af4307f --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_Blur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_HistoryFix.cs.hlsl new file mode 100644 index 0000000..a68221f --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_HistoryFix.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PostBlur.cs.hlsl new file mode 100644 index 0000000..188cf92 --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PostBlur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PreBlur.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PreBlur.cs.hlsl new file mode 100644 index 0000000..1ac8eb9 --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PreBlur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PreBlurAdvanced.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PreBlurAdvanced.cs.hlsl new file mode 100644 index 0000000..0237ad4 --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_PreBlurAdvanced.cs.hlsl @@ -0,0 +1,15 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR +#define REBLUR_SPATIAL_REUSE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalAccumulation.cs.hlsl new file mode 100644 index 0000000..988f6af --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalAccumulation.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalAccumulationWithConfidence.cs.hlsl new file mode 100644 index 0000000..ed733e6 --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalAccumulationWithConfidence.cs.hlsl @@ -0,0 +1,15 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR +#define REBLUR_PROVIDED_CONFIDENCE + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalStabilization.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalStabilization.cs.hlsl new file mode 100644 index 0000000..dc99e3b --- /dev/null +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Perf_Specular_TemporalStabilization.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_AntiFirefly.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_AntiFirefly.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Specular_AntiFirefly.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_AntiFirefly.cs.hlsl index 70f507a..a20e2c4 100644 --- a/Source/Shaders/REBLUR_Specular_AntiFirefly.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_AntiFirefly.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecular_AntiFirefly.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_AntiFirefly.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_Blur.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_Blur.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_Specular_Blur.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_Blur.cs.hlsl index 594a0bc..4510b97 100644 --- a/Source/Shaders/REBLUR_Specular_Blur.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_Blur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecular_Blur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_HistoryFix.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Specular_HistoryFix.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_HistoryFix.cs.hlsl index 6c001fd..e48f17e 100644 --- a/Source/Shaders/REBLUR_Specular_HistoryFix.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_HistoryFix.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecular_HistoryFix.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_PostBlur.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_Specular_PostBlur.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_PostBlur.cs.hlsl index 5af8e91..7c8d72b 100644 --- a/Source/Shaders/REBLUR_Specular_PostBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_PostBlur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecular_PostBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_PreBlur.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_PreBlur.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_Specular_PreBlur.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_PreBlur.cs.hlsl index a8a23dc..883da25 100644 --- a/Source/Shaders/REBLUR_Specular_PreBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_PreBlur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecular_PreBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_PreBlurAdvanced.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_PreBlurAdvanced.cs.hlsl similarity index 86% rename from Source/Shaders/REBLUR_Specular_PreBlurAdvanced.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_PreBlurAdvanced.cs.hlsl index 09f5338..55e7644 100644 --- a/Source/Shaders/REBLUR_Specular_PreBlurAdvanced.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_PreBlurAdvanced.cs.hlsl @@ -11,4 +11,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR #define REBLUR_SPATIAL_REUSE -#include "REBLUR_DiffuseSpecular_PreBlur.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_PreBlur.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_SplitScreen.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_SplitScreen.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Specular_SplitScreen.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_SplitScreen.cs.hlsl index 1cd6590..ddd5817 100644 --- a/Source/Shaders/REBLUR_Specular_SplitScreen.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_SplitScreen.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecular_SplitScreen.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_SplitScreen.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalAccumulation.cs.hlsl similarity index 84% rename from Source/Shaders/REBLUR_Specular_TemporalAccumulation.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalAccumulation.cs.hlsl index d05d212..0268273 100644 --- a/Source/Shaders/REBLUR_Specular_TemporalAccumulation.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalAccumulation.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalAccumulationWithConfidence.cs.hlsl similarity index 85% rename from Source/Shaders/REBLUR_Specular_TemporalAccumulationWithConfidence.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalAccumulationWithConfidence.cs.hlsl index 864717e..cbb8e64 100644 --- a/Source/Shaders/REBLUR_Specular_TemporalAccumulationWithConfidence.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalAccumulationWithConfidence.cs.hlsl @@ -11,4 +11,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR #define REBLUR_PROVIDED_CONFIDENCE -#include "REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_Specular_TemporalStabilization.cs.hlsl b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalStabilization.cs.hlsl similarity index 83% rename from Source/Shaders/REBLUR_Specular_TemporalStabilization.cs.hlsl rename to Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalStabilization.cs.hlsl index b922aa0..661a3c6 100644 --- a/Source/Shaders/REBLUR_Specular_TemporalStabilization.cs.hlsl +++ b/Source/Shaders/REBLUR_Specular/REBLUR_Specular_TemporalStabilization.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" +#include "REBLUR_DiffuseSpecular/REBLUR_DiffuseSpecular_TemporalStabilization.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_Blur.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_Blur.cs.hlsl new file mode 100644 index 0000000..d6c39ae --- /dev/null +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_Blur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_HistoryFix.cs.hlsl new file mode 100644 index 0000000..f070954 --- /dev/null +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_HistoryFix.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_PostBlur.cs.hlsl new file mode 100644 index 0000000..0a27c83 --- /dev/null +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_PostBlur.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_TemporalAccumulation.cs.hlsl new file mode 100644 index 0000000..049a067 --- /dev/null +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_TemporalAccumulation.cs.hlsl @@ -0,0 +1,14 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl new file mode 100644 index 0000000..7b02694 --- /dev/null +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_Perf_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl @@ -0,0 +1,15 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define REBLUR_PERFORMANCE_MODE +#define REBLUR_SPECULAR +#define REBLUR_PROVIDED_CONFIDENCE + +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion_Blur.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_Blur.cs.hlsl similarity index 83% rename from Source/Shaders/REBLUR_SpecularOcclusion_Blur.cs.hlsl rename to Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_Blur.cs.hlsl index 32fd7dc..904fd18 100644 --- a/Source/Shaders/REBLUR_SpecularOcclusion_Blur.cs.hlsl +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_Blur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_Blur.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion_HistoryFix.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_HistoryFix.cs.hlsl similarity index 82% rename from Source/Shaders/REBLUR_SpecularOcclusion_HistoryFix.cs.hlsl rename to Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_HistoryFix.cs.hlsl index 86d1ebd..aae056c 100644 --- a/Source/Shaders/REBLUR_SpecularOcclusion_HistoryFix.cs.hlsl +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_HistoryFix.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_HistoryFix.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion_PostBlur.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_PostBlur.cs.hlsl similarity index 83% rename from Source/Shaders/REBLUR_SpecularOcclusion_PostBlur.cs.hlsl rename to Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_PostBlur.cs.hlsl index 0080947..7e78254 100644 --- a/Source/Shaders/REBLUR_SpecularOcclusion_PostBlur.cs.hlsl +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_PostBlur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_PostBlur.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion_SplitScreen.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_SplitScreen.cs.hlsl similarity index 82% rename from Source/Shaders/REBLUR_SpecularOcclusion_SplitScreen.cs.hlsl rename to Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_SplitScreen.cs.hlsl index cc135cb..8ad2462 100644 --- a/Source/Shaders/REBLUR_SpecularOcclusion_SplitScreen.cs.hlsl +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_SplitScreen.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_SplitScreen.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion_TemporalAccumulation.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_TemporalAccumulation.cs.hlsl similarity index 81% rename from Source/Shaders/REBLUR_SpecularOcclusion_TemporalAccumulation.cs.hlsl rename to Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_TemporalAccumulation.cs.hlsl index 4f7ca92..37b4165 100644 --- a/Source/Shaders/REBLUR_SpecularOcclusion_TemporalAccumulation.cs.hlsl +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_TemporalAccumulation.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR -#include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REBLUR_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl similarity index 82% rename from Source/Shaders/REBLUR_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl rename to Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl index b9f9199..1702ec7 100644 --- a/Source/Shaders/REBLUR_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl +++ b/Source/Shaders/REBLUR_SpecularOcclusion/REBLUR_SpecularOcclusion_TemporalAccumulationWithConfidence.cs.hlsl @@ -11,4 +11,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define REBLUR_SPECULAR #define REBLUR_PROVIDED_CONFIDENCE -#include "REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" +#include "REBLUR_DiffuseSpecularOcclusion/REBLUR_DiffuseSpecularOcclusion_TemporalAccumulation.hlsli" diff --git a/Source/Shaders/REFERENCE_Accumulate.cs.hlsl b/Source/Shaders/REFERENCE/REFERENCE_Accumulate.cs.hlsl similarity index 94% rename from Source/Shaders/REFERENCE_Accumulate.cs.hlsl rename to Source/Shaders/REFERENCE/REFERENCE_Accumulate.cs.hlsl index 7be953a..dd7dfa7 100644 --- a/Source/Shaders/REFERENCE_Accumulate.cs.hlsl +++ b/Source/Shaders/REFERENCE/REFERENCE_Accumulate.cs.hlsl @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REFERENCE_Accumulate.resources.hlsli" +#include "REFERENCE\REFERENCE_Accumulate.resources.hlsli" NRD_DECLARE_CONSTANTS diff --git a/Source/Shaders/REFERENCE_SplitScreen.cs.hlsl b/Source/Shaders/REFERENCE/REFERENCE_SplitScreen.cs.hlsl similarity index 92% rename from Source/Shaders/REFERENCE_SplitScreen.cs.hlsl rename to Source/Shaders/REFERENCE/REFERENCE_SplitScreen.cs.hlsl index 0c47be4..984f8cd 100644 --- a/Source/Shaders/REFERENCE_SplitScreen.cs.hlsl +++ b/Source/Shaders/REFERENCE/REFERENCE_SplitScreen.cs.hlsl @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "REFERENCE_SplitScreen.resources.hlsli" +#include "REFERENCE\REFERENCE_SplitScreen.resources.hlsli" NRD_DECLARE_CONSTANTS diff --git a/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_ATrousShmem.cs.hlsl b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_ATrousShmem.cs.hlsl new file mode 100644 index 0000000..00282b0 --- /dev/null +++ b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_ATrousShmem.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_DIFFUSE + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.hlsli" diff --git a/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_ATrousStandard.cs.hlsl b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_ATrousStandard.cs.hlsl new file mode 100644 index 0000000..2d1347f --- /dev/null +++ b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_ATrousStandard.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_DIFFUSE + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.hlsli" diff --git a/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_DisocclusionFix.cs.hlsl b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_DisocclusionFix.cs.hlsl new file mode 100644 index 0000000..a7867cc --- /dev/null +++ b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_DisocclusionFix.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_DIFFUSE + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.hlsli" diff --git a/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Firefly.cs.hlsl b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Firefly.cs.hlsl new file mode 100644 index 0000000..e287716 --- /dev/null +++ b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Firefly.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_DIFFUSE + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.hlsli" diff --git a/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_HistoryClamping.cs.hlsl b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_HistoryClamping.cs.hlsl new file mode 100644 index 0000000..9ee7fdb --- /dev/null +++ b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_HistoryClamping.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_DIFFUSE + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.hlsli" diff --git a/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Prepass.cs.hlsl b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Prepass.cs.hlsl new file mode 100644 index 0000000..d1a2f52 --- /dev/null +++ b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Prepass.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_DIFFUSE + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.hlsli" \ No newline at end of file diff --git a/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Reproject.cs.hlsl b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Reproject.cs.hlsl new file mode 100644 index 0000000..0d71697 --- /dev/null +++ b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_Reproject.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_DIFFUSE + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.hlsli" diff --git a/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_SplitScreen.cs.hlsl b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_SplitScreen.cs.hlsl new file mode 100644 index 0000000..ce8037d --- /dev/null +++ b/Source/Shaders/RELAX_Diffuse/RELAX_Diffuse_SplitScreen.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_DIFFUSE + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.hlsli" diff --git a/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.cs.hlsl new file mode 100644 index 0000000..ca94b05 --- /dev/null +++ b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.cs.hlsl @@ -0,0 +1,11 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.hlsli" diff --git a/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.cs.hlsl new file mode 100644 index 0000000..790fc25 --- /dev/null +++ b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.cs.hlsl @@ -0,0 +1,12 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.hlsli" + diff --git a/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.cs.hlsl new file mode 100644 index 0000000..3e9463c --- /dev/null +++ b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.cs.hlsl @@ -0,0 +1,11 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.hlsli" diff --git a/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.cs.hlsl new file mode 100644 index 0000000..4ef933f --- /dev/null +++ b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.cs.hlsl @@ -0,0 +1,11 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.hlsli" diff --git a/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.cs.hlsl new file mode 100644 index 0000000..95224d2 --- /dev/null +++ b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.cs.hlsl @@ -0,0 +1,11 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.hlsli" diff --git a/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.cs.hlsl new file mode 100644 index 0000000..e3650b0 --- /dev/null +++ b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.cs.hlsl @@ -0,0 +1,11 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.hlsli" diff --git a/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.cs.hlsl new file mode 100644 index 0000000..d59f7e1 --- /dev/null +++ b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.cs.hlsl @@ -0,0 +1,11 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.hlsli" diff --git a/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.cs.hlsl new file mode 100644 index 0000000..e0926f2 --- /dev/null +++ b/Source/Shaders/RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.cs.hlsl @@ -0,0 +1,11 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.hlsli" diff --git a/Source/Shaders/RELAX_DiffuseSpecular_ATrousShmem.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular_ATrousShmem.cs.hlsl deleted file mode 100644 index 0b3104a..0000000 --- a/Source/Shaders/RELAX_DiffuseSpecular_ATrousShmem.cs.hlsl +++ /dev/null @@ -1,313 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_DiffuseSpecular_ATrousShmem.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 8 -#define SKIRT 1 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedDiffuseIlluminationAndVariance[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedSpecularIlluminationAndVariance[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalRoughness[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedWorldPos[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING -groupshared uint sharedMaterialType[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -#endif - -// Helper functions -float2 getRoughnessWeightParams(float roughness0, float specularReprojectionConfidence) -{ - float a = 1.0 / (0.001 + 0.999 * roughness0 * (0.333 + gRoughnessEdgeStoppingRelaxation * (1.0 - specularReprojectionConfidence))); - float b = roughness0 * a; - return float2(a, b); -} - -float getRoughnessWeight(float2 params0, float roughness) -{ - return saturate(1.0 - abs(params0.y - roughness * params0.x)); -} - -// computes a 3x3 gaussian blur of the variance, centered around -// the current pixel -void computeVariance(int2 groupThreadId, out float specularVariance, out float diffuseVariance) -{ - float specularSum = 0; - float diffuseSum = 0; - - static const float kernel[2][2] = - { - { 1.0 / 4.0, 1.0 / 8.0 }, - { 1.0 / 8.0, 1.0 / 16.0 } - }; - - const int radius = 1; - for (int yy = -radius; yy <= radius; yy++) - { - for (int xx = -radius; xx <= radius; xx++) - { - int2 sharedMemoryIndex = groupThreadId.xy + int2(1 + xx, 1 + yy); - float4 specularIlluminationAndVariance = sharedSpecularIlluminationAndVariance[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float4 diffuseIlluminationAndVariance = sharedDiffuseIlluminationAndVariance[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float k = kernel[abs(xx)][abs(yy)]; - specularSum += specularIlluminationAndVariance.a * k; - diffuseSum += diffuseIlluminationAndVariance.a * k; - } - } - specularVariance = specularSum; - diffuseVariance = diffuseSum; -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory - // - // Renumerating threads to load 18x18 (16+2 x 16+2) block of data to shared memory - // - // The preloading will be done in two stages: - // at the first stage the group will load 16x16 / 18 = 14.2 rows of the shared memory, - // and all threads in the group will be following the same path. - // At the second stage, the rest 18x18 - 16x16 = 68 threads = 2.125 warps will load the rest of data - - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - int ox = newIdxX; - int oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 specularIlluminationAndVariance = 0; - float4 diffuseIlluminationAndVariance = 0; - float3 normal = 0; - float roughness = 1.0; - float4 worldPos = 0; - float viewZ = 0.0; - uint materialType = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gResourceSize.x) && (yy < (int)gResourceSize.y)) - { - specularIlluminationAndVariance = gSpecularIlluminationAndVariance[int2(xx, yy)]; - diffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[int2(xx, yy)]; - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)], materialType); - normal = normalRoughness.rgb; - roughness = normalRoughness.a; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - worldPos = float4(GetCurrentWorldPos(int2(xx,yy), viewZ), viewZ); - } - sharedSpecularIlluminationAndVariance[oy][ox] = specularIlluminationAndVariance; - sharedDiffuseIlluminationAndVariance[oy][ox] = diffuseIlluminationAndVariance; - sharedNormalRoughness[oy][ox] = float4(normal, roughness); - sharedWorldPos[oy][ox] = worldPos; -#if (NRD_USE_MATERIAL_ID_AWARE_FILTERING == 1) - sharedMaterialType[oy][ox] = materialType; -#endif - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - specularIlluminationAndVariance = 0; - diffuseIlluminationAndVariance = 0; - normal = 0; - roughness = 1.0; - worldPos = 0; - viewZ = 0.0; - materialType = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gResourceSize.x) && (yy < (int)gResourceSize.y)) - { - specularIlluminationAndVariance = gSpecularIlluminationAndVariance[int2(xx, yy)]; - diffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[int2(xx, yy)]; - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)], materialType); - normal = normalRoughness.rgb; - roughness = normalRoughness.a; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - worldPos = float4(GetCurrentWorldPos(int2(xx, yy), viewZ), viewZ); - } - sharedSpecularIlluminationAndVariance[oy][ox] = specularIlluminationAndVariance; - sharedDiffuseIlluminationAndVariance[oy][ox] = diffuseIlluminationAndVariance; - sharedNormalRoughness[oy][ox] = float4(normal, roughness); - sharedWorldPos[oy][ox] = worldPos; -#if (NRD_USE_MATERIAL_ID_AWARE_FILTERING == 1) - sharedMaterialType[oy][ox] = materialType; -#endif - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // - // Shared memory is populated now and can be used for filtering - // - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - // Fetching center data - float4 centerWorldPosAndViewZ = sharedWorldPos[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float3 centerWorldPos = centerWorldPosAndViewZ.xyz; - float centerViewZ = centerWorldPosAndViewZ.w; - float3 centerV = normalize(centerWorldPos); - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float3 centerNormal = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; - float specularReprojectionConfidence = gSpecularReprojectionConfidence[ipos]; - - float4 centerSpecularIlluminationAndVariance = sharedSpecularIlluminationAndVariance[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float4 centerDiffuseIlluminationAndVariance = sharedDiffuseIlluminationAndVariance[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - - // Calculating center luminance - float centerSpecularLuminance = STL::Color::Luminance(centerSpecularIlluminationAndVariance.rgb); - float centerDiffuseLuminance = STL::Color::Luminance(centerDiffuseIlluminationAndVariance.rgb); - - // Center roughness - float centerRoughness = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x].a; - float2 roughnessWeightParams = getRoughnessWeightParams(centerRoughness, specularReprojectionConfidence); - - float2 normalWeightParams = GetNormalWeightParams_ATrous(centerRoughness, 255.0*gHistoryLength[ipos].y, specularReprojectionConfidence, gNormalEdgeStoppingRelaxation, gSpecularLobeAngleFraction); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - uint centerMaterialType = sharedMaterialType[sharedMemoryIndex.y][sharedMemoryIndex.x]; -#endif - - // Calculating variance, filtered using 3x3 gaussin blur - float centerSpecularVar; - float centerDiffuseVar; - computeVariance(groupThreadId.xy, centerSpecularVar, centerDiffuseVar); - - float specularPhiLIllumination = 1.0e-4 + gSpecularPhiLuminance * sqrt(max(0.0, centerSpecularVar)); - float diffusePhiLIllumination = 1.0e-4 + gDiffusePhiLuminance * sqrt(max(0.0, centerDiffuseVar)); - float depthThreshold = gDepthThreshold; - - float sumWSpecular = 0; - float4 sumSpecularIlluminationAndVariance = 0; - - float sumWDiffuse = 0; - float4 sumDiffuseIlluminationAndVariance = 0; - - static const float kernelWeightGaussian3x3[2] = { 0.44198, 0.27901 }; - - [unroll] - for (int cy = -1; cy <= 1; cy++) - { - [unroll] - for (int cx = -1; cx <= 1; cx++) - { - const float kernel = kernelWeightGaussian3x3[abs(cx)] * kernelWeightGaussian3x3[abs(cy)]; - const int2 p = ipos + int2(cx, cy); - const bool isInside = all(p >= int2(0, 0)) && all(p < int2(gResourceSize)); - const bool isCenter = ((cx == 0) && (cy == 0)); - - int2 sampleSharedMemoryIndex = groupThreadId.xy + int2(SKIRT + cx, SKIRT + cy); - - float4 sampleNormalRoughness = sharedNormalRoughness[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; - float3 sampleNormal = sampleNormalRoughness.rgb; - float sampleRoughness = sampleNormalRoughness.a; - float3 sampleWorldPos = sharedWorldPos[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x].rgb; - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - uint sampleMaterialType = sharedMaterialType[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; -#endif - - float4 sampleSpecularIlluminationAndVariance = sharedSpecularIlluminationAndVariance[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; - float4 sampleDiffuseIlluminationAndVariance = sharedDiffuseIlluminationAndVariance[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; - - float sampleSpecularLuminance = STL::Color::Luminance(sampleSpecularIlluminationAndVariance.rgb); - float sampleDiffuseLuminance = STL::Color::Luminance(sampleDiffuseIlluminationAndVariance.rgb); - - // Calculating geometry and normal weights - float geometryW = GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - depthThreshold); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - geometryW *= (sampleMaterialType == centerMaterialType) ? 1.0 : 0.0; -#endif - - float normalWSpecular = GetSpecularNormalWeight_ATrous(normalWeightParams, gSpecularLobeAngleSlack, centerNormal, sampleNormal); - float normalWDiffuse = GetDiffuseNormalWeight_ATrous(centerNormal, sampleNormal, gPhiNormal); - - // Calculating luminande weigths - float specularLuminanceW = abs(centerSpecularLuminance - sampleSpecularLuminance) / specularPhiLIllumination; - float relaxation = lerp(1.0, specularReprojectionConfidence, gLuminanceEdgeStoppingRelaxation); - specularLuminanceW *= relaxation; - specularLuminanceW = min(gMaxLuminanceRelativeDifference, specularLuminanceW); - - float diffuseLuminanceW = abs(centerDiffuseLuminance - sampleDiffuseLuminance) / diffusePhiLIllumination; - diffuseLuminanceW = min(gMaxLuminanceRelativeDifference, diffuseLuminanceW); - - // Roughness weight for specular - float specularRoughnessW = getRoughnessWeight(roughnessWeightParams, sampleRoughness); - - float wSpecular = kernel; - float wDiffuse = kernel; - if (!isCenter) - { - // Calculating bilateral weight for specular - wSpecular = geometryW * exp_approx(-specularLuminanceW); - wSpecular *= gRoughnessEdgeStoppingEnabled ? (normalWSpecular * specularRoughnessW) : normalWDiffuse; - wSpecular = kernel * max(1e-6, wSpecular); - - // Calculating bilateral weight for diffuse - wDiffuse = geometryW * kernel * max(1e-6, normalWDiffuse * exp_approx(-diffuseLuminanceW)); - } - - // Discarding out of screen samples - wSpecular *= isInside ? 1.0 : 0.0; - wDiffuse *= isInside ? 1.0 : 0.0; - - // alpha channel contains the variance, therefore the weights need to be squared - sumWSpecular += wSpecular; - sumSpecularIlluminationAndVariance += float4(wSpecular.xxx, wSpecular * wSpecular) * sampleSpecularIlluminationAndVariance; - - sumWDiffuse += wDiffuse; - sumDiffuseIlluminationAndVariance += float4(wDiffuse.xxx, wDiffuse * wDiffuse) * sampleDiffuseIlluminationAndVariance; - } - } - - float4 filteredSpecularIlluminationAndVariance = float4(sumSpecularIlluminationAndVariance / float4(sumWSpecular.xxx, sumWSpecular * sumWSpecular)); - float4 filteredDiffuseIlluminationAndVariance = float4(sumDiffuseIlluminationAndVariance / float4(sumWDiffuse.xxx, sumWDiffuse * sumWDiffuse)); - - gOutSpecularIlluminationAndVariance[ipos] = filteredSpecularIlluminationAndVariance; - gOutDiffuseIlluminationAndVariance[ipos] = filteredDiffuseIlluminationAndVariance; -} diff --git a/Source/Shaders/RELAX_DiffuseSpecular_Firefly.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular_Firefly.cs.hlsl deleted file mode 100644 index fde3f36..0000000 --- a/Source/Shaders/RELAX_DiffuseSpecular_Firefly.cs.hlsl +++ /dev/null @@ -1,241 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_DiffuseSpecular_Firefly.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 1 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedDiffuseIllumination[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedSpecularIllumination[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalAndViewZ[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -// Helper functions - -float edgeStoppingDepth(float centerViewZ, float sampleViewZ) -{ - return (abs(centerViewZ - sampleViewZ) / (centerViewZ + 1e-6)) < 0.1 ? 1.0 : 0.0; -} - -void PopulateSharedMemoryForFirefly(uint2 dispatchThreadId, uint2 groupThreadId, uint2 groupId) -{ - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 specularIllumination = 0; - float4 diffuseIllumination = 0; - float3 normal = 0; - float viewZ = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specularIllumination = gSpecularIllumination[int2(xx, yy)]; - diffuseIllumination = gDiffuseIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx,yy)]).rgb; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedSpecularIllumination[oy][ox] = specularIllumination; - sharedDiffuseIllumination[oy][ox] = diffuseIllumination; - sharedNormalAndViewZ[oy][ox] = float4(normal, viewZ); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - specularIllumination = 0; - diffuseIllumination = 0; - normal = 0; - viewZ = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specularIllumination = gSpecularIllumination[int2(xx, yy)]; - diffuseIllumination = gDiffuseIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedSpecularIllumination[oy][ox] = specularIllumination; - sharedDiffuseIllumination[oy][ox] = diffuseIllumination; - sharedNormalAndViewZ[oy][ox] = float4(normal, viewZ); - } -} - -// Cross bilateral Rank-Conditioned Rank-Selection (RCRS) filter -void runRCRS(int2 dispatchThreadId, int2 groupThreadId, float3 centerNormal, float centerViewZ, out float4 outSpecular, out float4 outDiffuse) -{ - // Fetching center data - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - float4 s = sharedSpecularIllumination[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float4 d = sharedDiffuseIllumination[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - float3 specularIlluminationCenter = s.rgb; - float3 diffuseIlluminationCenter = d.rgb; - float specular2ndMomentCenter = s.a; - float diffuse2ndMomentCenter = d.a; - - float specularLuminanceCenter = STL::Color::Luminance(specularIlluminationCenter); - float diffuseLuminanceCenter = STL::Color::Luminance(diffuseIlluminationCenter); - - // Finding max and min luminance in neighborhood, rejecting samples that don't belong to center pixel's surface - float maxSpecularLuminance = -1.0; - float minSpecularLuminance = 1.0e6; - int2 maxSpecularLuminanceCoords = sharedMemoryIndex; - int2 minSpecularLuminanceCoords = sharedMemoryIndex; - - float maxDiffuseLuminance = -1.0; - float minDiffuseLuminance = 1.0e6; - int2 maxDiffuseLuminanceCoords = sharedMemoryIndex; - int2 minDiffuseLuminanceCoords = sharedMemoryIndex; - - [unroll] - for (int yy = -1; yy <= 1; yy++) - { - [unroll] - for (int xx = -1; xx <= 1; xx++) - { - int2 p = dispatchThreadId.xy + int2(xx, yy); - int2 sharedMemoryIndexSample = groupThreadId.xy + int2(SKIRT, SKIRT) + int2(xx,yy); - - if ((xx == 0) && (yy == 0)) continue; - if (any(p < int2(0, 0)) || any(p >= (int2)gRectSize)) continue; - - // Fetching sample data - float4 v = sharedNormalAndViewZ[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x]; - float3 sampleNormal = v.xyz; - float sampleViewZ = v.w; - - float3 specularIlluminationSample = sharedSpecularIllumination[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x].rgb; - float3 diffuseIlluminationSample = sharedDiffuseIllumination[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x].rgb; - - float specularLuminanceSample = STL::Color::Luminance(specularIlluminationSample); - float diffuseLuminanceSample = STL::Color::Luminance(diffuseIlluminationSample); - - // Applying weights - // ..normal weight - float weight = dot(centerNormal, sampleNormal) > 0.99 ? 1.0 : 0.0; - - // ..depth weight - weight *= edgeStoppingDepth(centerViewZ, sampleViewZ); - - if(weight > 0) - { - if(specularLuminanceSample > maxSpecularLuminance) - { - maxSpecularLuminance = specularLuminanceSample; - maxSpecularLuminanceCoords = sharedMemoryIndexSample; - } - if(specularLuminanceSample < minSpecularLuminance) - { - minSpecularLuminance = specularLuminanceSample; - minSpecularLuminanceCoords = sharedMemoryIndexSample; - } - - if(diffuseLuminanceSample > maxDiffuseLuminance) - { - maxDiffuseLuminance = diffuseLuminanceSample; - maxDiffuseLuminanceCoords = sharedMemoryIndexSample; - } - if(diffuseLuminanceSample < minDiffuseLuminance) - { - minDiffuseLuminance = diffuseLuminanceSample; - minDiffuseLuminanceCoords = sharedMemoryIndexSample; - } - - } - } - } - - // Replacing current value with min or max in the neighborhood if outside min..max range, - // or leaving sample as it is if it's within the range - int2 specularCoords = sharedMemoryIndex; - int2 diffuseCoords = sharedMemoryIndex; - - if(specularLuminanceCenter > maxSpecularLuminance) - { - specularCoords = maxSpecularLuminanceCoords; - } - if(specularLuminanceCenter < minSpecularLuminance) - { - specularCoords = minSpecularLuminanceCoords; - } - - if(diffuseLuminanceCenter > maxDiffuseLuminance) - { - diffuseCoords = maxDiffuseLuminanceCoords; - } - if(diffuseLuminanceCenter < minDiffuseLuminance) - { - diffuseCoords = minDiffuseLuminanceCoords; - } - outSpecular = float4(sharedSpecularIllumination[specularCoords.y][specularCoords.x].rgb, specular2ndMomentCenter); - outDiffuse = float4(sharedDiffuseIllumination[diffuseCoords.y][diffuseCoords.x].rgb, diffuse2ndMomentCenter); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory for firefly filter - PopulateSharedMemoryForFirefly(dispatchThreadId.xy, groupThreadId.xy, groupId.xy); - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // Shared memory is populated now and can be used for filtering - float4 v = sharedNormalAndViewZ[groupThreadId.y + SKIRT][groupThreadId.x + SKIRT]; - float3 centerNormal = v.xyz; - float centerViewZ = v.w; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - // Running firefly filter - float4 outSpecularIlluminationAnd2ndMoment; - float4 outDiffuseIlluminationAnd2ndMoment; - - runRCRS(dispatchThreadId.xy, groupThreadId.xy, centerNormal, centerViewZ, outSpecularIlluminationAnd2ndMoment, outDiffuseIlluminationAnd2ndMoment); - - gOutSpecularIllumination[dispatchThreadId.xy] = outSpecularIlluminationAnd2ndMoment; - gOutDiffuseIllumination[dispatchThreadId.xy] = outDiffuseIlluminationAnd2ndMoment; -} - diff --git a/Source/Shaders/RELAX_DiffuseSpecular_HistoryClamping.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular_HistoryClamping.cs.hlsl deleted file mode 100644 index 99a31c6..0000000 --- a/Source/Shaders/RELAX_DiffuseSpecular_HistoryClamping.cs.hlsl +++ /dev/null @@ -1,186 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_DiffuseSpecular_HistoryClamping.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 2 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared uint3 sharedPackedSpecularDiffuse[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -uint3 pack(float3 specular, float3 diffuse) -{ - uint3 result; - result.r = f32tof16(specular.r) | f32tof16(specular.g) << 16; - result.g = f32tof16(specular.b) | f32tof16(diffuse.r) << 16; - result.b = f32tof16(diffuse.g) | f32tof16(diffuse.b) << 16; - return result; -} - -void unpack(uint3 packedData, out float3 specular, out float3 diffuse) -{ - specular.r = f16tof32(packedData.r); - specular.g = f16tof32(packedData.r >> 16); - specular.b = f16tof32(packedData.g); - diffuse.r = f16tof32(packedData.g >> 16); - diffuse.g = f16tof32(packedData.b); - diffuse.b = f16tof32(packedData.b >> 16); -} - -void runHistoryClamping(int2 pixelPos, int2 sharedMemoryIndex, float3 specular, float3 diffuse, out float3 outSpecular, out float3 outDiffuse) -{ - float3 specularYCoCg = STL::Color::LinearToYCoCg(specular); - float3 diffuseYCoCg = STL::Color::LinearToYCoCg(diffuse); - - float3 specularFirstMoment = 0; - float3 specularSecondMoment = 0; - float3 diffuseFirstMoment = 0; - float3 diffuseSecondMoment = 0; - - [unroll] - for (int dy = -2; dy <= 2; dy++) - { - [unroll] - for (int dx = -2; dx <= 2; dx++) - { - uint2 sharedMemoryIndexP = sharedMemoryIndex + int2(dx, dy); - int2 p = pixelPos + int2(dx, dy); - if (any(p < int2(0,0)) || any(p >= (int2)gRectSize)) sharedMemoryIndexP = sharedMemoryIndex; - - float3 specularP; - float3 diffuseP; - unpack(sharedPackedSpecularDiffuse[sharedMemoryIndexP.y][sharedMemoryIndexP.x], specularP, diffuseP); - - specularFirstMoment += specularP; - specularSecondMoment += specularP * specularP; - - diffuseFirstMoment += diffuseP; - diffuseSecondMoment += diffuseP * diffuseP; - } - } - - specularFirstMoment /= 25.0; - specularSecondMoment /= 25.0; - - diffuseFirstMoment /= 25.0; - diffuseSecondMoment /= 25.0; - - // Calculating color boxes for specular and diffuse signals - float3 specularSigma = sqrt(max(0.0f, specularSecondMoment - specularFirstMoment * specularFirstMoment)); - float3 specularColorMin = specularFirstMoment - gColorBoxSigmaScale * specularSigma; - float3 specularColorMax = specularFirstMoment + gColorBoxSigmaScale * specularSigma; - - float3 diffuseSigma = sqrt(max(0.0f, diffuseSecondMoment - diffuseFirstMoment * diffuseFirstMoment)); - float3 diffuseColorMin = diffuseFirstMoment - gColorBoxSigmaScale * diffuseSigma; - float3 diffuseColorMax = diffuseFirstMoment + gColorBoxSigmaScale * diffuseSigma; - - // Expanding specular and diffuse color boxes with color of the center pixel for specular and diffuse signals - // to avoid introducing bias - float3 specularCenter; - float3 diffuseCenter; - unpack(sharedPackedSpecularDiffuse[sharedMemoryIndex.y][sharedMemoryIndex.x], specularCenter, diffuseCenter); - - specularColorMin = min(specularColorMin, specularCenter); - specularColorMax = max(specularColorMax, specularCenter); - diffuseColorMin = min(diffuseColorMin, diffuseCenter); - diffuseColorMax = max(diffuseColorMax, diffuseCenter); - - // Color clamping - specularYCoCg = clamp(specularYCoCg, specularColorMin, specularColorMax); - outSpecular = STL::Color::YCoCgToLinear(specularYCoCg); - - diffuseYCoCg = clamp(diffuseYCoCg, diffuseColorMin, diffuseColorMax); - outDiffuse = STL::Color::YCoCgToLinear(diffuseYCoCg); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float3 specularResponsive = 0; - float3 diffuseResponsive = 0; - - if (xx >= 0 && yy >= 0 && xx < (int)gRectSize.x && yy < (int)gRectSize.y) - { - specularResponsive = gSpecularIlluminationResponsive[int2(xx, yy)].rgb; - diffuseResponsive = gDiffuseIlluminationResponsive[int2(xx, yy)].rgb; - } - sharedPackedSpecularDiffuse[oy][ox] = pack(STL::Color::LinearToYCoCg(specularResponsive), STL::Color::LinearToYCoCg(diffuseResponsive)); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - specularResponsive = 0; - diffuseResponsive = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if (xx >= 0 && yy >= 0 && xx < (int)gRectSize.x && yy < (int)gRectSize.y) - { - specularResponsive = gSpecularIlluminationResponsive[int2(xx, yy)].rgb; - diffuseResponsive = gDiffuseIlluminationResponsive[int2(xx, yy)].rgb; - } - sharedPackedSpecularDiffuse[oy][ox] = pack(STL::Color::LinearToYCoCg(specularResponsive), STL::Color::LinearToYCoCg(diffuseResponsive)); - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - // Shared memory is populated with responsive history now and can be used for history clamping - - // Reading normal history - float4 specularIlluminationAnd2ndMoment = gSpecularIllumination[dispatchThreadId.xy]; - float4 diffuseIlluminationAnd2ndMoment = gDiffuseIllumination[dispatchThreadId.xy]; - - // Reading history length - float2 historyLength = gSpecularAndDiffuseHistoryLength[dispatchThreadId.xy]; - - // Running history clamping - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - float3 clampedSpecular; - float3 clampedDiffuse; - float2 adjustedHistoryLength; - runHistoryClamping(dispatchThreadId.xy, sharedMemoryIndex, specularIlluminationAnd2ndMoment.rgb, diffuseIlluminationAnd2ndMoment.rgb, clampedSpecular, clampedDiffuse); - - // Writing out the results - gOutSpecularIllumination[dispatchThreadId.xy] =float4(clampedSpecular, specularIlluminationAnd2ndMoment.a); - gOutDiffuseIllumination[dispatchThreadId.xy] = float4(clampedDiffuse, diffuseIlluminationAnd2ndMoment.a); - gOutSpecularAndDiffuseHistoryLength[dispatchThreadId.xy] = historyLength; -} diff --git a/Source/Shaders/RELAX_DiffuseSpecular_SpatialVarianceEstimation.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular_SpatialVarianceEstimation.cs.hlsl deleted file mode 100644 index 92b661e..0000000 --- a/Source/Shaders/RELAX_DiffuseSpecular_SpatialVarianceEstimation.cs.hlsl +++ /dev/null @@ -1,232 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_DiffuseSpecular_SpatialVarianceEstimation.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 2 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedSpecularAnd2ndMoment[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedDiffuseAnd2ndMoment[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalViewZ[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -float computeDepthWeight(float depthCenter, float depthP, float depthThreshold) -{ - return 1; -} - -float computeNormalWeight(float3 normalCenter, float3 normalP, float phiNormal) -{ - return phiNormal == 0.0f ? 1.0f : pow(saturate(dot(normalCenter, normalP)), phiNormal); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - const int2 ipos = dispatchThreadId.xy; - - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - int ox = newIdxX; - int oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 specular = 0; - float4 diffuse = 0; - float3 normal = 0; - float viewZ = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specular = gSpecularIllumination[int2(xx, yy)]; - diffuse = gDiffuseIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZ[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedSpecularAnd2ndMoment[oy][ox] = specular; - sharedDiffuseAnd2ndMoment[oy][ox] = diffuse; - sharedNormalViewZ[oy][ox] = float4(normal, viewZ); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - specular = 0; - diffuse = 0; - normal = 0; - viewZ = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specular = gSpecularIllumination[int2(xx, yy)]; - diffuse = gDiffuseIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZ[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedSpecularAnd2ndMoment[oy][ox] = specular; - sharedDiffuseAnd2ndMoment[oy][ox] = diffuse; - sharedNormalViewZ[oy][ox] = float4(normal, viewZ); - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // - // Shared memory is populated now and can be used for filtering - // - - int2 sharedMemoryCenterIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - // Repacking normal and roughness to prev normal roughness to be used in the next frame - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos]); - gOutNormalRoughness[ipos] = PackPrevNormalRoughness(normalRoughness); - - // Using diffuse history length for spatial variance estimation - float historyLength = 255.0 * gHistoryLength[ipos].y; - - float4 centerSpecularAnd2ndMoment = sharedSpecularAnd2ndMoment[sharedMemoryCenterIndex.y][sharedMemoryCenterIndex.x]; - float4 centerDiffuseAnd2ndMoment = sharedDiffuseAnd2ndMoment[sharedMemoryCenterIndex.y][sharedMemoryCenterIndex.x]; - float3 centerSpecularIllumination = centerSpecularAnd2ndMoment.rgb; - float3 centerDiffuseIllumination = centerDiffuseAnd2ndMoment.rgb; - float centerSpecular1stMoment = STL::Color::Luminance(centerSpecularIllumination); - float centerDiffuse1stMoment = STL::Color::Luminance(centerDiffuseIllumination); - float centerSpecular2ndMoment = centerSpecularAnd2ndMoment.a; - float centerDiffuse2ndMoment = centerDiffuseAnd2ndMoment.a; - - [branch] - if (historyLength >= float(gHistoryThreshold)) - { - // If we have enough temporal history available, - // we pass illumination data unmodified - // and calculate variance based on temporally accumulated moments - float specularVariance = centerSpecular2ndMoment - centerSpecular1stMoment * centerSpecular1stMoment; - float diffuseVariance = centerDiffuse2ndMoment - centerDiffuse1stMoment * centerDiffuse1stMoment; - - gOutSpecularIlluminationAndVariance[ipos] = float4(centerSpecularIllumination, specularVariance); - gOutDiffuseIlluminationAndVariance[ipos] = float4(centerDiffuseIllumination, diffuseVariance); - return; - } - - float4 centerNormalViewZ = sharedNormalViewZ[sharedMemoryCenterIndex.y][sharedMemoryCenterIndex.x]; - float3 centerNormal = centerNormalViewZ.xyz; - float centerViewZ = centerNormalViewZ.a; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float sumWSpecularIllumination = 0; - float3 sumSpecularIllumination = 0; - - float sumWDiffuseIllumination = 0; - float3 sumDiffuseIllumination = 0; - - float sumSpecular1stMoment = 0; - float sumDiffuse1stMoment = 0; - float sumSpecular2ndMoment = 0; - float sumDiffuse2ndMoment = 0; - - // Compute first and second moment spatially. This code also applies cross-bilateral - // filtering on the input illumination. - [unroll] - for (int cy = -2; cy <= 2; cy++) - { - [unroll] - for (int cx = -2; cx <= 2; cx++) - { - int2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT + cx, SKIRT + cy); - - // Fetching sample data - float3 sampleNormal = sharedNormalViewZ[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; - - float4 sampleSpecular = sharedSpecularAnd2ndMoment[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float4 sampleDiffuse = sharedDiffuseAnd2ndMoment[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float3 sampleSpecularIllumination = sampleSpecular.rgb; - float3 sampleDiffuseIllumination = sampleDiffuse.rgb; - float sampleSpecular1stMoment = STL::Color::Luminance(sampleSpecularIllumination); - float sampleDiffuse1stMoment = STL::Color::Luminance(sampleDiffuseIllumination); - float sampleSpecular2ndMoment = sampleSpecular.a; - float sampleDiffuse2ndMoment = sampleDiffuse.a; - - - // Calculating weights - float depthW = 1.0;// TODO: should we take in account depth here? - float normalW = computeNormalWeight(centerNormal, sampleNormal, gPhiNormal); - - float specularW = normalW * depthW; - float diffuseW = normalW * depthW; - - // Accumulating - sumWSpecularIllumination += specularW; - sumSpecularIllumination += sampleSpecularIllumination.rgb * specularW; - sumSpecular1stMoment += sampleSpecular1stMoment * specularW; - sumSpecular2ndMoment += sampleSpecular2ndMoment * specularW; - - sumWDiffuseIllumination += diffuseW; - sumDiffuseIllumination += sampleDiffuseIllumination.rgb * diffuseW; - sumDiffuse1stMoment += sampleDiffuse1stMoment * diffuseW; - sumDiffuse2ndMoment += sampleDiffuse2ndMoment * diffuseW; - } - } - - // Clamp sum to >0 to avoid NaNs. - sumWSpecularIllumination = max(sumWSpecularIllumination, 1e-6f); - sumWDiffuseIllumination = max(sumWDiffuseIllumination, 1e-6f); - - sumSpecularIllumination /= sumWSpecularIllumination; - sumSpecular1stMoment /= sumWSpecularIllumination; - sumSpecular2ndMoment /= sumWSpecularIllumination; - - sumDiffuseIllumination /= sumWDiffuseIllumination; - sumDiffuse1stMoment /= sumWDiffuseIllumination; - sumDiffuse2ndMoment /= sumWDiffuseIllumination; - - // compute variance using the first and second moments - float specularVariance = abs(sumSpecular2ndMoment - sumSpecular1stMoment * sumSpecular1stMoment); - float diffuseVariance = abs(sumDiffuse2ndMoment - sumDiffuse1stMoment * sumDiffuse1stMoment); - - // give the variance a boost for the first frames - float boost = max(1.0, 4.0 / (historyLength + 1.0)); - specularVariance *= boost; - diffuseVariance *= boost; - - gOutSpecularIlluminationAndVariance[ipos] = float4(sumSpecularIllumination, specularVariance); - gOutDiffuseIlluminationAndVariance[ipos] = float4(sumDiffuseIllumination, diffuseVariance); -} diff --git a/Source/Shaders/RELAX_DiffuseSpecular_SplitScreen.cs.hlsl b/Source/Shaders/RELAX_DiffuseSpecular_SplitScreen.cs.hlsl deleted file mode 100644 index 9c3ce29..0000000 --- a/Source/Shaders/RELAX_DiffuseSpecular_SplitScreen.cs.hlsl +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_DiffuseSpecular_SplitScreen.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -[numthreads( 16, 16, 1)] -NRD_EXPORT void NRD_CS_MAIN( uint2 pixelPos : SV_DispatchThreadId) -{ - float2 pixelUv = float2( pixelPos + 0.5 ) * gInvRectSize; - uint2 pixelPosUser = gRectOrigin + pixelPos; - - if( pixelUv.x > gSplitScreen ) - return; - - float viewZ = gIn_ViewZ[ pixelPosUser ]; - - uint2 checkerboardPos = pixelPos; - checkerboardPos.x = pixelPos.x >> (gDiffuseCheckerboard != 2 ? 1 : 0); - float3 diffResult = gIn_Diff[gRectOrigin + checkerboardPos]; - gOut_Diff[pixelPos] = diffResult * float(viewZ < gDenoisingRange); - - checkerboardPos.x = pixelPos.x >> (gSpecularCheckerboard != 2 ? 1 : 0); - float3 specResult = gIn_Spec[gRectOrigin + checkerboardPos]; - gOut_Spec[pixelPos] = specResult * float(viewZ < gDenoisingRange); -} diff --git a/Source/Shaders/RELAX_Diffuse_ATrousShmem.cs.hlsl b/Source/Shaders/RELAX_Diffuse_ATrousShmem.cs.hlsl deleted file mode 100644 index 05cd9c2..0000000 --- a/Source/Shaders/RELAX_Diffuse_ATrousShmem.cs.hlsl +++ /dev/null @@ -1,252 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Diffuse_ATrousShmem.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 8 -#define SKIRT 1 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedDiffuseIlluminationAndVariance[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalRoughness[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedWorldPos[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING -groupshared uint sharedMaterialType[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -#endif - -// Helper functions - -// Computes a 3x3 gaussian blur of the variance, centered around -// the current pixel -void computeVariance(int2 groupThreadId, out float diffuseVariance) -{ - float diffuseSum = 0; - - const float kernel[2][2] = - { - { 1.0 / 4.0, 1.0 / 8.0 }, - { 1.0 / 8.0, 1.0 / 16.0 } - }; - - const int radius = 1; - for (int yy = -radius; yy <= radius; yy++) - { - for (int xx = -radius; xx <= radius; xx++) - { - int2 sharedMemoryIndex = groupThreadId.xy + int2(1 + xx, 1 + yy); - float4 diffuseIlluminationAndVariance = sharedDiffuseIlluminationAndVariance[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float k = kernel[abs(xx)][abs(yy)]; - diffuseSum += diffuseIlluminationAndVariance.a * k; - } - } - diffuseVariance = diffuseSum; -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory - // - // Renumerating threads to load 18x18 (16+2 x 16+2) block of data to shared memory - // - // The preloading will be done in two stages: - // at the first stage the group will load 16x16 / 18 = 14.2 rows of the shared memory, - // and all threads in the group will be following the same path. - // At the second stage, the rest 18x18 - 16x16 = 68 threads = 2.125 warps will load the rest of data - - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - int ox = newIdxX; - int oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 diffuseIlluminationAndVariance = 0; - float3 normal = 0; - float roughness = 1.0; - float4 worldPos = 0; - float viewZ = 0.0; - uint materialType = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gResourceSize.x) && (yy < (int)gResourceSize.y)) - { - diffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[int2(xx, yy)]; - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)], materialType); - normal = normalRoughness.rgb; - roughness = normalRoughness.a; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - worldPos = float4(GetCurrentWorldPos(int2(xx, yy), viewZ), viewZ); - } - sharedDiffuseIlluminationAndVariance[oy][ox] = diffuseIlluminationAndVariance; - sharedNormalRoughness[oy][ox] = float4(normal, roughness); - sharedWorldPos[oy][ox] = worldPos; -#if (NRD_USE_MATERIAL_ID_AWARE_FILTERING == 1) - sharedMaterialType[oy][ox] = materialType; -#endif - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - diffuseIlluminationAndVariance = 0; - normal = 0; - roughness = 1.0; - worldPos = 0; - viewZ = 0.0; - materialType = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gResourceSize.x) && (yy < (int)gResourceSize.y)) - { - diffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[int2(xx, yy)]; - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)], materialType); - normal = normalRoughness.rgb; - roughness = normalRoughness.a; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - worldPos = float4(GetCurrentWorldPos(int2(xx, yy), viewZ), viewZ); - } - sharedDiffuseIlluminationAndVariance[oy][ox] = diffuseIlluminationAndVariance; - sharedNormalRoughness[oy][ox] = float4(normal, roughness); - sharedWorldPos[oy][ox] = worldPos; -#if (NRD_USE_MATERIAL_ID_AWARE_FILTERING == 1) - sharedMaterialType[oy][ox] = materialType; -#endif - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // - // Shared memory is populated now and can be used for filtering - // - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - // Fetching center data - float4 centerWorldPosAndViewZ = sharedWorldPos[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float3 centerWorldPos = centerWorldPosAndViewZ.xyz; - float centerViewZ = centerWorldPosAndViewZ.w; - float3 centerV = normalize(centerWorldPos); - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float3 centerNormal = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; - - float4 centerDiffuseIlluminationAndVariance = sharedDiffuseIlluminationAndVariance[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - - // Calculating center luminance - float centerDiffuseLuminance = STL::Color::Luminance(centerDiffuseIlluminationAndVariance.rgb); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - uint centerMaterialType = sharedMaterialType[sharedMemoryIndex.y][sharedMemoryIndex.x]; -#endif - - // Calculating variance, filtered using 3x3 gaussin blur - float centerDiffuseVar; - computeVariance(groupThreadId.xy, centerDiffuseVar); - - float diffusePhiLIllumination = 1.0e-4 + gDiffusePhiLuminance * sqrt(max(0.0, centerDiffuseVar)); - float depthThreshold = gDepthThreshold; - - float sumWDiffuse = 0; - float4 sumDiffuseIlluminationAndVariance = 0; - - static const float kernelWeightGaussian3x3[2] = { 0.44198, 0.27901 }; - - [unroll] - for (int cy = -1; cy <= 1; cy++) - { - [unroll] - for (int cx = -1; cx <= 1; cx++) - { - const float kernel = kernelWeightGaussian3x3[abs(cx)] * kernelWeightGaussian3x3[abs(cy)]; - const int2 p = ipos + int2(cx, cy); - const bool isInside = all(p >= int2(0, 0)) && all(p < (int2)gResourceSize); - const bool isCenter = ((cx == 0) && (cy == 0)); - - int2 sampleSharedMemoryIndex = groupThreadId.xy + int2(SKIRT + cx, SKIRT + cy); - - float3 sampleNormal = sharedNormalRoughness[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x].rgb; - float3 sampleWorldPos = sharedWorldPos[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x].rgb; - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - uint sampleMaterialType = sharedMaterialType[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; -#endif - - float4 sampleDiffuseIlluminationAndVariance = sharedDiffuseIlluminationAndVariance[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; - - float sampleDiffuseLuminance = STL::Color::Luminance(sampleDiffuseIlluminationAndVariance.rgb); - - // Calculating geometry and normal weights - float geometryW = GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - depthThreshold); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - geometryW *= (sampleMaterialType == centerMaterialType) ? 1.0 : 0.0; -#endif - - float normalWDiffuse = GetDiffuseNormalWeight_ATrous(centerNormal, sampleNormal, gPhiNormal); - - // Calculating luminande weigths - float diffuseLuminanceW = abs(centerDiffuseLuminance - sampleDiffuseLuminance) / diffusePhiLIllumination; - diffuseLuminanceW = min(gMaxLuminanceRelativeDifference, diffuseLuminanceW); - - float wDiffuse = kernel; - if (!isCenter) - { - // Calculating bilateral weight for diffuse - wDiffuse = kernel * max(1e-6, normalWDiffuse * geometryW * exp_approx(-diffuseLuminanceW)); - } - - // Discarding out of screen samples - wDiffuse *= isInside ? 1.0 : 0.0; - - // alpha channel contains the variance, therefore the weights need to be squared - sumWDiffuse += wDiffuse; - sumDiffuseIlluminationAndVariance += float4(wDiffuse.xxx, wDiffuse * wDiffuse) * sampleDiffuseIlluminationAndVariance; - } - } - - float4 filteredDiffuseIlluminationAndVariance = float4(sumDiffuseIlluminationAndVariance / float4(sumWDiffuse.xxx, sumWDiffuse * sumWDiffuse)); - - gOutDiffuseIlluminationAndVariance[ipos] = filteredDiffuseIlluminationAndVariance; -} diff --git a/Source/Shaders/RELAX_Diffuse_ATrousStandard.cs.hlsl b/Source/Shaders/RELAX_Diffuse_ATrousStandard.cs.hlsl deleted file mode 100644 index fa0563d..0000000 --- a/Source/Shaders/RELAX_Diffuse_ATrousStandard.cs.hlsl +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Diffuse_ATrousStandard.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -[numthreads(16, 16, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId) -{ - uint centerMaterialType; - float3 centerNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos], centerMaterialType).rgb; - - float centerViewZ = gViewZFP16[ipos] / NRD_FP16_VIEWZ_SCALE; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { -#if( RELAX_BLACK_OUT_INF_PIXELS == 1 ) - gOutDiffuseIlluminationAndVariance[ipos] = 0; -#endif - return; - } - - float4 centerDiffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[ipos]; - float centerDiffuseLuminance = STL::Color::Luminance(centerDiffuseIlluminationAndVariance.rgb); - - // Variance, NOT filtered using 3x3 gaussin blur, as we don't need this in other than 1st Atrous pass - float centerDiffuseVar = centerDiffuseIlluminationAndVariance.a; - - float3 centerWorldPos = GetCurrentWorldPos(ipos, centerViewZ); - - float diffusePhiLIllumination = 1.0e-4 + gDiffusePhiLuminance * sqrt(max(0.0, centerDiffuseVar)); - float depthThreshold = gDepthThreshold; - - static const float kernelWeightGaussian3x3[2] = { 0.44198, 0.27901 }; - - float sumWDiffuse = 0.44198 * 0.44198; - float4 sumDiffuseIlluminationAndVariance = centerDiffuseIlluminationAndVariance * float4(sumWDiffuse.xxx, sumWDiffuse * sumWDiffuse); - - // Adding random offsets to minimize "ringing" at large A-Trous steps - uint2 offset = 0; - if (gStepSize > 4) - { - STL::Rng::Initialize(ipos, gFrameIndex); - offset = int2(gStepSize.xx * 0.5 * (STL::Rng::GetFloat2() - 0.5)); - } - - [unroll] - for (int yy = -1; yy <= 1; yy++) - { - [unroll] - for (int xx = -1; xx <= 1; xx++) - { - int2 p = ipos + offset + int2(xx, yy) * gStepSize; - bool isInside = all(p >= int2(0, 0)) && all(p < (int2)gRectSize); - bool isCenter = ((xx == 0) && (yy == 0)); - if (isCenter) continue; - - float kernel = kernelWeightGaussian3x3[abs(xx)] * kernelWeightGaussian3x3[abs(yy)]; - - // Discarding out of screen samples - float wDiffuse = isInside ? kernel : 0.0; - - // Fetching normal, roughness, linear Z - uint sampleMaterialType; - float3 sampleNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[p], sampleMaterialType).rgb; - float sampleViewZ = gViewZFP16[p] / NRD_FP16_VIEWZ_SCALE; - - // Calculating sample world position - float3 sampleWorldPos = GetCurrentWorldPos(p, sampleViewZ); - - // Calculating geometry weight for diffuse and specular - float geometryW = GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - depthThreshold); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - geometryW *= (sampleMaterialType == centerMaterialType) ? 1.0 : 0.0; -#endif - - // Calculating normal weight for diffuse - float normalWDiffuse = GetDiffuseNormalWeight_ATrous(centerNormal, sampleNormal, gPhiNormal); - - // Applying all the weights except luminance weights - wDiffuse *= geometryW * normalWDiffuse; - - // Summing up diffuse - if (wDiffuse > 1e-4) - { - float4 sampleDiffuseIlluminationAndVariance = gDiffuseIlluminationAndVariance[p]; - float sampleDiffuseLuminance = STL::Color::Luminance(sampleDiffuseIlluminationAndVariance.rgb); - - float diffuseLuminanceW = abs(centerDiffuseLuminance - sampleDiffuseLuminance) / diffusePhiLIllumination; - diffuseLuminanceW = min(gMaxLuminanceRelativeDifference, diffuseLuminanceW); - - wDiffuse *= exp_approx(-diffuseLuminanceW); - sumDiffuseIlluminationAndVariance += float4(wDiffuse.xxx, wDiffuse * wDiffuse) * sampleDiffuseIlluminationAndVariance; - sumWDiffuse += wDiffuse; - } - } - } - - float4 filteredDiffuseIlluminationAndVariance = float4(sumDiffuseIlluminationAndVariance / float4(sumWDiffuse.xxx, sumWDiffuse * sumWDiffuse)); - - gOutDiffuseIlluminationAndVariance[ipos] = filteredDiffuseIlluminationAndVariance; -} diff --git a/Source/Shaders/RELAX_Diffuse_DisocclusionFix.cs.hlsl b/Source/Shaders/RELAX_Diffuse_DisocclusionFix.cs.hlsl deleted file mode 100644 index 8544616..0000000 --- a/Source/Shaders/RELAX_Diffuse_DisocclusionFix.cs.hlsl +++ /dev/null @@ -1,124 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Diffuse_DisocclusionFix.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -// Helper functions -float getDiffuseNormalWeight(float3 centerNormal, float3 pointNormal) -{ - return pow(max(0.01, dot(centerNormal, pointNormal)), max(gDisocclusionFixEdgeStoppingNormalPower, 0.01)); -} - -float GetRadius(float numFramesInHistory) -{ - return gMaxRadius / (numFramesInHistory + 1.0); -} - -// -// Main -// - -[numthreads(8, 8, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId) -{ - const int2 ipos = int2(dispatchThreadId.xy); - - float centerViewZ = gViewZFP16[ipos] / NRD_FP16_VIEWZ_SCALE; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float historyLength = 255.0 * gDiffuseHistoryLength[ipos]; - float4 diffuseIlluminationAnd2ndMoment = gDiffuseIllumination[ipos]; - float4 diffuseIlluminationResponsive = gDiffuseIlluminationResponsive[ipos]; - - // Pass through the input data if no disocclusion detected - [branch] - if (historyLength > gFramesToFix) - { - gOutDiffuseIllumination[ipos] = diffuseIlluminationAnd2ndMoment; - gOutDiffuseIlluminationResponsive[ipos] = diffuseIlluminationResponsive; - return; - } - - // Unpacking the rest of center data - float3 centerNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos]).rgb; - float3 centerWorldPos = GetCurrentWorldPos(ipos, centerViewZ); - - // Running sparse cross-bilateral filter - float4 diffuseIlluminationAnd2ndMomentSum = diffuseIlluminationAnd2ndMoment; - - float diffuseWSum = 1; - - float r = GetRadius(historyLength); - - [unroll] - for (int j = -2; j <= 2; j++) - [unroll] - for (int i = -2; i <= 2; i++) - { - int dx = (int)(i * r); - int dy = (int)(j * r); - - int2 samplePosInt = (int2)ipos + int2(dx, dy); - - bool isInside = all(samplePosInt >= int2(0, 0)) && all(samplePosInt < int2(gRectSize)); - if ((i == 0) && (j == 0)) continue; - - float3 sampleNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[samplePosInt]).rgb; - - float sampleViewZ = gViewZFP16[samplePosInt] / NRD_FP16_VIEWZ_SCALE; - - // Edge stopping functions: - // ..normal - float diffuseW = getDiffuseNormalWeight(centerNormal, sampleNormal); - - // ..geometry - float3 sampleWorldPos = GetCurrentWorldPos(samplePosInt, sampleViewZ); - float geometryWeight = GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - gDepthThreshold); - diffuseW *= geometryWeight; - diffuseW *= isInside ? 1.0 : 0; - - // Summing up diffuse result - if (diffuseW > 1e-4) - { - float4 sampleDiffuseIlluminationAnd2ndMoment = gDiffuseIllumination[samplePosInt]; - diffuseIlluminationAnd2ndMomentSum += sampleDiffuseIlluminationAnd2ndMoment * diffuseW; - diffuseWSum += diffuseW; - } - - } - - float4 outDiffuseIlluminationAnd2ndMoment = diffuseIlluminationAnd2ndMomentSum / diffuseWSum; - - // Writing out the results - gOutDiffuseIllumination[ipos] = outDiffuseIlluminationAnd2ndMoment; - gOutDiffuseIlluminationResponsive[ipos] = outDiffuseIlluminationAnd2ndMoment; -} \ No newline at end of file diff --git a/Source/Shaders/RELAX_Diffuse_Firefly.cs.hlsl b/Source/Shaders/RELAX_Diffuse_Firefly.cs.hlsl deleted file mode 100644 index fe37ce9..0000000 --- a/Source/Shaders/RELAX_Diffuse_Firefly.cs.hlsl +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Diffuse_Firefly.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 1 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedDiffuseIllumination[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalAndViewZ[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -// Helper functions - -float edgeStoppingDepth(float centerViewZ, float sampleViewZ) -{ - return (abs(centerViewZ - sampleViewZ) / (centerViewZ + 1e-6)) < 0.1 ? 1.0 : 0.0; -} - -void PopulateSharedMemoryForFirefly(uint2 dispatchThreadId, uint2 groupThreadId, uint2 groupId) -{ - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 diffuseIllumination = 0; - float3 normal = 0; - float viewZ = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - diffuseIllumination = gDiffuseIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedDiffuseIllumination[oy][ox] = diffuseIllumination; - sharedNormalAndViewZ[oy][ox] = float4(normal, viewZ); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - diffuseIllumination = 0; - normal = 0; - viewZ = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - diffuseIllumination = gDiffuseIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedDiffuseIllumination[oy][ox] = diffuseIllumination; - sharedNormalAndViewZ[oy][ox] = float4(normal, viewZ); - } -} - -// Cross bilateral Rank-Conditioned Rank-Selection (RCRS) filter -void runRCRS(int2 dispatchThreadId, int2 groupThreadId, float3 centerNormal, float centerViewZ, out float4 outDiffuse) -{ - // Fetching center data - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - float4 d = sharedDiffuseIllumination[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - float3 diffuseIlluminationCenter = d.rgb; - float diffuse2ndMomentCenter = d.a; - - float diffuseLuminanceCenter = STL::Color::Luminance(diffuseIlluminationCenter); - - // Finding max and min luminance in neighborhood, rejecting samples that don't belong to center pixel's surface - float maxDiffuseLuminance = -1.0; - float minDiffuseLuminance = 1.0e6; - int2 maxDiffuseLuminanceCoords = sharedMemoryIndex; - int2 minDiffuseLuminanceCoords = sharedMemoryIndex; - - [unroll] - for (int yy = -1; yy <= 1; yy++) - { - [unroll] - for (int xx = -1; xx <= 1; xx++) - { - int2 p = dispatchThreadId.xy + int2(xx, yy); - int2 sharedMemoryIndexSample = groupThreadId.xy + int2(SKIRT, SKIRT) + int2(xx, yy); - - if ((xx == 0) && (yy == 0)) continue; - if (any(p < int2(0,0)) || any(p >= int2(gRectSize))) continue; - - // Fetching sample data - float4 v = sharedNormalAndViewZ[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x]; - float3 sampleNormal = v.xyz; - float sampleViewZ = v.w; - - float3 diffuseIlluminationSample = sharedDiffuseIllumination[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x].rgb; - - float diffuseLuminanceSample = STL::Color::Luminance(diffuseIlluminationSample); - - // Applying weights - // ..normal weight - float weight = dot(centerNormal, sampleNormal) > 0.99 ? 1.0 : 0.0; - - // ..depth weight - weight *= edgeStoppingDepth(centerViewZ, sampleViewZ); - - if (weight > 0) - { - if (diffuseLuminanceSample > maxDiffuseLuminance) - { - maxDiffuseLuminance = diffuseLuminanceSample; - maxDiffuseLuminanceCoords = sharedMemoryIndexSample; - } - if (diffuseLuminanceSample < minDiffuseLuminance) - { - minDiffuseLuminance = diffuseLuminanceSample; - minDiffuseLuminanceCoords = sharedMemoryIndexSample; - } - } - } - } - - // Replacing current value with min or max in the neighborhood if outside min..max range, - // or leaving sample as it is if it's within the range - int2 diffuseCoords = sharedMemoryIndex; - - if (diffuseLuminanceCenter > maxDiffuseLuminance) - { - diffuseCoords = maxDiffuseLuminanceCoords; - } - if (diffuseLuminanceCenter < minDiffuseLuminance) - { - diffuseCoords = minDiffuseLuminanceCoords; - } - outDiffuse = float4(sharedDiffuseIllumination[diffuseCoords.y][diffuseCoords.x].rgb, diffuse2ndMomentCenter); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory for firefly filter - PopulateSharedMemoryForFirefly(dispatchThreadId.xy, groupThreadId.xy, groupId.xy); - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // Shared memory is populated now and can be used for filtering - float4 v = sharedNormalAndViewZ[groupThreadId.y + SKIRT][groupThreadId.x + SKIRT]; - float3 centerNormal = v.xyz; - float centerViewZ = v.w; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - // Running firefly filter - float4 outDiffuseIlluminationAnd2ndMoment; - - runRCRS(dispatchThreadId.xy, groupThreadId.xy, centerNormal, centerViewZ, outDiffuseIlluminationAnd2ndMoment); - - gOutDiffuseIllumination[dispatchThreadId.xy] = outDiffuseIlluminationAnd2ndMoment; -} - diff --git a/Source/Shaders/RELAX_Diffuse_HistoryClamping.cs.hlsl b/Source/Shaders/RELAX_Diffuse_HistoryClamping.cs.hlsl deleted file mode 100644 index 64116dc..0000000 --- a/Source/Shaders/RELAX_Diffuse_HistoryClamping.cs.hlsl +++ /dev/null @@ -1,139 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Diffuse_HistoryClamping.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 2 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float3 sharedDiffuse[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -void runHistoryClamping(int2 pixelPos, int2 sharedMemoryIndex, float3 diffuse, out float3 outDiffuse) -{ - - float3 diffuseYCoCg = STL::Color::LinearToYCoCg(diffuse); - - float3 diffuseFirstMoment = 0; - float3 diffuseSecondMoment = 0; - - [unroll] - for (int dy = -2; dy <= 2; dy++) - { - [unroll] - for (int dx = -2; dx <= 2; dx++) - { - uint2 sharedMemoryIndexP = sharedMemoryIndex + int2(dx, dy); - int2 p = pixelPos + int2(dx, dy); - if (any(p < int2(0,0)) || any(p >= int2(gRectSize))) sharedMemoryIndexP = sharedMemoryIndex; - - float3 diffuseP = sharedDiffuse[sharedMemoryIndexP.y][sharedMemoryIndexP.x]; - - diffuseFirstMoment += diffuseP; - diffuseSecondMoment += diffuseP * diffuseP; - } - } - - diffuseFirstMoment /= 25.0; - diffuseSecondMoment /= 25.0; - - // Calculating color boxes for diffuse signal - float3 diffuseSigma = sqrt(max(0.0f, diffuseSecondMoment - diffuseFirstMoment * diffuseFirstMoment)); - float3 diffuseColorMin = diffuseFirstMoment - gColorBoxSigmaScale * diffuseSigma; - float3 diffuseColorMax = diffuseFirstMoment + gColorBoxSigmaScale * diffuseSigma; - - // Expanding diffuse color boxes with color of the center pixel for diffuse signal - // to avoid introducing bias - float3 diffuseCenter = sharedDiffuse[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - diffuseColorMin = min(diffuseColorMin, diffuseCenter); - diffuseColorMax = max(diffuseColorMax, diffuseCenter); - - // Color clamping - diffuseYCoCg = clamp(diffuseYCoCg, diffuseColorMin, diffuseColorMax); - outDiffuse = STL::Color::YCoCgToLinear(diffuseYCoCg); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float3 diffuseResponsive = 0; - - if (xx >= 0 && yy >= 0 && xx < (int)gRectSize.x && yy < (int)gRectSize.y) - { - diffuseResponsive = gDiffuseResponsiveIllumination[int2(xx, yy)].rgb; - } - sharedDiffuse[oy][ox] = STL::Color::LinearToYCoCg(diffuseResponsive); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - diffuseResponsive = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if (xx >= 0 && yy >= 0 && xx < (int)gRectSize.x && yy < (int)gRectSize.y) - { - diffuseResponsive = gDiffuseResponsiveIllumination[int2(xx, yy)].rgb; - } - sharedDiffuse[oy][ox] = STL::Color::LinearToYCoCg(diffuseResponsive); - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - // Shared memory is populated with responsive history now and can be used for history clamping - - // Reading normal history - float4 diffuseAnd2ndMoment = gDiffuseIllumination[dispatchThreadId.xy]; - - // Reading history length - float historyLength = gDiffuseHistoryLength[dispatchThreadId.xy]; - - // Running history clamping - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - float3 clampedDiffuse; - float adjustedHistoryLength; - runHistoryClamping(dispatchThreadId.xy, sharedMemoryIndex, diffuseAnd2ndMoment.rgb, clampedDiffuse); - - // Writing out the results - gOutDiffuseIllumination[dispatchThreadId.xy] = float4(clampedDiffuse, diffuseAnd2ndMoment.a); - gOutDiffuseHistoryLength[dispatchThreadId.xy] = historyLength; -} diff --git a/Source/Shaders/RELAX_Diffuse_Prepass.cs.hlsl b/Source/Shaders/RELAX_Diffuse_Prepass.cs.hlsl deleted file mode 100644 index d84fa94..0000000 --- a/Source/Shaders/RELAX_Diffuse_Prepass.cs.hlsl +++ /dev/null @@ -1,261 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Diffuse_Prepass.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -#define POISSON_SAMPLE_NUM 8 -#define POISSON_SAMPLES g_Poisson8 - -#define THREAD_GROUP_SIZE 16 - -float GetNormHitDist(float hitDist, float viewZ, float4 hitDistParams = float4(3.0, 0.1, 10.0, -25.0), float linearRoughness = 1.0) -{ - float f = _REBLUR_GetHitDistanceNormalization(viewZ, hitDistParams, linearRoughness); - return saturate(hitDist / f); -} - -float GetBlurRadius(float radius, float hitDist, float viewZ, float nonLinearAccumSpeed, float boost, float error, float radiusBias, float radiusScale) -{ - // Modify by hit distance - float hitDistFactor = hitDist / (hitDist + viewZ); - float s = hitDistFactor; - - // A non zero addition is needed to avoid under-blurring: - float addon = 9.0; - addon = min(addon, radius * 0.333); - addon *= hitDistFactor; - - // Final blur radius - float r = s * radius + addon; - r = r * (radiusScale + radiusBias) + radiusBias; - return r; -} - -float2x3 GetKernelBasis(float3 X, float3 N, float worldRadius, float roughness = 1.0, float anisoFade = 1.0) -{ - float3x3 basis = STL::Geometry::GetBasis(N); - float3 T = basis[0]; - float3 B = basis[1]; - - float3 V = -normalize(X); - float4 D = STL::ImportanceSampling::GetSpecularDominantDirection(N, V, roughness, RELAX_SPEC_DOMINANT_DIRECTION); - float NoD = abs(dot(N, D.xyz)); - - if (NoD < 0.999 && roughness < RELAX_SPEC_BASIS_ROUGHNESS_THRESHOLD) - { - float3 R = reflect(-D.xyz, N); - T = normalize(cross(N, R)); - B = cross(R, T); - -#if( RELAX_USE_ANISOTROPIC_KERNEL == 1 ) - float NoV = abs(dot(N, V)); - float acos01sq = saturate(1.0 - NoV); // see AcosApprox() - - float skewFactor = lerp(1.0, roughness, D.w); - skewFactor = lerp(1.0, skewFactor, STL::Math::Sqrt01(acos01sq)); - - T *= lerp(skewFactor, 1.0, anisoFade); -#endif - } - - T *= worldRadius; - B *= worldRadius; - - return float2x3(T, B); -} - -float2 GetHitDistanceWeightParams(float normHitDist, float nonLinearAccumSpeed, float roughness = 1.0) -{ - float threshold = exp2(-17.0 * roughness * roughness); // TODO: not in line with other weights - float scale = lerp(threshold, 1.0, nonLinearAccumSpeed); - - float a = rcp(normHitDist * scale * 0.99 + 0.01); - float b = normHitDist * a; - - return float2(a, -b); -} - -float GetNormalWeightParams(float nonLinearAccumSpeed, float edge, float error, float roughness = 1.0, float strictness = 1.0) -{ - float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle(roughness); - - // TODO: 0.15 can be different for blur passes - // TODO: curvature is needed to estimate initial scale - float s = lerp(0.04, 0.15, error); - s *= strictness; - - s = lerp(s, 1.0, edge); - s = lerp(s, 1.0, nonLinearAccumSpeed); - angle *= s; - - angle += STL::Math::DegToRad(0.625); - - return rcp(angle); -} - -int2 DiffCheckerboard(int2 pos) -{ - int2 result = pos; - if (gDiffuseCheckerboard != 2) - { - result.x >>= 1; - } - return result; -} - -float GetGaussianWeight(float r) -{ - // radius is normalized to 1 - return exp(-0.66 * r * r); -} - -float GetNormalWeight(float params0, float3 n0, float3 n) -{ - float cosa = saturate(dot(n0, n)); - float angle = STL::Math::AcosApprox(cosa); - - return _ComputeWeight(float2(params0, -0.001), angle); -} - -#define GetHitDistanceWeight(p, value) _ComputeWeight(p, value) - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Calculating checkerboard fields - bool diffHasData = true; - uint checkerboard = STL::Sequence::CheckerBoard(ipos, gFrameIndex); - - if (gDiffuseCheckerboard != 2) - { - diffHasData = (checkerboard == gDiffuseCheckerboard); - } - - // Reading center GBuffer data - // Applying abs() to viewZ so it is positive down the denoising pipeline. - // This ensures correct denoiser operation with different camera handedness. - float centerViewZ = abs(gViewZ[ipos + gRectOrigin]); - float3 centerNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos + gRectOrigin]).rgb; - - // Outputting ViewZ and scaled ViewZ to be used down the denoising pipeline - gOutViewZ[ipos] = centerViewZ; - gOutScaledViewZ[ipos] = min(centerViewZ * NRD_FP16_VIEWZ_SCALE, NRD_FP16_MAX); - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float2 uv = ((float2)ipos + float2(0.5, 0.5)) * gInvRectSize; - float3 centerWorldPos = GetCurrentWorldPos(uv * 2.0 - 1.0, centerViewZ); - float4 rotator = GetBlurKernelRotation(NRD_FRAME, ipos, gRotator, gFrameIndex); - - // Checkerboard resolve weights - float2 checkerboardResolveWeights = 1.0; - if (gDiffuseCheckerboard != 2) - { - float viewZ0 = abs(gViewZ[ipos + int2(-1, 0) + gRectOrigin]); - float viewZ1 = abs(gViewZ[ipos + int2(1, 0) + gRectOrigin]); - - checkerboardResolveWeights = GetBilateralWeight(float2(viewZ0, viewZ1), centerViewZ); - checkerboardResolveWeights *= STL::Math::PositiveRcp(checkerboardResolveWeights.x + checkerboardResolveWeights.y); - } - - // Reading diffuse & resolving diffuse checkerboard - float4 diffuseIllumination = gDiffuseIllumination[DiffCheckerboard(ipos + gRectOrigin)]; - - if (!diffHasData) - { - float4 d0 = gDiffuseIllumination[DiffCheckerboard(ipos + int2(-1, 0) + gRectOrigin)]; - float4 d1 = gDiffuseIllumination[DiffCheckerboard(ipos + int2(1, 0) + gRectOrigin)]; - diffuseIllumination *= saturate(1.0 - checkerboardResolveWeights.x - checkerboardResolveWeights.y); - diffuseIllumination += d0 * checkerboardResolveWeights.x + d1 * checkerboardResolveWeights.y; - } - - // Pre-blur for diffuse - if (gDiffuseBlurRadius > 0) - { - // Diffuse blur radius - float hitDist = GetNormHitDist(diffuseIllumination.w, centerViewZ); - float blurRadius = GetBlurRadius(gDiffuseBlurRadius, diffuseIllumination.w, centerViewZ, 1.0 / 9.0, 1.0, 1.0, 0, 1.0); - - float worldBlurRadius = PixelRadiusToWorld(gUnproject, gIsOrtho, blurRadius, centerViewZ) * - min(gResolutionScale.x, gResolutionScale.y); - - float2x3 TvBv = GetKernelBasis(centerWorldPos, centerNormal, worldBlurRadius); - float normalWeightParams = GetNormalWeightParams(1.0 / 9.0, 0.0, 1.0, 1.0, 1.0); - float2 hitDistanceWeightParams = GetHitDistanceWeightParams(diffuseIllumination.w, 1.0 / 9.0); - float weightSum = 1.0; - - // Spatial blur - [unroll] - for (uint i = 0; i < POISSON_SAMPLE_NUM; i++) - { - float3 offset = POISSON_SAMPLES[i]; - - // Sample coordinates - float2 uv = GetKernelSampleCoordinates(gWorldToClip, offset, centerWorldPos, TvBv[0], TvBv[1], rotator); - - // Handle half res input in the checkerboard mode - float2 checkerboardUv = uv; - if (gDiffuseCheckerboard != 2) - { - checkerboardUv = ApplyCheckerboard(uv, gDiffuseCheckerboard, i, gRectSize, gInvRectSize, gFrameIndex); - } - - // Fetch data - float2 uvScaled = uv * gResolutionScale; - float3 sampleNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0)).rgb; - - float2 checkerboardUvScaled = checkerboardUv * gResolutionScale + gRectOffset; - float4 sampleDiffuseIllumination = gDiffuseIllumination.SampleLevel(gNearestMirror, checkerboardUvScaled, 0); - float sampleViewZ = abs(gViewZ.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0)); - - float3 sampleWorldPos = GetCurrentWorldPos(uv * 2.0 - 1.0, sampleViewZ); - - // Sample weight - float sampleWeight = IsInScreen(uv); - sampleWeight *= GetGaussianWeight(offset.z); - - float sampleNormalizedHitDist = GetNormHitDist(sampleDiffuseIllumination.w, sampleViewZ); - - float minHitDistanceWeight = 0.2; - float hitDistanceWeight = GetHitDistanceWeight(hitDistanceWeightParams, sampleNormalizedHitDist); - - sampleWeight *= GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - gDepthThreshold); - - sampleWeight *= GetNormalWeight(normalWeightParams, centerNormal, sampleNormal); - sampleWeight *= lerp(minHitDistanceWeight, 1.0, hitDistanceWeight); - - diffuseIllumination += sampleDiffuseIllumination * sampleWeight; - weightSum += sampleWeight; - } - diffuseIllumination /= weightSum; - } - gOutDiffuseIllumination[ipos] = clamp(diffuseIllumination, 0, NRD_FP16_MAX); -} diff --git a/Source/Shaders/RELAX_Diffuse_Reproject.cs.hlsl b/Source/Shaders/RELAX_Diffuse_Reproject.cs.hlsl deleted file mode 100644 index 378722e..0000000 --- a/Source/Shaders/RELAX_Diffuse_Reproject.cs.hlsl +++ /dev/null @@ -1,460 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Diffuse_Reproject.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 1 - -groupshared float4 sharedNormalRoughness[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -// Helper functions -float getJitterRadius(float jitterDelta, float linearZ) -{ - return jitterDelta * gUnproject * (gIsOrtho == 0 ? linearZ : 1.0); -} - - -float isReprojectionTapValid(float3 currentWorldPos, float3 previousWorldPos, float3 currentNormal, float disocclusionThreshold) -{ - // Check if plane distance is acceptable - float3 posDiff = currentWorldPos - previousWorldPos; - float maxPlaneDistance = abs(dot(posDiff, currentNormal)); - return maxPlaneDistance > disocclusionThreshold ? 0.0 : 1.0; -} - -// Returns reprojection search result based on surface motion: -// 2 - reprojection found, bicubic footprint was used -// 1 - reprojection found, bilinear footprint was used -// 0 - reprojection not found -// -// Also returns reprojected data from previous frame calculated using filtering based on filters above. -// For better performance, some data is filtered using weighed bilinear instead of bicubic even if all bicubic taps are valid. -float loadSurfaceMotionBasedPrevData( - int2 pixelPosOnScreen, - float3 currentWorldPos, - float3 currentNormal, - float currentLinearZ, - float3 motionVector, - out float4 prevDiffuseIllumAnd2ndMoment, - out float3 prevDiffuseResponsiveIllum, - out float3 prevNormal, - out float historyLength, - out float footprintQuality) -{ - // Calculating jitter margin radius in world space - float jitterRadius = getJitterRadius(gPrevCameraPositionAndJitterDelta.w, currentLinearZ); - float disocclusionThreshold = (gDisocclusionDepthThreshold + jitterRadius) * (gIsOrtho == 0 ? currentLinearZ : 1.0); - - // Calculating previous pixel position and UV - float2 pixelUV = (pixelPosOnScreen + 0.5) * gInvRectSize; - float2 prevUV = STL::Geometry::GetPrevUvFromMotion(pixelUV, currentWorldPos, gPrevWorldToClip, motionVector, gIsWorldSpaceMotion); - float2 prevPixelPosOnScreen = prevUV * gRectSizePrev; - - // 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. - int2 prevPixelPosInt = int2(prevPixelPosOnScreen); - bool isSmallMotion = all(prevPixelPosInt == pixelPosOnScreen); - bool skipReprojectionTest = gSkipReprojectionTestWithoutMotion && gIsCameraStatic && isSmallMotion; - - // Calculating footprint origin and weights - int2 bilinearOrigin = int2(floor(prevPixelPosOnScreen - 0.5)); - float2 bilinearWeights = frac(prevPixelPosOnScreen - 0.5); - - // Checking bicubic footprint (with cut corners) first, - // remembering bilinear taps validity and worldspace position along the way, - // for faster weighted bilinear and for calculating previous worldspace position - // bc - bicubic & bilinear tap, - // bl - bilinear tap - // - // -- bc bc -- - // bc bl bl bc - // bc bl bl bc - // -- bc bc -- - - float bicubicFootprintValid = 1.0; - float4 bilinearTapsValid = 0; - - float3 prevNormalInTap; - float prevViewZInTap; - float3 prevWorldPosInTap; - int2 tapPos; - float reprojectionTapValid; - float3 prevNormal00, prevNormal10, prevNormal01, prevNormal11; - - prevNormal00 = UnpackPrevNormalRoughness(gPrevNormalRoughness[bilinearOrigin + int2(0, 0)]).rgb; - prevNormal10 = UnpackPrevNormalRoughness(gPrevNormalRoughness[bilinearOrigin + int2(1, 0)]).rgb; - prevNormal01 = UnpackPrevNormalRoughness(gPrevNormalRoughness[bilinearOrigin + int2(0, 1)]).rgb; - prevNormal11 = UnpackPrevNormalRoughness(gPrevNormalRoughness[bilinearOrigin + int2(1, 1)]).rgb; - float3 prevNormalFlat = normalize(prevNormal00 + prevNormal10 + prevNormal01 + prevNormal11); - - // Adjusting worldspace position: - // Applying worldspace motion first, - motionVector *= gIsWorldSpaceMotion > 0 ? 1.0 : 0.0; - - // Then taking care of camera motion, because world space is always centered at camera position in NRD - currentWorldPos += motionVector - gPrevCameraPositionAndJitterDelta.xyz; - - // Transforming bilinearOrigin to clip space coords to simplify previous world pos calculation - float2 prevClipSpaceXY = ((float2)bilinearOrigin + float2(0.5, 0.5)) * (1.0 / gRectSizePrev) * 2.0 - 1.0; - float2 dXY = (2.0 / gRectSizePrev); - - // 1st row - tapPos = bilinearOrigin + int2(0, -1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, -1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - tapPos = bilinearOrigin + int2(1, -1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, -1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - // 2nd row - tapPos = bilinearOrigin + int2(-1, 0); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(-1.0, 0.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - tapPos = bilinearOrigin + int2(0, 0); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 0.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - bilinearTapsValid.x = reprojectionTapValid; - - tapPos = bilinearOrigin + int2(1, 0); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 0.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - bilinearTapsValid.y = reprojectionTapValid; - - tapPos = bilinearOrigin + int2(2, 0); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(2.0, 0.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - // 3rd row - tapPos = bilinearOrigin + int2(-1, 1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(-1.0, 1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - tapPos = bilinearOrigin + int2(0, 1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - bilinearTapsValid.z = reprojectionTapValid; - - tapPos = bilinearOrigin + int2(1, 1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - bilinearTapsValid.w = reprojectionTapValid; - - tapPos = bilinearOrigin + int2(2, 1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(2.0, 1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - // 4th row - tapPos = bilinearOrigin + int2(0, 2); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 2.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - tapPos = bilinearOrigin + int2(1, 2); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 2.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - bilinearTapsValid = skipReprojectionTest ? float4(1.0, 1.0, 1.0, 1.0) : bilinearTapsValid; - - // Reject backfacing history: if angle between current normal and previous normal is larger than 90 deg - if (dot(currentNormal, prevNormalFlat) < 0.0) - { - bilinearTapsValid = 0; - bicubicFootprintValid = 0; - } - - // Checking bicubic footprint validity for being in rect - if (any(bilinearOrigin < int2(1, 1)) || any(bilinearOrigin >= int2(gRectSizePrev)-int2(2, 2))) - { - bicubicFootprintValid = 0; - } - - // Checking bilinear footprint validity for being in rect - // Bilinear footprint: - // x y - // z w - if (bilinearOrigin.x < 0) bilinearTapsValid.xz = 0; - if (bilinearOrigin.x >= gRectSizePrev.x) bilinearTapsValid.yw = 0; - if (bilinearOrigin.y < 0) bilinearTapsValid.xy = 0; - if (bilinearOrigin.y >= gRectSizePrev.y) bilinearTapsValid.zw = 0; - - // Calculating interpolated binary weight for bilinear taps in advance - STL::Filtering::Bilinear bilinear; - bilinear.weights = bilinearWeights; - float interpolatedBinaryWeight = STL::Filtering::ApplyBilinearFilter(bilinearTapsValid.x, bilinearTapsValid.y, bilinearTapsValid.z, bilinearTapsValid.w, bilinear); - interpolatedBinaryWeight = max(1e-6, interpolatedBinaryWeight); - - // Applying reprojection filters - float reprojectionFound = 0; - prevDiffuseIllumAnd2ndMoment = 0; - prevDiffuseResponsiveIllum = 0; - prevNormal = currentNormal; - historyLength = 0; - footprintQuality = 0; - - if (any(bilinearTapsValid)) - { - // Trying to apply bicubic filter first - if (bicubicFootprintValid > 0) - { - // Bicubic for illumination and 2nd moments - prevDiffuseIllumAnd2ndMoment = - max(0, BicubicFloat4(gPrevDiffuseIllumination, gLinearClamp, prevPixelPosOnScreen, gInvResourceSize)); -#if( RELAX_USE_BICUBIC_FOR_FAST_HISTORY == 1 ) - prevDiffuseResponsiveIllum = max(0, BicubicFloat4(gPrevDiffuseIlluminationResponsive, gLinearClamp, prevPixelPosOnScreen, gInvResourceSize)).rgb; -#else - prevDiffuseResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevDiffuseIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; -#endif - footprintQuality = 1.0; - reprojectionFound = 2.0; - } - else - { - // If no success with the bicubic, then do weighted bilinear - prevDiffuseIllumAnd2ndMoment = - BilinearWithBinaryWeightsFloat4(gPrevDiffuseIllumination, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - prevDiffuseResponsiveIllum = - BilinearWithBinaryWeightsFloat4(gPrevDiffuseIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; - - reprojectionFound = 1.0; - } - - prevNormal = BilinearWithBinaryWeightsImmediateFloat3( - prevNormal00, prevNormal10, prevNormal01, prevNormal11, - bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - historyLength = 255.0 * BilinearWithBinaryWeightsFloat(gPrevDiffuseHistoryLength, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - footprintQuality = interpolatedBinaryWeight; - } - return reprojectionFound; -} - -// -// Main -// -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Calculating checkerboard fields - bool diffHasData = true; - uint2 checkerboardPixelPos = ipos.xx; - uint checkerboard = STL::Sequence::CheckerBoard(ipos, gFrameIndex); - - if (gDiffCheckerboard != 2) - { - diffHasData = checkerboard == gDiffCheckerboard; - checkerboardPixelPos.x >>= 1; - } - - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 normalRoughness = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy) + gRectOrigin]); - } - sharedNormalRoughness[oy][ox] = normalRoughness; - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - normalRoughness = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy) + gRectOrigin]); - } - sharedNormalRoughness[oy][ox] = normalRoughness; - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - // Center data - float3 diffuseIllumination = gDiffuseIllumination[ipos.xy + gRectOrigin].rgb; - - // Reading current GBuffer data and center/left/right viewZ - float3 currentNormal = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; - float currentLinearZ = gViewZ[ipos.xy + gRectOrigin]; - - // Early out if linearZ is beyond denoising range - [branch] - if (currentLinearZ > gDenoisingRange) - { - return; - } - - // Calculating average normal in 3x3 area around current pixel - float3 currentNormalAveraged = currentNormal; - - [unroll] - for (int i = -1; i <= 1; i++) - { - [unroll] - for (int j = -1; j <= 1; j++) - { - // Skipping center pixel - if ((i == 0) && (j == 0)) continue; - - int2 p = ipos + int2(i, j); - float3 pNormal = sharedNormalRoughness[sharedMemoryIndex.y + j][sharedMemoryIndex.x + i].xyz; - - currentNormalAveraged += pNormal; - } - } - currentNormalAveraged /= 9.0; - - // Computing 2nd moments of luminance - float diffuse1stMoment = STL::Color::Luminance(diffuseIllumination.rgb); - float diffuse2ndMoment = diffuse1stMoment * diffuse1stMoment; - - // Getting current frame worldspace position for current pixel - float3 currentWorldPos = GetCurrentWorldPos(ipos, currentLinearZ); - - // Reading motion vector - float3 motionVector = gMotion[gRectOrigin + ipos].xyz * gMotionVectorScale.xyy; - - // Loading previous data based on surface motion vectors - float4 prevDiffuseIlluminationAnd2ndMomentSMB; - float3 prevDiffuseIlluminationAnd2ndMomentSMBResponsive; - float3 prevNormalSMB; - float historyLength; - float footprintQuality; - - float surfaceMotionBasedReprojectionFound = loadSurfaceMotionBasedPrevData( - ipos, - currentWorldPos, - normalize(currentNormalAveraged), - currentLinearZ, - motionVector, - prevDiffuseIlluminationAnd2ndMomentSMB, - prevDiffuseIlluminationAnd2ndMomentSMBResponsive, - prevNormalSMB, - historyLength, - footprintQuality - ); - - // History length is based on surface motion based disocclusion - historyLength = historyLength + 1.0; - historyLength = min(100.0, historyLength); - - // Minimize "getting stuck in history" effect when only fraction of bilinear footprint is valid - // by shortening the history length - if (footprintQuality < 1.0) - { - historyLength *= sqrt(footprintQuality); - historyLength = max(historyLength, 1.0); - } - - // Handling history reset if needed - if (gResetHistory != 0) historyLength = 1.0; - - // DIFFUSE ACCUMULATION BELOW - // - // Temporal accumulation of diffuse illumination - float diffMaxAccumulatedFrameNum = gDiffuseMaxAccumulatedFrameNum; - float diffMaxFastAccumulatedFrameNum = gDiffuseMaxFastAccumulatedFrameNum; - - if (gRejectDiffuseHistoryNormalThreshold > 0) - { - float NDotPrevN = saturate(dot(currentNormal, prevNormalSMB)); - float diffuseNormalWeight = 0.5 + 0.5 * (NDotPrevN > (1.0 - gRejectDiffuseHistoryNormalThreshold) ? 1.0 : 0.0); - diffMaxAccumulatedFrameNum *= diffuseNormalWeight; - diffMaxFastAccumulatedFrameNum *= diffuseNormalWeight; - } - - if (gUseConfidenceInputs) - { - float inDiffConfidence = gDiffConfidence[ipos]; - diffMaxAccumulatedFrameNum *= inDiffConfidence; - diffMaxFastAccumulatedFrameNum *= inDiffConfidence; - } - - float diffuseAlpha = (surfaceMotionBasedReprojectionFound > 0) ? max(1.0 / (diffMaxAccumulatedFrameNum + 1.0), 1.0 / historyLength) : 1.0; - float diffuseAlphaResponsive = (surfaceMotionBasedReprojectionFound > 0) ? max(1.0 / (diffMaxFastAccumulatedFrameNum + 1.0), 1.0 / historyLength) : 1.0; - - if ((!diffHasData) && (historyLength > 1.0)) - { - // Adjusting diffuse accumulation weights for checkerboard - diffuseAlpha *= 1.0 - gCheckerboardResolveAccumSpeed; - diffuseAlphaResponsive *= 1.0 - gCheckerboardResolveAccumSpeed; - } - - float4 accumulatedDiffuseIlluminationAnd2ndMoment = lerp(prevDiffuseIlluminationAnd2ndMomentSMB, float4(diffuseIllumination.rgb, diffuse2ndMoment), diffuseAlpha); - float3 accumulatedDiffuseIlluminationResponsive = lerp(prevDiffuseIlluminationAnd2ndMomentSMBResponsive.rgb, diffuseIllumination.rgb, diffuseAlphaResponsive); - - // Write out the diffuse results - gOutDiffuseIllumination[ipos] = accumulatedDiffuseIlluminationAnd2ndMoment; - gOutDiffuseIlluminationResponsive[ipos] = float4(accumulatedDiffuseIlluminationResponsive, 0); - - gOutDiffuseHistoryLength[ipos] = historyLength / 255.0; -} diff --git a/Source/Shaders/RELAX_Diffuse_SpatialVarianceEstimation.cs.hlsl b/Source/Shaders/RELAX_Diffuse_SpatialVarianceEstimation.cs.hlsl deleted file mode 100644 index 88c245c..0000000 --- a/Source/Shaders/RELAX_Diffuse_SpatialVarianceEstimation.cs.hlsl +++ /dev/null @@ -1,195 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Diffuse_SpatialVarianceEstimation.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 2 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedDiffuseAnd2ndMoment[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalViewZ[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -float computeDepthWeight(float depthCenter, float depthP, float depthThreshold) -{ - return 1; -} - -float computeNormalWeight(float3 normalCenter, float3 normalP, float phiNormal) -{ - return phiNormal == 0.0f ? 1.0f : pow(saturate(dot(normalCenter, normalP)), phiNormal); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - const int2 ipos = dispatchThreadId.xy; - - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - int ox = newIdxX; - int oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 diffuse = 0; - float3 normal = 0; - float viewZ = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - diffuse = gDiffuseIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZ[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedDiffuseAnd2ndMoment[oy][ox] = diffuse; - sharedNormalViewZ[oy][ox] = float4(normal, viewZ); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - diffuse = 0; - normal = 0; - viewZ = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - diffuse = gDiffuseIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZ[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedDiffuseAnd2ndMoment[oy][ox] = diffuse; - sharedNormalViewZ[oy][ox] = float4(normal, viewZ); - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // - // Shared memory is populated now and can be used for filtering - // - - int2 sharedMemoryCenterIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - // Repacking normal and roughness to prev normal roughness to be used in the next frame - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos]); - gOutNormalRoughness[ipos] = PackPrevNormalRoughness(normalRoughness); - - // Using diffuse history length for spatial variance estimation - float historyLength = 255.0 * gHistoryLength[ipos]; - - float4 centerDiffuseAnd2ndMoment = sharedDiffuseAnd2ndMoment[sharedMemoryCenterIndex.y][sharedMemoryCenterIndex.x]; - float3 centerDiffuseIllumination = centerDiffuseAnd2ndMoment.rgb; - float centerDiffuse1stMoment = STL::Color::Luminance(centerDiffuseIllumination); - float centerDiffuse2ndMoment = centerDiffuseAnd2ndMoment.a; - - [branch] - if (historyLength >= float(gHistoryThreshold)) - { - // If we have enough temporal history available, - // we pass illumination data unmodified - // and calculate variance based on temporally accumulated moments - float diffuseVariance = centerDiffuse2ndMoment - centerDiffuse1stMoment * centerDiffuse1stMoment; - - gOutDiffuseIlluminationAndVariance[ipos] = float4(centerDiffuseIllumination, diffuseVariance); - return; - } - - float4 centerNormalViewZ = sharedNormalViewZ[sharedMemoryCenterIndex.y][sharedMemoryCenterIndex.x]; - float3 centerNormal = centerNormalViewZ.xyz; - float centerViewZ = centerNormalViewZ.a; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float sumWDiffuseIllumination = 0; - float3 sumDiffuseIllumination = 0; - - float sumDiffuse1stMoment = 0; - float sumDiffuse2ndMoment = 0; - - // Compute first and second moment spatially. This code also applies cross-bilateral - // filtering on the input illumination. - [unroll] - for (int cy = -2; cy <= 2; cy++) - { - [unroll] - for (int cx = -2; cx <= 2; cx++) - { - int2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT + cx, SKIRT + cy); - - // Fetching sample data - float3 sampleNormal = sharedNormalViewZ[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; - - float4 sampleDiffuse = sharedDiffuseAnd2ndMoment[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float3 sampleDiffuseIllumination = sampleDiffuse.rgb; - float sampleDiffuse1stMoment = STL::Color::Luminance(sampleDiffuseIllumination); - float sampleDiffuse2ndMoment = sampleDiffuse.a; - - - // Calculating weights - float depthW = 1.0;// TODO: should we take in account depth here? - float normalW = computeNormalWeight(centerNormal, sampleNormal, gPhiNormal); - float diffuseW = normalW * depthW; - - // Accumulating - sumWDiffuseIllumination += diffuseW; - sumDiffuseIllumination += sampleDiffuseIllumination.rgb * diffuseW; - sumDiffuse1stMoment += sampleDiffuse1stMoment * diffuseW; - sumDiffuse2ndMoment += sampleDiffuse2ndMoment * diffuseW; - } - } - - // Clamp sum to >0 to avoid NaNs. - sumWDiffuseIllumination = max(sumWDiffuseIllumination, 1e-6f); - - sumDiffuseIllumination /= sumWDiffuseIllumination; - sumDiffuse1stMoment /= sumWDiffuseIllumination; - sumDiffuse2ndMoment /= sumWDiffuseIllumination; - - // compute variance using the first and second moments - float diffuseVariance = abs(sumDiffuse2ndMoment - sumDiffuse1stMoment * sumDiffuse1stMoment); - - // give the variance a boost for the first frames - float boost = max(1.0, 4.0 / (historyLength + 1.0)); - diffuseVariance *= boost; - - gOutDiffuseIlluminationAndVariance[ipos] = float4(sumDiffuseIllumination, diffuseVariance); -} diff --git a/Source/Shaders/RELAX_Specular/RELAX_Specular_ATrousShmem.cs.hlsl b/Source/Shaders/RELAX_Specular/RELAX_Specular_ATrousShmem.cs.hlsl new file mode 100644 index 0000000..f6b5fef --- /dev/null +++ b/Source/Shaders/RELAX_Specular/RELAX_Specular_ATrousShmem.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_SPECULAR + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousShmem.hlsli" diff --git a/Source/Shaders/RELAX_Specular/RELAX_Specular_ATrousStandard.cs.hlsl b/Source/Shaders/RELAX_Specular/RELAX_Specular_ATrousStandard.cs.hlsl new file mode 100644 index 0000000..be4f692 --- /dev/null +++ b/Source/Shaders/RELAX_Specular/RELAX_Specular_ATrousStandard.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_SPECULAR + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_ATrousStandard.hlsli" diff --git a/Source/Shaders/RELAX_Specular/RELAX_Specular_DisocclusionFix.cs.hlsl b/Source/Shaders/RELAX_Specular/RELAX_Specular_DisocclusionFix.cs.hlsl new file mode 100644 index 0000000..f739332 --- /dev/null +++ b/Source/Shaders/RELAX_Specular/RELAX_Specular_DisocclusionFix.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_SPECULAR + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_DisocclusionFix.hlsli" diff --git a/Source/Shaders/RELAX_Specular/RELAX_Specular_Firefly.cs.hlsl b/Source/Shaders/RELAX_Specular/RELAX_Specular_Firefly.cs.hlsl new file mode 100644 index 0000000..0e2e84e --- /dev/null +++ b/Source/Shaders/RELAX_Specular/RELAX_Specular_Firefly.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_SPECULAR + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Firefly.hlsli" diff --git a/Source/Shaders/RELAX_Specular/RELAX_Specular_HistoryClamping.cs.hlsl b/Source/Shaders/RELAX_Specular/RELAX_Specular_HistoryClamping.cs.hlsl new file mode 100644 index 0000000..7ffb14e --- /dev/null +++ b/Source/Shaders/RELAX_Specular/RELAX_Specular_HistoryClamping.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_SPECULAR + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_HistoryClamping.hlsli" diff --git a/Source/Shaders/RELAX_Specular/RELAX_Specular_Prepass.cs.hlsl b/Source/Shaders/RELAX_Specular/RELAX_Specular_Prepass.cs.hlsl new file mode 100644 index 0000000..96c53e4 --- /dev/null +++ b/Source/Shaders/RELAX_Specular/RELAX_Specular_Prepass.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_SPECULAR + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Prepass.hlsli" diff --git a/Source/Shaders/RELAX_Specular/RELAX_Specular_Reproject.cs.hlsl b/Source/Shaders/RELAX_Specular/RELAX_Specular_Reproject.cs.hlsl new file mode 100644 index 0000000..d6b3887 --- /dev/null +++ b/Source/Shaders/RELAX_Specular/RELAX_Specular_Reproject.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_SPECULAR + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_Reproject.hlsli" diff --git a/Source/Shaders/RELAX_Specular/RELAX_Specular_SplitScreen.cs.hlsl b/Source/Shaders/RELAX_Specular/RELAX_Specular_SplitScreen.cs.hlsl new file mode 100644 index 0000000..d460e1e --- /dev/null +++ b/Source/Shaders/RELAX_Specular/RELAX_Specular_SplitScreen.cs.hlsl @@ -0,0 +1,13 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#define RELAX_SPECULAR + +#include "RELAX_DiffuseSpecular/RELAX_DiffuseSpecular_SplitScreen.hlsli" diff --git a/Source/Shaders/RELAX_Specular_ATrousShmem.cs.hlsl b/Source/Shaders/RELAX_Specular_ATrousShmem.cs.hlsl deleted file mode 100644 index 03a2742..0000000 --- a/Source/Shaders/RELAX_Specular_ATrousShmem.cs.hlsl +++ /dev/null @@ -1,281 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_ATrousShmem.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 8 -#define SKIRT 1 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedSpecularIlluminationAndVariance[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalRoughness[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedWorldPos[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING -groupshared uint sharedMaterialType[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -#endif - -// Helper functions -float2 getRoughnessWeightParams(float roughness0, float specularReprojectionConfidence) -{ - float a = 1.0 / (0.001 + 0.999 * roughness0 * (0.333 + gRoughnessEdgeStoppingRelaxation * (1.0 - specularReprojectionConfidence))); - float b = roughness0 * a; - return float2(a, b); -} - -float getRoughnessWeight(float2 params0, float roughness) -{ - return saturate(1.0 - abs(params0.y - roughness * params0.x)); -} - -// computes a 3x3 gaussian blur of the variance, centered around -// the current pixel -void computeVariance(int2 groupThreadId, out float specularVariance) -{ - float specularSum = 0; - float diffuseSum = 0; - - static const float kernel[2][2] = - { - { 1.0 / 4.0, 1.0 / 8.0 }, - { 1.0 / 8.0, 1.0 / 16.0 } - }; - - const int radius = 1; - for (int yy = -radius; yy <= radius; yy++) - { - for (int xx = -radius; xx <= radius; xx++) - { - int2 sharedMemoryIndex = groupThreadId.xy + int2(1 + xx, 1 + yy); - float4 specularIlluminationAndVariance = sharedSpecularIlluminationAndVariance[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float k = kernel[abs(xx)][abs(yy)]; - specularSum += specularIlluminationAndVariance.a * k; - } - } - specularVariance = specularSum; -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory - // - // Renumerating threads to load 18x18 (16+2 x 16+2) block of data to shared memory - // - // The preloading will be done in two stages: - // at the first stage the group will load 16x16 / 18 = 14.2 rows of the shared memory, - // and all threads in the group will be following the same path. - // At the second stage, the rest 18x18 - 16x16 = 68 threads = 2.125 warps will load the rest of data - - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - int ox = newIdxX; - int oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 specularIlluminationAndVariance = 0; - float3 normal = 0; - float roughness = 1.0; - float4 worldPos = 0; - float viewZ = 0.0; - uint materialType = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gResourceSize.x) && (yy < (int)gResourceSize.y)) - { - specularIlluminationAndVariance = gSpecularIlluminationAndVariance[int2(xx, yy)]; - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)], materialType); - normal = normalRoughness.rgb; - roughness = normalRoughness.a; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - worldPos = float4(GetCurrentWorldPos(int2(xx, yy), viewZ), viewZ); - } - sharedSpecularIlluminationAndVariance[oy][ox] = specularIlluminationAndVariance; - sharedNormalRoughness[oy][ox] = float4(normal, roughness); - sharedWorldPos[oy][ox] = worldPos; -#if (NRD_USE_MATERIAL_ID_AWARE_FILTERING == 1) - sharedMaterialType[oy][ox] = materialType; -#endif - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - specularIlluminationAndVariance = 0; - normal = 0; - roughness = 1.0; - worldPos = 0; - viewZ = 0.0; - materialType = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gResourceSize.x) && (yy < (int)gResourceSize.y)) - { - specularIlluminationAndVariance = gSpecularIlluminationAndVariance[int2(xx, yy)]; - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)], materialType); - normal = normalRoughness.rgb; - roughness = normalRoughness.a; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - worldPos = float4(GetCurrentWorldPos(int2(xx, yy), viewZ), viewZ); - } - sharedSpecularIlluminationAndVariance[oy][ox] = specularIlluminationAndVariance; - sharedNormalRoughness[oy][ox] = float4(normal, roughness); - sharedWorldPos[oy][ox] = worldPos; -#if (NRD_USE_MATERIAL_ID_AWARE_FILTERING == 1) - sharedMaterialType[oy][ox] = materialType; -#endif - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // - // Shared memory is populated now and can be used for filtering - // - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - // Fetching center data - float4 centerWorldPosAndViewZ = sharedWorldPos[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float3 centerWorldPos = centerWorldPosAndViewZ.xyz; - float centerViewZ = centerWorldPosAndViewZ.w; - float3 centerV = normalize(centerWorldPos); - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float3 centerNormal = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; - float specularReprojectionConfidence = gSpecularReprojectionConfidence[ipos]; - - float4 centerSpecularIlluminationAndVariance = sharedSpecularIlluminationAndVariance[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - - // Calculating center luminance - float centerSpecularLuminance = STL::Color::Luminance(centerSpecularIlluminationAndVariance.rgb); - - // Center roughness - float centerRoughness = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x].a; - float2 roughnessWeightParams = getRoughnessWeightParams(centerRoughness, specularReprojectionConfidence); - - float2 normalWeightParams = GetNormalWeightParams_ATrous(centerRoughness, 255.0 * gHistoryLength[ipos], specularReprojectionConfidence, gNormalEdgeStoppingRelaxation, gSpecularLobeAngleFraction); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - uint centerMaterialType = sharedMaterialType[sharedMemoryIndex.y][sharedMemoryIndex.x]; -#endif - - // Calculating variance, filtered using 3x3 gaussin blur - float centerSpecularVar; - computeVariance(groupThreadId.xy, centerSpecularVar); - - float specularPhiLIllumination = 1.0e-4 + gSpecularPhiLuminance * sqrt(max(0.0, centerSpecularVar)); - float depthThreshold = gDepthThreshold; - - float sumWSpecular = 0; - float4 sumSpecularIlluminationAndVariance = 0; - - static const float kernelWeightGaussian3x3[2] = { 0.44198, 0.27901 }; - - [unroll] - for (int cy = -1; cy <= 1; cy++) - { - [unroll] - for (int cx = -1; cx <= 1; cx++) - { - const float kernel = kernelWeightGaussian3x3[abs(cx)] * kernelWeightGaussian3x3[abs(cy)]; - const int2 p = ipos + int2(cx, cy); - const bool isInside = all(p >= int2(0, 0)) && all(p < int2(gResourceSize)); - const bool isCenter = ((cx == 0) && (cy == 0)); - - int2 sampleSharedMemoryIndex = groupThreadId.xy + int2(SKIRT + cx, SKIRT + cy); - - float4 sampleNormalRoughness = sharedNormalRoughness[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; - float3 sampleNormal = sampleNormalRoughness.rgb; - float sampleRoughness = sampleNormalRoughness.a; - float3 sampleWorldPos = sharedWorldPos[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x].rgb; - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - uint sampleMaterialType = sharedMaterialType[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; -#endif - - float4 sampleSpecularIlluminationAndVariance = sharedSpecularIlluminationAndVariance[sampleSharedMemoryIndex.y][sampleSharedMemoryIndex.x]; - - float sampleSpecularLuminance = STL::Color::Luminance(sampleSpecularIlluminationAndVariance.rgb); - - // Calculating geometry and normal weights - float geometryW = GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - depthThreshold); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - geometryW *= (sampleMaterialType == centerMaterialType) ? 1.0 : 0.0; -#endif - - float normalWSpecular = GetSpecularNormalWeight_ATrous(normalWeightParams, gSpecularLobeAngleSlack, centerNormal, sampleNormal); - float normalWDiffuse = GetDiffuseNormalWeight_ATrous(centerNormal, sampleNormal, gPhiNormal); - - // Calculating luminande weigths - float specularLuminanceW = abs(centerSpecularLuminance - sampleSpecularLuminance) / specularPhiLIllumination; - float relaxation = lerp(1.0, specularReprojectionConfidence, gLuminanceEdgeStoppingRelaxation); - specularLuminanceW *= relaxation; - specularLuminanceW = min(gMaxLuminanceRelativeDifference, specularLuminanceW); - - // Roughness weight for specular - float specularRoughnessW = getRoughnessWeight(roughnessWeightParams, sampleRoughness); - - float wSpecular = kernel; - if (!isCenter) - { - // Calculating bilateral weight for specular - wSpecular = geometryW * exp_approx(-specularLuminanceW); - wSpecular *= gRoughnessEdgeStoppingEnabled ? (normalWSpecular * specularRoughnessW) : normalWDiffuse; - wSpecular = kernel * max(1e-6, wSpecular); - } - - // Discarding out of screen samples - wSpecular *= isInside ? 1.0 : 0.0; - - // alpha channel contains the variance, therefore the weights need to be squared - sumWSpecular += wSpecular; - sumSpecularIlluminationAndVariance += float4(wSpecular.xxx, wSpecular * wSpecular) * sampleSpecularIlluminationAndVariance; - } - } - - float4 filteredSpecularIlluminationAndVariance = float4(sumSpecularIlluminationAndVariance / float4(sumWSpecular.xxx, sumWSpecular * sumWSpecular)); - - gOutSpecularIlluminationAndVariance[ipos] = filteredSpecularIlluminationAndVariance; -} diff --git a/Source/Shaders/RELAX_Specular_ATrousStandard.cs.hlsl b/Source/Shaders/RELAX_Specular_ATrousStandard.cs.hlsl deleted file mode 100644 index cf023c7..0000000 --- a/Source/Shaders/RELAX_Specular_ATrousStandard.cs.hlsl +++ /dev/null @@ -1,162 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_ATrousStandard.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -// Helper functions -float3 getCurrentWorldPos(int2 pixelPos, float viewZ) -{ - float2 uv = ((float2)pixelPos + float2(0.5, 0.5)) * gInvRectSize * 2.0 - 1.0; - return viewZ * (gFrustumForward.xyz + gFrustumRight.xyz * uv.x - gFrustumUp.xyz * uv.y); -} - -float2 getRoughnessWeightParams(float roughness0, float specularReprojectionConfidence) -{ - float a = 1.0 / (0.001 + 0.999 * roughness0 * (0.333 + gRoughnessEdgeStoppingRelaxation * (1.0 - specularReprojectionConfidence))); - float b = roughness0 * a; - return float2(a, b); -} - -float getRoughnessWeight(float2 params0, float roughness) -{ - return saturate(1.0 - abs(params0.y - roughness * params0.x)); -} - -[numthreads(16, 16, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId) -{ - uint centerMaterialType; - float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos], centerMaterialType); - float3 centerNormal = centerNormalRoughness.rgb; - float centerRoughness = centerNormalRoughness.a; - - float centerViewZ = gViewZFP16[ipos] / NRD_FP16_VIEWZ_SCALE; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { -#if( RELAX_BLACK_OUT_INF_PIXELS == 1 ) - gOutSpecularIlluminationAndVariance[ipos] = 0; -#endif - return; - } - - float4 centerSpecularIlluminationAndVariance = gSpecularIlluminationAndVariance[ipos]; - float centerSpecularLuminance = STL::Color::Luminance(centerSpecularIlluminationAndVariance.rgb); - float specularReprojectionConfidence = gSpecularReprojectionConfidence[ipos]; - - float specularLuminanceWeightRelaxation = 1.0; - if (gStepSize <= 4) - { - specularLuminanceWeightRelaxation = lerp(1.0, specularReprojectionConfidence, gLuminanceEdgeStoppingRelaxation); - } - - // Variance, NOT filtered using 3x3 gaussin blur, as we don't need this in other than 1st Atrous pass - float centerSpecularVar = centerSpecularIlluminationAndVariance.a; - - float2 roughnessWeightParams = getRoughnessWeightParams(centerRoughness, specularReprojectionConfidence); - float2 normalWeightParams = GetNormalWeightParams_ATrous(centerRoughness, 255.0 * gHistoryLength[ipos], specularReprojectionConfidence, gNormalEdgeStoppingRelaxation, gSpecularLobeAngleFraction); - - float3 centerWorldPos = getCurrentWorldPos(ipos, centerViewZ); - float3 centerV = normalize(centerWorldPos); - - float specularPhiLIllumination = 1.0e-4 + gSpecularPhiLuminance * sqrt(max(0.0, centerSpecularVar)); - float depthThreshold = gDepthThreshold; - - static const float kernelWeightGaussian3x3[2] = { 0.44198, 0.27901 }; - - float sumWSpecular = 0.44198 * 0.44198; - float4 sumSpecularIlluminationAndVariance = centerSpecularIlluminationAndVariance * float4(sumWSpecular.xxx, sumWSpecular * sumWSpecular); - - // Adding random offsets to minimize "ringing" at large A-Trous steps - uint2 offset = 0; - if (gStepSize > 4) - { - STL::Rng::Initialize(ipos, gFrameIndex); - offset = int2(gStepSize.xx * 0.5 * (STL::Rng::GetFloat2() - 0.5)); - } - - [unroll] - for (int yy = -1; yy <= 1; yy++) - { - [unroll] - for (int xx = -1; xx <= 1; xx++) - { - int2 p = ipos + offset + int2(xx, yy) * gStepSize; - bool isInside = all(p >= int2(0, 0)) && all(p < int2(gRectSize)); - bool isCenter = ((xx == 0) && (yy == 0)); - if (isCenter) continue; - - float kernel = kernelWeightGaussian3x3[abs(xx)] * kernelWeightGaussian3x3[abs(yy)]; - - // Discarding out of screen samples - float wSpecular = isInside ? kernel : 0.0; - - // Fetching normal, roughness, linear Z - uint sampleMaterialType; - float4 sampleNormalRoughnes = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[p], sampleMaterialType); - float3 sampleNormal = sampleNormalRoughnes.rgb; - float sampleRoughness = sampleNormalRoughnes.a; - float sampleViewZ = gViewZFP16[p] / NRD_FP16_VIEWZ_SCALE; - - // Calculating sample world position - float3 sampleWorldPos = getCurrentWorldPos(p, sampleViewZ); - - // Calculating geometry weight for diffuse and specular - float geometryW = GetPlaneDistanceWeight(centerWorldPos, centerNormal, centerViewZ, sampleWorldPos, depthThreshold); - -#if NRD_USE_MATERIAL_ID_AWARE_FILTERING - geometryW *= (sampleMaterialType == centerMaterialType) ? 1.0 : 0.0; -#endif - - // Calculating normal weights for diffuse and specular - float normalWSpecular = GetSpecularNormalWeight_ATrous(normalWeightParams, gSpecularLobeAngleSlack, centerNormal, sampleNormal); - float normalWDiffuse = GetDiffuseNormalWeight_ATrous(centerNormal, sampleNormal, gPhiNormal); - - // Calculating roughness weight for specular - float roughnessWSpecular = getRoughnessWeight(roughnessWeightParams, sampleRoughness); - - // Applying all the weights except luminance weights - wSpecular *= geometryW * (gRoughnessEdgeStoppingEnabled ? (normalWSpecular * roughnessWSpecular) : normalWDiffuse); - - // Summing up specular - if (wSpecular > 1e-4) - { - float4 sampleSpecularIlluminationAndVariance = gSpecularIlluminationAndVariance[p]; - float sampleSpecularLuminance = STL::Color::Luminance(sampleSpecularIlluminationAndVariance.rgb); - - float specularLuminanceW = abs(centerSpecularLuminance - sampleSpecularLuminance) / specularPhiLIllumination; - // Adjusting specular weight to allow more blur for pixels with low reprojection confidence value - specularLuminanceW *= specularLuminanceWeightRelaxation; - specularLuminanceW = min(gMaxLuminanceRelativeDifference, specularLuminanceW); - - wSpecular *= exp_approx(-specularLuminanceW); - sumSpecularIlluminationAndVariance += float4(wSpecular.xxx, wSpecular * wSpecular) * sampleSpecularIlluminationAndVariance; - sumWSpecular += wSpecular; - } - } - } - - float4 filteredSpecularIlluminationAndVariance = float4(sumSpecularIlluminationAndVariance / float4(sumWSpecular.xxx, sumWSpecular * sumWSpecular)); - - gOutSpecularIlluminationAndVariance[ipos] = filteredSpecularIlluminationAndVariance; -} diff --git a/Source/Shaders/RELAX_Specular_DisocclusionFix.cs.hlsl b/Source/Shaders/RELAX_Specular_DisocclusionFix.cs.hlsl deleted file mode 100644 index 09fa296..0000000 --- a/Source/Shaders/RELAX_Specular_DisocclusionFix.cs.hlsl +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_DisocclusionFix.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -// Helper functions -float GetRadius(float numFramesInHistory) -{ - return gMaxRadius / (numFramesInHistory + 1.0); -} - -float getSpecularLobeHalfAngle(float roughness) -{ - // Defines a cone angle, where micro-normals are distributed - float r2 = roughness * roughness; - float r3 = roughness * r2; - return 3.141592 * r2 / (1.0 + 0.5 * r2 + r3); -} - -float2 getNormalWeightParams(float roughness, float numFramesInHistory) -{ - // This is the main parameter - cone angle - float angle = 0.33 * getSpecularLobeHalfAngle(roughness); - return float2(angle, 1.0); -} - -float getSpecularRWeight(float2 params0, float3 v0, float3 v) -{ - float cosa = saturate(dot(v0, v)); - float a = STL::Math::AcosApprox(cosa); - a = 1.0 - STL::Math::SmoothStep(0.0, params0.x, a); - return saturate(1.0 + (a - 1.0) * params0.y); -} - -// -// Main -// - -[numthreads(8, 8, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId) -{ - const int2 ipos = int2(dispatchThreadId.xy); - - float centerViewZ = gViewZFP16[ipos] / NRD_FP16_VIEWZ_SCALE; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float historyLength = 255.0 * gSpecularHistoryLength[ipos]; - float4 specularIlluminationAnd2ndMoment = gSpecularIllumination[ipos]; - float4 specularIlluminationResponsive = gSpecularIlluminationResponsive[ipos]; - - // Pass through the input data if no disocclusion detected - [branch] - if (historyLength > gFramesToFix) - { - gOutSpecularIllumination[ipos] = specularIlluminationAnd2ndMoment; - gOutSpecularIlluminationResponsive[ipos] = specularIlluminationResponsive; - return; - } - - // Unpacking the rest of center data - float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos]); - float3 centerNormal = centerNormalRoughness.rgb; - float centerRoughness = centerNormalRoughness.a; - float3 centerWorldPos = GetCurrentWorldPos(ipos, centerViewZ); - float3 centerV = normalize(centerWorldPos); - float3 centerR = reflect(centerV, centerNormal); - float2 normalWeightParams = getNormalWeightParams(centerRoughness, historyLength); - - // Running sparse cross-bilateral filter - float4 specularIlluminationAnd2ndMomentSum = specularIlluminationAnd2ndMoment; - - float specularWSum = 1; - - float r = GetRadius(historyLength); - - [unroll] - for (int j = -2; j <= 2; j++) - [unroll] - for (int i = -2; i <= 2; i++) - { - int dx = (int)(i * r); - int dy = (int)(j * r); - - int2 samplePosInt = (int2)ipos + int2(dx, dy); - - bool isInside = all(samplePosInt >= int2(0, 0)) && all(samplePosInt < int2(gRectSize)); - if ((i == 0) && (j == 0)) continue; - - float3 sampleNormal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[samplePosInt]).rgb; - - float sampleViewZ = gViewZFP16[samplePosInt] / NRD_FP16_VIEWZ_SCALE; - - // Edge stopping functions: - // ..geometry - float3 sampleWorldPos = GetCurrentWorldPos(samplePosInt, sampleViewZ); - float geometryWeight = GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - gDepthThreshold); - - float specularW = geometryWeight; - - // ..specular lobe - float3 sampleV = normalize(sampleWorldPos); - float3 sampleR = reflect(sampleV, sampleNormal); - specularW *= getSpecularRWeight(normalWeightParams, sampleR, centerR); - specularW *= isInside ? 1.0 : 0; - - // Summing up specular result - if (specularW > 1e-4) - { - float4 sampleSpecularIlluminationAnd2ndMoment = gSpecularIllumination[samplePosInt]; - specularIlluminationAnd2ndMomentSum += sampleSpecularIlluminationAnd2ndMoment * specularW; - specularWSum += specularW; - } - } - - float4 outSpecularIlluminationAnd2ndMoment = specularIlluminationAnd2ndMomentSum / specularWSum; - - // Writing out the results - gOutSpecularIllumination[ipos] = outSpecularIlluminationAnd2ndMoment; - gOutSpecularIlluminationResponsive[ipos] = outSpecularIlluminationAnd2ndMoment; -} diff --git a/Source/Shaders/RELAX_Specular_Firefly.cs.hlsl b/Source/Shaders/RELAX_Specular_Firefly.cs.hlsl deleted file mode 100644 index 98f1598..0000000 --- a/Source/Shaders/RELAX_Specular_Firefly.cs.hlsl +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_Firefly.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 1 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedSpecularIllumination[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalAndViewZ[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -// Helper functions - -float edgeStoppingDepth(float centerViewZ, float sampleViewZ) -{ - return (abs(centerViewZ - sampleViewZ) / (centerViewZ + 1e-6)) < 0.1 ? 1.0 : 0.0; -} - -void PopulateSharedMemoryForFirefly(uint2 dispatchThreadId, uint2 groupThreadId, uint2 groupId) -{ - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 specularIllumination = 0; - float3 normal = 0; - float viewZ = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specularIllumination = gSpecularIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedSpecularIllumination[oy][ox] = specularIllumination; - sharedNormalAndViewZ[oy][ox] = float4(normal, viewZ); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - specularIllumination = 0; - normal = 0; - viewZ = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specularIllumination = gSpecularIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZFP16[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedSpecularIllumination[oy][ox] = specularIllumination; - sharedNormalAndViewZ[oy][ox] = float4(normal, viewZ); - } -} - -// Cross bilateral Rank-Conditioned Rank-Selection (RCRS) filter -void runRCRS(int2 dispatchThreadId, int2 groupThreadId, float3 centerNormal, float centerViewZ, out float4 outSpecular) -{ - // Fetching center data - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - float4 s = sharedSpecularIllumination[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - float3 specularIlluminationCenter = s.rgb; - float specular2ndMomentCenter = s.a; - - float specularLuminanceCenter = STL::Color::Luminance(specularIlluminationCenter); - - // Finding max and min luminance in neighborhood, rejecting samples that don't belong to center pixel's surface - float maxSpecularLuminance = -1.0; - float minSpecularLuminance = 1.0e6; - int2 maxSpecularLuminanceCoords = sharedMemoryIndex; - int2 minSpecularLuminanceCoords = sharedMemoryIndex; - - [unroll] - for (int yy = -1; yy <= 1; yy++) - { - [unroll] - for (int xx = -1; xx <= 1; xx++) - { - int2 p = dispatchThreadId.xy + int2(xx, yy); - int2 sharedMemoryIndexSample = groupThreadId.xy + int2(SKIRT, SKIRT) + int2(xx, yy); - - if ((xx == 0) && (yy == 0)) continue; - if (any(p < int2(0, 0)) || any(p >= int2(gRectSize))) continue; - - // Fetching sample data - float4 v = sharedNormalAndViewZ[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x]; - float3 sampleNormal = v.xyz; - float sampleViewZ = v.w; - - float3 specularIlluminationSample = sharedSpecularIllumination[sharedMemoryIndexSample.y][sharedMemoryIndexSample.x].rgb; - float specularLuminanceSample = STL::Color::Luminance(specularIlluminationSample); - - // Applying weights - // ..normal weight - float weight = dot(centerNormal, sampleNormal) > 0.99 ? 1.0 : 0.0; - - // ..depth weight - weight *= edgeStoppingDepth(centerViewZ, sampleViewZ); - - if (weight > 0) - { - if (specularLuminanceSample > maxSpecularLuminance) - { - maxSpecularLuminance = specularLuminanceSample; - maxSpecularLuminanceCoords = sharedMemoryIndexSample; - } - if (specularLuminanceSample < minSpecularLuminance) - { - minSpecularLuminance = specularLuminanceSample; - minSpecularLuminanceCoords = sharedMemoryIndexSample; - } - } - } - } - - // Replacing current value with min or max in the neighborhood if outside min..max range, - // or leaving sample as it is if it's within the range - int2 specularCoords = sharedMemoryIndex; - - if (specularLuminanceCenter > maxSpecularLuminance) - { - specularCoords = maxSpecularLuminanceCoords; - } - if (specularLuminanceCenter < minSpecularLuminance) - { - specularCoords = minSpecularLuminanceCoords; - } - - outSpecular = float4(sharedSpecularIllumination[specularCoords.y][specularCoords.x].rgb, specular2ndMomentCenter); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory for firefly filter - PopulateSharedMemoryForFirefly(dispatchThreadId.xy, groupThreadId.xy, groupId.xy); - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // Shared memory is populated now and can be used for filtering - float4 v = sharedNormalAndViewZ[groupThreadId.y + SKIRT][groupThreadId.x + SKIRT]; - float3 centerNormal = v.xyz; - float centerViewZ = v.w; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - // Running firefly filter - float4 outSpecularIlluminationAnd2ndMoment; - - runRCRS(dispatchThreadId.xy, groupThreadId.xy, centerNormal, centerViewZ, outSpecularIlluminationAnd2ndMoment); - - gOutSpecularIllumination[dispatchThreadId.xy] = outSpecularIlluminationAnd2ndMoment; -} - diff --git a/Source/Shaders/RELAX_Specular_HistoryClamping.cs.hlsl b/Source/Shaders/RELAX_Specular_HistoryClamping.cs.hlsl deleted file mode 100644 index e57969b..0000000 --- a/Source/Shaders/RELAX_Specular_HistoryClamping.cs.hlsl +++ /dev/null @@ -1,140 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_HistoryClamping.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 2 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float3 sharedSpecular[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -// Helper functions - -void runHistoryClamping(int2 pixelPos, int2 sharedMemoryIndex, float3 specular, out float3 outSpecular) -{ - - float3 specularYCoCg = STL::Color::LinearToYCoCg(specular); - - float3 specularFirstMoment = 0; - float3 specularSecondMoment = 0; - - [unroll] - for (int dy = -2; dy <= 2; dy++) - { - [unroll] - for (int dx = -2; dx <= 2; dx++) - { - uint2 sharedMemoryIndexP = sharedMemoryIndex + int2(dx, dy); - int2 p = pixelPos + int2(dx, dy); - if (any(p <= int2(0,0)) || any(p >= int2(gRectSize))) sharedMemoryIndexP = sharedMemoryIndex; - - float3 specularP = sharedSpecular[sharedMemoryIndexP.y][sharedMemoryIndexP.x]; - - specularFirstMoment += specularP; - specularSecondMoment += specularP * specularP; - } - } - - specularFirstMoment /= 25.0; - specularSecondMoment /= 25.0; - - // Calculating color boxes for specular signal - float3 specularSigma = sqrt(max(0.0f, specularSecondMoment - specularFirstMoment * specularFirstMoment)); - float3 specularColorMin = specularFirstMoment - gColorBoxSigmaScale * specularSigma; - float3 specularColorMax = specularFirstMoment + gColorBoxSigmaScale * specularSigma; - - // Expanding specular color boxes with color of the center pixel for specular signal - // to avoid introducing bias - float3 specularCenter = sharedSpecular[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - specularColorMin = min(specularColorMin, specularCenter); - specularColorMax = max(specularColorMax, specularCenter); - - // Color clamping - specularYCoCg = clamp(specularYCoCg, specularColorMin, specularColorMax); - outSpecular = STL::Color::YCoCgToLinear(specularYCoCg); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float3 specularResponsive = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specularResponsive = gSpecularResponsiveIllumination[int2(xx, yy)].rgb; - } - sharedSpecular[oy][ox] = STL::Color::LinearToYCoCg(specularResponsive); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - specularResponsive = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if (xx >= 0 && yy >= 0 && xx < (int)gRectSize.x && yy < (int)gRectSize.y) - { - specularResponsive = gSpecularResponsiveIllumination[int2(xx, yy)].rgb; - } - sharedSpecular[oy][ox] = STL::Color::LinearToYCoCg(specularResponsive); - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - // Shared memory is populated with responsive history now and can be used for history clamping - - // Reading normal history and history length - float4 specularAnd2ndMoment = gSpecularIllumination[dispatchThreadId.xy]; - - // Reading history length - float historyLength = gSpecularHistoryLength[dispatchThreadId.xy]; - - // Running history clamping - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - float3 clampedSpecular; - runHistoryClamping(dispatchThreadId.xy, sharedMemoryIndex, specularAnd2ndMoment.rgb, clampedSpecular); - - // Writing out the results - gOutSpecularIllumination[dispatchThreadId.xy] = float4(clampedSpecular, specularAnd2ndMoment.a); - gOutSpecularHistoryLength[dispatchThreadId.xy] = historyLength; -} diff --git a/Source/Shaders/RELAX_Specular_Prepass.cs.hlsl b/Source/Shaders/RELAX_Specular_Prepass.cs.hlsl deleted file mode 100644 index d7b5c41..0000000 --- a/Source/Shaders/RELAX_Specular_Prepass.cs.hlsl +++ /dev/null @@ -1,308 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_Prepass.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -#define POISSON_SAMPLE_NUM 8 -#define POISSON_SAMPLES g_Poisson8 - -#define THREAD_GROUP_SIZE 16 - -float GetNormHitDist(float hitDist, float viewZ, float4 hitDistParams = float4(3.0, 0.1, 10.0, -25.0), float linearRoughness = 1.0) -{ - float f = _REBLUR_GetHitDistanceNormalization(viewZ, hitDistParams, linearRoughness); - return saturate(hitDist / f); -} - -float GetSpecMagicCurve(float roughness, float power = 0.25) -{ - // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtMl4oLTE1LjAqeCkiLCJjb2xvciI6IiNGMjE4MTgifSx7InR5cGUiOjAsImVxIjoiKDEtMl4oLTIwMCp4KngpKSooeF4wLjI1KSIsImNvbG9yIjoiIzIyRUQxNyJ9LHsidHlwZSI6MCwiZXEiOiIoMS0yXigtMjAwKngqeCkpKih4XjAuNSkiLCJjb2xvciI6IiMxNzE2MTYifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMSIsIjAiLCIxLjEiXSwic2l6ZSI6WzEwMDAsNTAwXX1d - - float f = 1.0 - exp2(-200.0 * roughness * roughness); - f *= STL::Math::Pow01(roughness, power); - - return f; -} - -float GetBlurRadius(float radius, float roughness, float hitDist, float viewZ, float nonLinearAccumSpeed, float boost, float error, float radiusBias, float radiusScale) -{ - // Modify by hit distance - float hitDistFactor = hitDist / (hitDist + viewZ); - float s = hitDistFactor; - - // A non zero addition is needed to avoid under-blurring: - float addon = 9.0; - addon = min(addon, radius * 0.333); - addon *= hitDistFactor; - addon *= roughness; - - // Avoid over-blurring on contact - radiusBias *= lerp(roughness, 1.0, hitDistFactor); - - // Final blur radius - float r = s * radius + addon; - r = r * (radiusScale + radiusBias) + radiusBias; - r *= GetSpecMagicCurve(roughness); - - return r; -} - -float2x3 GetKernelBasis(float3 X, float3 N, float worldRadius, float roughness = 1.0, float anisoFade = 1.0) -{ - float3x3 basis = STL::Geometry::GetBasis(N); - float3 T = basis[0]; - float3 B = basis[1]; - - float3 V = -normalize(X); - float4 D = STL::ImportanceSampling::GetSpecularDominantDirection(N, V, roughness, RELAX_SPEC_DOMINANT_DIRECTION); - float NoD = abs(dot(N, D.xyz)); - - if (NoD < 0.999 && roughness < RELAX_SPEC_BASIS_ROUGHNESS_THRESHOLD) - { - float3 R = reflect(-D.xyz, N); - T = normalize(cross(N, R)); - B = cross(R, T); - -#if( RELAX_USE_ANISOTROPIC_KERNEL == 1 ) - float NoV = abs(dot(N, V)); - float acos01sq = saturate(1.0 - NoV); // see AcosApprox() - - float skewFactor = lerp(1.0, roughness, D.w); - skewFactor = lerp(1.0, skewFactor, STL::Math::Sqrt01(acos01sq)); - - T *= lerp(skewFactor, 1.0, anisoFade); -#endif - } - - T *= worldRadius; - B *= worldRadius; - - return float2x3(T, B); -} - -float2 GetHitDistanceWeightParams(float normHitDist, float nonLinearAccumSpeed, float roughness = 1.0) -{ - float threshold = exp2(-17.0 * roughness * roughness); // TODO: not in line with other weights - float scale = lerp(threshold, 1.0, nonLinearAccumSpeed); - - float a = rcp(normHitDist * scale * 0.99 + 0.01); - float b = normHitDist * a; - - return float2(a, -b); -} - -float GetNormalWeightParams(float nonLinearAccumSpeed, float edge, float error, float roughness = 1.0, float strictness = 1.0) -{ - float angle = STL::ImportanceSampling::GetSpecularLobeHalfAngle(roughness); - - // TODO: 0.15 can be different for blur passes - // TODO: curvature is needed to estimate initial scale - float s = lerp(0.04, 0.15, error); - s *= strictness; - - s = lerp(s, 1.0, edge); - s = lerp(s, 1.0, nonLinearAccumSpeed); - angle *= s; - - angle += STL::Math::DegToRad(0.625); - - return rcp(angle); -} - -int2 SpecCheckerboard(int2 pos) -{ - int2 result = pos; - if (gSpecularCheckerboard != 2) - { - result.x >>= 1; - } - return result; -} - -float GetGaussianWeight(float r) -{ - // radius is normalized to 1 - return exp(-0.66 * r * r); -} - -float GetNormalWeight(float params0, float3 n0, float3 n) -{ - float cosa = saturate(dot(n0, n)); - float angle = STL::Math::AcosApprox(cosa); - - return _ComputeWeight(float2(params0, -0.001), angle); -} - -#define GetHitDistanceWeight(p, value) _ComputeWeight(p, value) - -float2 GetRoughnessWeightParams(float roughness0) -{ - float a = rcp(roughness0 * 0.05 * 0.99 + 0.01); - float b = roughness0 * a; - - return float2(a, -b); -} - -float GetRoughnessWeight(float2 params0, float roughness) -{ - return STL::Math::SmoothStep01(1.0 - abs(roughness * params0.x + params0.y)); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Calculating checkerboard fields - bool specHasData = true; - uint checkerboard = STL::Sequence::CheckerBoard(ipos, gFrameIndex); - - if (gSpecularCheckerboard != 2) - { - specHasData = (checkerboard == gSpecularCheckerboard); - } - - // Reading center GBuffer data - // Applying abs() to viewZ so it is positive down the denoising pipeline. - // This ensures correct denoiser operation with different camera handedness. - float centerViewZ = abs(gViewZ[ipos + gRectOrigin]); - float4 centerNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos + gRectOrigin]); - float3 centerNormal = centerNormalRoughness.xyz; - float centerRoughness = centerNormalRoughness.w; - - // Outputting ViewZ and scaled ViewZ - gOutViewZ[ipos] = centerViewZ; - gOutScaledViewZ[ipos] = min(centerViewZ * NRD_FP16_VIEWZ_SCALE, NRD_FP16_MAX); - - // Outputting ViewZ and scaled ViewZ to be used down the denoising pipeline - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float2 uv = ((float2)ipos + float2(0.5, 0.5)) * gInvRectSize; - float3 centerWorldPos = GetCurrentWorldPos(uv * 2.0 - 1.0, centerViewZ); - float4 rotator = GetBlurKernelRotation(NRD_FRAME, ipos, gRotator, gFrameIndex); - - // Checkerboard resolve weights - float2 checkerboardResolveWeights = 1.0; - if (gSpecularCheckerboard != 2) - { - float viewZ0 = abs(gViewZ[ipos + int2(-1, 0) + gRectOrigin]); - float viewZ1 = abs(gViewZ[ipos + int2(1, 0) + gRectOrigin]); - - checkerboardResolveWeights = GetBilateralWeight(float2(viewZ0, viewZ1), centerViewZ); - checkerboardResolveWeights *= STL::Math::PositiveRcp(checkerboardResolveWeights.x + checkerboardResolveWeights.y); - } - - // Reading specular & resolving specular checkerboard - float4 specularIllumination = gSpecularIllumination[SpecCheckerboard(ipos + gRectOrigin)]; - - if (!specHasData) - { - float4 s0 = gSpecularIllumination[SpecCheckerboard(ipos + int2(-1, 0) + gRectOrigin)]; - float4 s1 = gSpecularIllumination[SpecCheckerboard(ipos + int2(1, 0) + gRectOrigin)]; - specularIllumination *= saturate(1.0 - checkerboardResolveWeights.x - checkerboardResolveWeights.y); - specularIllumination += s0 * checkerboardResolveWeights.x + s1 * checkerboardResolveWeights.y; - } - - specularIllumination.a = max(0.001, min(gDenoisingRange, specularIllumination.a)); - float specularHitT = specularIllumination.a; - - // Pre-blur for specular - if (gSpecularBlurRadius > 0) - { - - float exposure = _NRD_GetColorCompressionExposureForSpatialPasses(centerRoughness); - specularIllumination.rgb = STL::Color::Compress(specularIllumination.rgb, exposure); - - // Specular blur radius - float hitDist = GetNormHitDist(specularIllumination.w, centerViewZ, float4(3.0, 0.1, 10.0, -25.0), centerRoughness); - float blurRadius = GetBlurRadius(gSpecularBlurRadius, centerRoughness, specularIllumination.w, centerViewZ, 1.0 / 9.0, 1.0, 1.0, 0, 1.0); - - float worldBlurRadius = PixelRadiusToWorld(gUnproject, gIsOrtho, blurRadius, centerViewZ) * - min(gResolutionScale.x, gResolutionScale.y); - - float anisoFade = 1.0 / 9.0; - float2x3 TvBv = GetKernelBasis(centerWorldPos, centerNormal, worldBlurRadius, centerRoughness, anisoFade); - float normalWeightParams = GetNormalWeightParams(1.0 / 9.0, 0.0, 1.0, centerRoughness, 1.0); - float2 hitDistanceWeightParams = GetHitDistanceWeightParams(specularIllumination.w, 1.0 / 9.0, centerRoughness); - float2 roughnessWeightParams = GetRoughnessWeightParams(centerRoughness); - float weightSum = 1.0; - - // Spatial blur - [unroll] - for (uint i = 0; i < POISSON_SAMPLE_NUM; i++) - { - float3 offset = POISSON_SAMPLES[i]; - - // Sample coordinates - float2 uv = GetKernelSampleCoordinates(gWorldToClip, offset, centerWorldPos, TvBv[0], TvBv[1], rotator); - - // Handle half res input in the checkerboard mode - float2 checkerboardUv = uv; - if (gSpecularCheckerboard != 2) - { - checkerboardUv = ApplyCheckerboard(uv, gSpecularCheckerboard, i, gRectSize, gInvRectSize, gFrameIndex); - } - - // Fetch data - float2 uvScaled = uv * gResolutionScale; - float4 sampleNormalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0)); - float3 sampleNormal = sampleNormalRoughness.rgb; - float sampleRoughness = sampleNormalRoughness.a; - - float2 checkerboardUvScaled = checkerboardUv * gResolutionScale + gRectOffset; - float4 sampleSpecularIllumination = gSpecularIllumination.SampleLevel(gNearestMirror, checkerboardUvScaled, 0); - sampleSpecularIllumination.rgb = STL::Color::Compress(sampleSpecularIllumination.rgb, exposure); - float sampleViewZ = abs(gViewZ.SampleLevel(gNearestMirror, uvScaled + gRectOffset, 0)); - - float3 sampleWorldPos = GetCurrentWorldPos(uv * 2.0 - 1.0, sampleViewZ); - - // Sample weight - float sampleWeight = IsInScreen(uv); - sampleWeight *= GetGaussianWeight(offset.z); - sampleWeight *= GetRoughnessWeight(roughnessWeightParams, sampleRoughness); - - float sampleNormalizedHitDist = GetNormHitDist(sampleSpecularIllumination.w, sampleViewZ); - - float minHitDistanceWeight = 0.2; - float hitDistanceWeight = GetHitDistanceWeight(hitDistanceWeightParams, sampleNormalizedHitDist); - - sampleWeight *= GetPlaneDistanceWeight( - centerWorldPos, - centerNormal, - gIsOrtho == 0 ? centerViewZ : 1.0, - sampleWorldPos, - gDepthThreshold); - sampleWeight *= GetNormalWeight(normalWeightParams, centerNormal, sampleNormal); - sampleWeight *= lerp(minHitDistanceWeight, 1.0, hitDistanceWeight); - - specularIllumination += sampleSpecularIllumination * sampleWeight; - weightSum += sampleWeight; - } - specularIllumination /= weightSum; - - specularIllumination.rgb = STL::Color::Decompress(specularIllumination.rgb, exposure); - specularIllumination.a = specularHitT; // No, we don't preblur specular HitT! - } - gOutSpecularIllumination[ipos] = clamp(specularIllumination, 0, NRD_FP16_MAX); - -} diff --git a/Source/Shaders/RELAX_Specular_Reproject.cs.hlsl b/Source/Shaders/RELAX_Specular_Reproject.cs.hlsl deleted file mode 100644 index 5280419..0000000 --- a/Source/Shaders/RELAX_Specular_Reproject.cs.hlsl +++ /dev/null @@ -1,966 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_Reproject.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -#define THREAD_GROUP_SIZE 8 -#define SKIRT 2 - -groupshared float4 sharedInSpecular[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalRoughness[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -// Helper functions - -float GetSpecMagicCurve(float roughness, float power = 0.25) -{ - // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIxLjAtMl4oLTE1LjAqeCkiLCJjb2xvciI6IiNGMjE4MTgifSx7InR5cGUiOjAsImVxIjoiKDEtMl4oLTIwMCp4KngpKSooeF4wLjI1KSIsImNvbG9yIjoiIzIyRUQxNyJ9LHsidHlwZSI6MCwiZXEiOiIoMS0yXigtMjAwKngqeCkpKih4XjAuNSkiLCJjb2xvciI6IiMxNzE2MTYifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMSIsIjAiLCIxLjEiXSwic2l6ZSI6WzEwMDAsNTAwXX1d - - float f = 1.0 - exp2(-200.0 * roughness * roughness); - f *= STL::Math::Pow01(roughness, power); - - return f; -} - -float GetSpecAccumulatedFrameNum(float roughness, float powerScale) -{ - // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIzMSooeF4wLjY2KSIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MCwiZXEiOiIzMSooMS0yXigtMjAwKngqeCkpKih4XjAuNSkiLCJjb2xvciI6IiNGQTBEMEQifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMSIsIjAiLCIzMSJdfV0- - float f = 1.0 - exp2(-200.0 * roughness * roughness); - f *= STL::Math::Pow01(roughness, RELAX_SPEC_ACCUM_BASE_POWER * powerScale); - return RELAX_MAX_ACCUM_FRAME_NUM * f; -} - - -float GetSpecAccumSpeed(float maxAccumSpeed, float roughness, float NoV, float parallax) -{ - float acos01sq = saturate(1.0 - NoV); // see AcosApprox() - - // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS4wNSsoeCp4KV4xLjApLygxLjA1LSh4KngpXjEuMCkiLCJjb2xvciI6IiM1MkExMDgifSx7InR5cGUiOjAsImVxIjoiKDEuMDUrKHgqeCleMC42NikvKDEuMDUtKHgqeCleMC42NikiLCJjb2xvciI6IiNFM0Q4MDkifSx7InR5cGUiOjAsImVxIjoiKDEuMDUrKHgqeCleMC41KS8oMS4wNS0oeCp4KV4wLjUpIiwiY29sb3IiOiIjRjUwQTMxIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMCIsIjEiLCIwIiwiNDIiXSwic2l6ZSI6WzE5MDAsNzAwXX1d - float a = STL::Math::Pow01(acos01sq, RELAX_SPEC_ACCUM_CURVE); - float b = 1.1 + roughness * roughness; - float parallaxSensitivity = (b + a) / (b - a); - float powerScale = 1.0 + parallax * 3.0 * parallaxSensitivity; - float accumSpeed = GetSpecAccumulatedFrameNum(roughness, powerScale); - accumSpeed = min(accumSpeed, maxAccumSpeed); - return accumSpeed; -} - -float GetNormalWeight(float params0, float3 n0, float3 n) -{ - float cosa = saturate(dot(n0, n)); - float angle = STL::Math::AcosApprox(cosa); - return _ComputeWeight(float2(params0, -0.001), angle); -} - -float2 GetRoughnessWeightParams(float roughness0) -{ - float a = rcp(roughness0 * 0.05 * 0.99 + 0.01); - float b = roughness0 * a; - return float2(a, -b); -} - -#define GetRoughnessWeight _ComputeWeight - -float ComputeParallax(float3 X, float3 Xprev, float3 cameraDelta) -{ - float3 Xt = Xprev - cameraDelta; - float cosa = dot(X, Xt); - cosa *= STL::Math::Rsqrt(STL::Math::LengthSquared(Xt) * STL::Math::LengthSquared(X)); - cosa = saturate(cosa); - float parallax = STL::Math::Sqrt01(1.0 - cosa * cosa) * STL::Math::PositiveRcp(cosa); - parallax *= RELAX_PARALLAX_NORMALIZATION; - parallax /= 1.0 + RELAX_PARALLAX_COMPRESSION_STRENGTH * parallax; - return parallax; -} - -float GetParallaxInPixels(float parallax) -{ - parallax /= 1.0 - RELAX_PARALLAX_COMPRESSION_STRENGTH * parallax; - - float parallaxInPixels = parallax / (RELAX_PARALLAX_NORMALIZATION * gUnproject); - - return parallaxInPixels; -} - -float getJitterRadius(float jitterDelta, float linearZ) -{ - return jitterDelta * gUnproject * (gIsOrtho == 0 ? linearZ : 1.0); -} - -float isReprojectionTapValid(float3 currentWorldPos, float3 previousWorldPos, float3 currentNormal, float disocclusionThreshold) -{ - // Check if plane distance is acceptable - float3 posDiff = currentWorldPos - previousWorldPos; - float maxPlaneDistance = abs(dot(posDiff, currentNormal)); - return maxPlaneDistance > disocclusionThreshold ? 0.0 : 1.0; -} - -// Returns reprojection search result based on surface motion: -// 2 - reprojection found, bicubic footprint was used -// 1 - reprojection found, bilinear footprint was used -// 0 - reprojection not found -// -// Also returns reprojected data from previous frame calculated using filtering based on filters above. -// For better performance, some data is filtered using weighed bilinear instead of bicubic even if all bicubic taps are valid. -float loadSurfaceMotionBasedPrevData( - int2 pixelPosOnScreen, - float3 currentWorldPos, - float3 currentNormal, - float currentLinearZ, - float currentReflectionHitT, - float3 motionVector, - out float4 prevSpecularIllumAnd2ndMoment, - out float3 prevSpecularResponsiveIllum, - out float3 prevWorldPos, - out float3 prevNormal, - out float prevReflectionHitT, - out float historyLength, - out float2 prevUV, - out float footprintQuality) -{ - // Calculating jitter margin radius in world space - float jitterRadius = getJitterRadius(gPrevCameraPositionAndJitterDelta.w, currentLinearZ); - float disocclusionThreshold = (gDisocclusionDepthThreshold + jitterRadius) * (gIsOrtho == 0 ? currentLinearZ : 1.0); - - // Calculating previous pixel position and UV - float2 pixelUV = (pixelPosOnScreen + 0.5) * gInvRectSize; - prevUV = STL::Geometry::GetPrevUvFromMotion(pixelUV, currentWorldPos, gPrevWorldToClip, motionVector, gIsWorldSpaceMotion); - float2 prevPixelPosOnScreen = prevUV * gRectSizePrev; - - // 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. - int2 prevPixelPosInt = int2(prevPixelPosOnScreen); - bool isSmallMotion = all(prevPixelPosInt == pixelPosOnScreen); - bool skipReprojectionTest = gSkipReprojectionTestWithoutMotion && gIsCameraStatic && isSmallMotion; - - // Calculating footprint origin and weights - int2 bilinearOrigin = int2(floor(prevPixelPosOnScreen - 0.5)); - float2 bilinearWeights = frac(prevPixelPosOnScreen - 0.5); - - // Checking bicubic footprint (with cut corners) first, - // remembering bilinear taps validity and worldspace position along the way, - // for faster weighted bilinear and for calculating previous worldspace position - // bc - bicubic & bilinear tap, - // bl - bilinear tap - // - // -- bc bc -- - // bc bl bl bc - // bc bl bl bc - // -- bc bc -- - - float bicubicFootprintValid = 1.0; - float4 bilinearTapsValid = 0; - - float3 prevNormalInTap; - float prevViewZInTap; - float3 prevWorldPosInTap; - int2 tapPos; - float reprojectionTapValid; - float3 prevWorldPos00, prevWorldPos10, prevWorldPos01, prevWorldPos11; - float3 prevNormal00, prevNormal10, prevNormal01, prevNormal11; - - prevNormal00 = UnpackPrevNormalRoughness(gPrevNormalRoughness[bilinearOrigin + int2(0, 0)]).rgb; - prevNormal10 = UnpackPrevNormalRoughness(gPrevNormalRoughness[bilinearOrigin + int2(1, 0)]).rgb; - prevNormal01 = UnpackPrevNormalRoughness(gPrevNormalRoughness[bilinearOrigin + int2(0, 1)]).rgb; - prevNormal11 = UnpackPrevNormalRoughness(gPrevNormalRoughness[bilinearOrigin + int2(1, 1)]).rgb; - float3 prevNormalFlat = normalize(prevNormal00 + prevNormal10 + prevNormal01 + prevNormal11); - - // Adjusting worldspace position: - // Applying worldspace motion first, - motionVector *= gIsWorldSpaceMotion > 0 ? 1.0 : 0.0; - - // Then taking care of camera motion, because world space is always centered at camera position in NRD - currentWorldPos += motionVector - gPrevCameraPositionAndJitterDelta.xyz; - - // Transforming bilinearOrigin to clip space coords to simplify previous world pos calculation - float2 prevClipSpaceXY = ((float2)bilinearOrigin + float2(0.5, 0.5)) * (1.0 / gRectSizePrev) * 2.0 - 1.0; - float2 dXY = (2.0 / gRectSizePrev); - - // 1st row - tapPos = bilinearOrigin + int2(0, -1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, -1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - tapPos = bilinearOrigin + int2(1, -1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, -1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - // 2nd row - tapPos = bilinearOrigin + int2(-1, 0); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(-1.0, 0.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - tapPos = bilinearOrigin + int2(0, 0); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 0.0), prevViewZInTap); - prevWorldPos00 = prevWorldPosInTap; - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - bilinearTapsValid.x = reprojectionTapValid; - - tapPos = bilinearOrigin + int2(1, 0); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 0.0), prevViewZInTap); - prevWorldPos10 = prevWorldPosInTap; - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - bilinearTapsValid.y = reprojectionTapValid; - - tapPos = bilinearOrigin + int2(2, 0); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(2.0, 0.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - // 3rd row - tapPos = bilinearOrigin + int2(-1, 1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(-1.0, 1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - tapPos = bilinearOrigin + int2(0, 1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 1.0), prevViewZInTap); - prevWorldPos01 = prevWorldPosInTap; - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - bilinearTapsValid.z = reprojectionTapValid; - - tapPos = bilinearOrigin + int2(1, 1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 1.0), prevViewZInTap); - prevWorldPos11 = prevWorldPosInTap; - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - bilinearTapsValid.w = reprojectionTapValid; - - tapPos = bilinearOrigin + int2(2, 1); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(2.0, 1.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - // 4th row - tapPos = bilinearOrigin + int2(0, 2); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(0.0, 2.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - tapPos = bilinearOrigin + int2(1, 2); - prevViewZInTap = gPrevViewZ[tapPos]; - prevWorldPosInTap = GetPreviousWorldPos(prevClipSpaceXY + dXY * float2(1.0, 2.0), prevViewZInTap); - reprojectionTapValid = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - bicubicFootprintValid *= reprojectionTapValid; - - bilinearTapsValid = skipReprojectionTest ? float4(1.0, 1.0, 1.0, 1.0) : bilinearTapsValid; - - // Reject backfacing history: if angle between current normal and previous normal is larger than 90 deg - if (dot(currentNormal, prevNormalFlat) < 0.0) - { - bilinearTapsValid = 0; - bicubicFootprintValid = 0; - } - - // Checking bicubic footprint validity for being in rect - if (any(bilinearOrigin < int2(1, 1)) || any(bilinearOrigin >= int2(gRectSizePrev)-int2(2, 2))) - { - bicubicFootprintValid = 0; - } - - // Checking bilinear footprint validity for being in rect - // Bilinear footprint: - // x y - // z w - if (bilinearOrigin.x < 0) bilinearTapsValid.xz = 0; - if (bilinearOrigin.x >= gRectSizePrev.x) bilinearTapsValid.yw = 0; - if (bilinearOrigin.y < 0) bilinearTapsValid.xy = 0; - if (bilinearOrigin.y >= gRectSizePrev.y) bilinearTapsValid.zw = 0; - - // Calculating interpolated binary weight for bilinear taps in advance - STL::Filtering::Bilinear bilinear; - bilinear.weights = bilinearWeights; - float interpolatedBinaryWeight = STL::Filtering::ApplyBilinearFilter(bilinearTapsValid.x, bilinearTapsValid.y, bilinearTapsValid.z, bilinearTapsValid.w, bilinear); - interpolatedBinaryWeight = max(1e-6, interpolatedBinaryWeight); - - // Applying reprojection filters - float reprojectionFound = 0; - prevSpecularIllumAnd2ndMoment = 0; - prevSpecularResponsiveIllum = 0; - prevWorldPos = currentWorldPos; - prevNormal = currentNormal; - prevReflectionHitT = currentReflectionHitT; - historyLength = 0; - footprintQuality = 0; - - if (any(bilinearTapsValid)) - { - // Trying to apply bicubic filter first - if (bicubicFootprintValid > 0) - { - // Bicubic for illumination and 2nd moments - prevSpecularIllumAnd2ndMoment = - max(0, BicubicFloat4(gPrevSpecularIllumination, gLinearClamp, prevPixelPosOnScreen, gInvResourceSize)); -#if( RELAX_USE_BICUBIC_FOR_FAST_HISTORY == 1 ) - prevSpecularResponsiveIllum = max(0, BicubicFloat4(gPrevSpecularIlluminationResponsive, gLinearClamp, prevPixelPosOnScreen, gInvResourceSize)).rgb; -#else - prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; - #endif - footprintQuality = 1.0; - - reprojectionFound = 2.0; - } - else - { - // If no success with the bicubic, then do weighted bilinear - prevSpecularIllumAnd2ndMoment = - BilinearWithBinaryWeightsFloat4(gPrevSpecularIllumination, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; - - reprojectionFound = 1.0; - } - - prevWorldPos = BilinearWithBinaryWeightsImmediateFloat3( - prevWorldPos00, prevWorldPos10, prevWorldPos01, prevWorldPos11, - bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - prevNormal = BilinearWithBinaryWeightsImmediateFloat3( - prevNormal00, prevNormal10, prevNormal01, prevNormal11, - bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - historyLength = 255.0 * BilinearWithBinaryWeightsFloat(gPrevSpecularHistoryLength, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - float2 gatherOrigin = (bilinearOrigin + 1.0) * gInvResourceSize; - float4 prevReflectionHitTs = gPrevReflectionHitT.GatherRed(gNearestClamp, gatherOrigin).wzxy; - - prevReflectionHitT = BilinearWithBinaryWeightsImmediateFloat( - prevReflectionHitTs.x, prevReflectionHitTs.y, prevReflectionHitTs.z, prevReflectionHitTs.w, - bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - prevReflectionHitT = max(0.001, prevReflectionHitT); - - footprintQuality = interpolatedBinaryWeight; - } - return reprojectionFound; -} - -// Returns specular reprojection search result based on virtual motion -float loadVirtualMotionBasedPrevData( - int2 pixelPosOnScreen, - float3 currentWorldPos, - float3 currentNormal, - float currentLinearZ, - float currentReflectionHitT, - float3 currentViewVector, - float3 prevWorldPos, - bool surfaceBicubicValid, - out float4 prevSpecularIllumAnd2ndMoment, - out float3 prevSpecularResponsiveIllum, - out float3 prevNormal, - out float prevRoughness, - out float prevReflectionHitT, - out float2 prevUVVMB) -{ - // Taking care of camera motion, because world space is always centered at camera position in NRD - prevWorldPos += gPrevCameraPositionAndJitterDelta.xyz; - currentWorldPos -= gPrevCameraPositionAndJitterDelta.xyz; - - // Calculating previous worldspace virtual position based on reflection hitT - float3 virtualViewVector = normalize(currentViewVector) * currentReflectionHitT; - float3 prevVirtualWorldPos = prevWorldPos + virtualViewVector; - - float currentViewVectorLength = length(currentViewVector); - float accumulatedSpecularVMBZ = currentViewVectorLength + currentReflectionHitT; - - float4 prevVirtualClipPos = mul(gPrevWorldToClip, float4(prevVirtualWorldPos, 1.0)); - prevVirtualClipPos.xy /= prevVirtualClipPos.w; - prevUVVMB = prevVirtualClipPos.xy * float2(0.5, -0.5) + float2(0.5, 0.5); - float2 prevVirtualPixelPosOnScreen = prevUVVMB * gRectSizePrev; - - float jitterRadius = getJitterRadius(gPrevCameraPositionAndJitterDelta.w, accumulatedSpecularVMBZ); - float disocclusionThreshold = (gDisocclusionDepthThreshold + jitterRadius) * (gIsOrtho == 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. - int2 prevVirtualPixelPosInt = int2(prevVirtualPixelPosOnScreen); - bool isSmallVirtualMotion = all(prevVirtualPixelPosInt == pixelPosOnScreen); - bool skipReprojectionTest = gSkipReprojectionTestWithoutMotion && gIsCameraStatic && isSmallVirtualMotion; - - // Calculating footprint origin and weights - int2 bilinearOrigin = int2(floor(prevVirtualPixelPosOnScreen - 0.5)); - float2 bilinearWeights = frac(prevVirtualPixelPosOnScreen - 0.5); - - // Checking bilinear footprint - float3 prevNormal00, prevNormal10, prevNormal01, prevNormal11; - float prevRoughness00, prevRoughness10, prevRoughness01, prevRoughness11; - int2 tapPos; - float prevLinearZInTap; - float3 prevWorldPosInTap; - float4 bilinearTapsValid; - float4 prevNormalRoughness; - - float2 gatherOrigin = (bilinearOrigin + 1.0) * gInvResourceSize; - float4 prevViewZs = gPrevViewZ.GatherRed(gNearestClamp, gatherOrigin).wzxy; - - tapPos = bilinearOrigin + int2(0, 0); - prevNormalRoughness = UnpackPrevNormalRoughness(gPrevNormalRoughness[tapPos]); - prevNormal00 = prevNormalRoughness.rgb; - prevRoughness00 = prevNormalRoughness.a; - prevLinearZInTap = prevViewZs.x; - prevWorldPosInTap = GetPreviousWorldPos(tapPos, prevLinearZInTap); - bilinearTapsValid.x = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - - tapPos = bilinearOrigin + int2(1, 0); - prevNormalRoughness = UnpackPrevNormalRoughness(gPrevNormalRoughness[tapPos]); - prevNormal10 = prevNormalRoughness.rgb; - prevRoughness10 = prevNormalRoughness.a; - prevLinearZInTap = prevViewZs.y; - prevWorldPosInTap = GetPreviousWorldPos(tapPos, prevLinearZInTap); - bilinearTapsValid.y = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - - tapPos = bilinearOrigin + int2(0, 1); - prevNormalRoughness = UnpackPrevNormalRoughness(gPrevNormalRoughness[tapPos]); - prevNormal01 = prevNormalRoughness.rgb; - prevRoughness01 = prevNormalRoughness.a; - prevLinearZInTap = prevViewZs.z; - prevWorldPosInTap = GetPreviousWorldPos(tapPos, prevLinearZInTap); - bilinearTapsValid.z = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - - tapPos = bilinearOrigin + int2(1, 1); - prevNormalRoughness = UnpackPrevNormalRoughness(gPrevNormalRoughness[tapPos]); - prevNormal11 = prevNormalRoughness.rgb; - prevRoughness11 = prevNormalRoughness.a; - prevLinearZInTap = prevViewZs.w; - prevWorldPosInTap = GetPreviousWorldPos(tapPos, prevLinearZInTap); - bilinearTapsValid.w = isReprojectionTapValid(currentWorldPos, prevWorldPosInTap, currentNormal, disocclusionThreshold); - - bilinearTapsValid = skipReprojectionTest ? float4(1.0, 1.0, 1.0, 1.0) : bilinearTapsValid; - - // Checking bilinear footprint validity for being in rect - // Bilinear footprint: - // x y - // z w - if (bilinearOrigin.x < 0) bilinearTapsValid.xz = 0; - if (bilinearOrigin.x >= gRectSizePrev.x) bilinearTapsValid.yw = 0; - if (bilinearOrigin.y < 0) bilinearTapsValid.xy = 0; - if (bilinearOrigin.y >= gRectSizePrev.y) bilinearTapsValid.zw = 0; - - // Calculating interpolated binary weight for bilinear taps in advance - STL::Filtering::Bilinear bilinear; - bilinear.weights = bilinearWeights; - float interpolatedBinaryWeight = STL::Filtering::ApplyBilinearFilter(bilinearTapsValid.x, bilinearTapsValid.y, bilinearTapsValid.z, bilinearTapsValid.w, bilinear); - interpolatedBinaryWeight = max(1e-6, interpolatedBinaryWeight); - - // Applying reprojection - float reprojectionFound = 0; - prevSpecularIllumAnd2ndMoment = 0; - prevSpecularResponsiveIllum = 0; - prevNormal = currentNormal; - prevRoughness = 0; - prevReflectionHitT = currentReflectionHitT; - - // Weighted bilinear (or bicubic optionally) for prev specular data based on virtual motion - if (any(bilinearTapsValid)) - { -#if( RELAX_USE_BICUBIC_FOR_VIRTUAL_MOTION_SPECULAR == 1 ) - if (surfaceBicubicValid) - { - prevSpecularIllumAnd2ndMoment = max(0, BicubicFloat4(gPrevSpecularIllumination, gLinearClamp, prevVirtualPixelPosOnScreen, gInvResourceSize)); - -#if( RELAX_USE_BICUBIC_FOR_FAST_HISTORY == 1 ) - prevSpecularResponsiveIllum = max(0, BicubicFloat4(gPrevSpecularIlluminationResponsive, gLinearClamp, prevVirtualPixelPosOnScreen, gInvResourceSize).rgb); -#else - prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; -#endif - } - else - { - prevSpecularIllumAnd2ndMoment = BilinearWithBinaryWeightsFloat4(gPrevSpecularIllumination, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; - } -#else - prevSpecularIllumAnd2ndMoment = BilinearWithBinaryWeightsFloat4(gPrevSpecularIllumination, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - prevSpecularResponsiveIllum = BilinearWithBinaryWeightsFloat4(gPrevSpecularIlluminationResponsive, bilinearOrigin, bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight).rgb; -#endif - float4 prevNormalRoughness = BilinearWithBinaryWeightsImmediateFloat4( - float4(prevNormal00, prevRoughness00), - float4(prevNormal10, prevRoughness10), - float4(prevNormal01, prevRoughness01), - float4(prevNormal11, prevRoughness11), - bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - prevNormal = prevNormalRoughness.xyz; - prevRoughness = prevNormalRoughness.w; - - float4 prevReflectionHitTs = gPrevReflectionHitT.GatherRed(gNearestClamp, gatherOrigin).wzxy; - - prevReflectionHitT = BilinearWithBinaryWeightsImmediateFloat( - prevReflectionHitTs.x, prevReflectionHitTs.y, prevReflectionHitTs.z, prevReflectionHitTs.w, - bilinearWeights, bilinearTapsValid, interpolatedBinaryWeight); - - prevReflectionHitT = max(0.001, prevReflectionHitT); - reprojectionFound = 1.0; - } - return reprojectionFound; -} - -// -// Main -// -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(int2 ipos : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - // Calculating checkerboard fields - bool diffHasData = true; - bool specHasData = true; - uint2 checkerboardPixelPos = ipos.xx; - uint checkerboard = STL::Sequence::CheckerBoard(ipos, gFrameIndex); - - if (gSpecCheckerboard != 2) - { - specHasData = checkerboard == gSpecCheckerboard; - checkerboardPixelPos.y >>= 1; - } - - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - uint ox = newIdxX; - uint oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 inSpecularIllumination = 0; - float4 normalRoughness = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - inSpecularIllumination = gSpecularIllumination[int2(xx, yy) + gRectOrigin]; - normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy) + gRectOrigin]); - } - sharedInSpecular[oy][ox] = inSpecularIllumination; - sharedNormalRoughness[oy][ox] = normalRoughness; - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - inSpecularIllumination = 0; - normalRoughness = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - inSpecularIllumination = gSpecularIllumination[int2(xx, yy) + gRectOrigin]; - normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy) + gRectOrigin]); - } - sharedInSpecular[oy][ox] = inSpecularIllumination; - sharedNormalRoughness[oy][ox] = normalRoughness; - } - // Third stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - inSpecularIllumination = 0; - normalRoughness = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - inSpecularIllumination = gSpecularIllumination[int2(xx, yy) + gRectOrigin]; - normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy) + gRectOrigin]); - } - sharedInSpecular[oy][ox] = inSpecularIllumination; - sharedNormalRoughness[oy][ox] = normalRoughness; - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - uint2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - // Center data - float4 specularIllumination = sharedInSpecular[sharedMemoryIndex.y][sharedMemoryIndex.x]; - - // Reading current GBuffer data and center/left/right viewZ - float4 currentNormalRoughness = sharedNormalRoughness[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float3 currentNormal = currentNormalRoughness.xyz; - float currentRoughness = currentNormalRoughness.w; - float currentLinearZ = gViewZ[ipos.xy + gRectOrigin]; - - specularIllumination.a = max(0.001, min(gDenoisingRange, specularIllumination.a)); - - // Early out if linearZ is beyond denoising range - [branch] - if (currentLinearZ > gDenoisingRange) - { - return; - } - - // Calculating average normal, curvature, min hit dist and specular moments in 3x3 and 5x5 areas around current pixel - float3 currentNormalAveraged = currentNormal; - float4 specM1 = specularIllumination; - float4 specM2 = specM1 * specM1; - float curvature = 0; - float minHitDist3x3 = gDenoisingRange; - float minHitDist5x5 = gDenoisingRange; - - [unroll] - for (int i = -2; i <= 2; i++) - { - [unroll] - for (int j = -2; j <= 2; j++) - { - // Skipping center pixel - if ((i == 0) && (j == 0)) continue; - - int2 p = ipos + int2(i, j); - - float4 spec = sharedInSpecular[sharedMemoryIndex.y + j][sharedMemoryIndex.x + i]; - specM1 += spec; - specM2 += spec * spec; - minHitDist5x5 = min(spec.w, minHitDist5x5); - if ((abs(i) <= 1) && (abs(j) <= 1)) - { - minHitDist3x3 = min(spec.w, minHitDist3x3); - } - } - } - specM1 /= 25.0; - specM2 /= 25.0; - float4 specSigma = GetStdDev(specM1, specM2); - - [unroll] - for (int k = -1; k <= 1; k++) - { - [unroll] - for (int l = -1; l <= 1; l++) - { - // Skipping center pixel - if ((k == 0) && (l == 0)) continue; - - int2 p = ipos + int2(k, l); - float3 pNormal = sharedNormalRoughness[sharedMemoryIndex.y + k][sharedMemoryIndex.x + l].xyz; - currentNormalAveraged += pNormal; - curvature += length(pNormal - currentNormal) * rsqrt(STL::Math::LengthSquared(float2(k, l))); - } - } - currentNormalAveraged /= 9.0; - curvature /= 8.0; - - // Only needed to mitigate banding - curvature = STL::Math::LinearStep(NRD_ENCODING_ERRORS.y, 1.0, curvature); - - // Calculating modified roughness that takes normal variation in account - float currentRoughnessModified = STL::Filtering::GetModifiedRoughnessFromNormalVariance(currentRoughness, currentNormalAveraged); - - // Computing 2nd moments of luminance - float specular1stMoment = STL::Color::Luminance(specularIllumination.rgb); - float specular2ndMoment = specular1stMoment * specular1stMoment; - - // Getting current frame worldspace position and view vector for current pixel - float3 currentWorldPos = GetCurrentWorldPos(ipos, currentLinearZ); - float3 currentViewVector = (gIsOrtho == 0) ? - currentWorldPos : - currentLinearZ * normalize(gFrustumForward.xyz); - - - // Reading motion vector - float3 motionVector = gMotion[gRectOrigin + ipos].xyz * gMotionVectorScale.xyy; - - // Loading previous data based on surface motion vectors - float4 prevSpecularIlluminationAnd2ndMomentSMB; - float3 prevSpecularIlluminationAnd2ndMomentSMBResponsive; - float prevReflectionHitTSMB; - float3 prevWorldPosSMB; - float3 prevNormalSMB; - float historyLength; - float2 prevUVSMB; - float footprintQuality; - - float surfaceMotionBasedReprojectionFound = loadSurfaceMotionBasedPrevData( - ipos, - currentWorldPos, - normalize(currentNormalAveraged), - currentLinearZ, - specularIllumination.a, - motionVector, - prevSpecularIlluminationAnd2ndMomentSMB, - prevSpecularIlluminationAnd2ndMomentSMBResponsive, - prevWorldPosSMB, - prevNormalSMB, - prevReflectionHitTSMB, - historyLength, - prevUVSMB, - footprintQuality - ); - - // History length is based on surface motion based disocclusion - historyLength = historyLength + 1.0; - historyLength = min(100.0, historyLength); - - // Minimize "getting stuck in history" effect when only fraction of bilinear footprint is valid - // by shortening the history length - if (footprintQuality < 1.0) - { - historyLength *= sqrt(footprintQuality); - historyLength = max(historyLength, 1.0); - } - - // Handling history reset if needed - if (gResetHistory != 0) historyLength = 1.0; - - gOutSpecularHistoryLength[ipos] = historyLength / 255.0; - - // SPECULAR ACCUMULATION BELOW - // - float specMaxAccumulatedFrameNum = gSpecularMaxAccumulatedFrameNum; - float specMaxFastAccumulatedFrameNum = gSpecularMaxFastAccumulatedFrameNum; - if (gUseConfidenceInputs) - { - float inSpecConfidence = gSpecConfidence[ipos]; - specMaxAccumulatedFrameNum *= inSpecConfidence; - specMaxFastAccumulatedFrameNum *= inSpecConfidence; - } - - float specHistoryFrames = min(specMaxAccumulatedFrameNum, historyLength.x); - float specHistoryResponsiveFrames = min(specMaxFastAccumulatedFrameNum, historyLength.x); - - // Calculating surface parallax - float parallax = ComputeParallax(currentWorldPos, currentWorldPos + motionVector * (gIsWorldSpaceMotion != 0 ? 1.0 : 0.0), gPrevCameraPositionAndJitterDelta.xyz); - float parallaxOrig = parallax; - float hitDistToSurfaceRatio = saturate(prevReflectionHitTSMB / currentLinearZ); - parallax *= hitDistToSurfaceRatio; - float parallaxInPixels = GetParallaxInPixels(max(0.01, parallaxOrig)); - - // Params required for surface motion based (SMB) specular reprojection - float3 V = normalize(-currentViewVector); - float NoV = saturate(dot(currentNormal, V)); - - // Current specular signal ( surface motion ) - float specSurfaceFrames = GetSpecAccumSpeed(specHistoryFrames, max(0.05, currentRoughnessModified), NoV, parallax); - float specSurfaceResponsiveFrames = GetSpecAccumSpeed(specHistoryResponsiveFrames, max(0.05, currentRoughnessModified), NoV, parallax); - - float specSurfaceAlpha = saturate(1.0 / specSurfaceFrames); - float specSurfaceResponsiveAlpha = saturate(1.0 / specSurfaceResponsiveFrames); - - float surfaceHistoryConfidence = saturate(specSurfaceFrames / (specHistoryFrames + 1.0)); - - if (!specHasData) - { - // Adjusting surface motion based specular accumulation weights for checkerboard - if ((gIsOrtho == 0) || ((gIsOrtho != 0) && (gIsCameraStatic != 0))) - { - specSurfaceAlpha *= 1.0 - gCheckerboardResolveAccumSpeed * (surfaceMotionBasedReprojectionFound > 0 ? 1.0 : 0.0); - specSurfaceResponsiveAlpha *= 1.0 - gCheckerboardResolveAccumSpeed * (surfaceMotionBasedReprojectionFound > 0 ? 1.0 : 0.0); - } - } - - float4 accumulatedSpecularSMB; - accumulatedSpecularSMB.rgb = lerp(prevSpecularIlluminationAnd2ndMomentSMB.rgb, specularIllumination.rgb, specSurfaceAlpha); - accumulatedSpecularSMB.w = lerp(prevReflectionHitTSMB, specularIllumination.w, max(specSurfaceAlpha, RELAX_HIT_DIST_MIN_ACCUM_SPEED(currentRoughnessModified))); - - float3 accumulatedSpecularSMBResponsive = lerp(prevSpecularIlluminationAnd2ndMomentSMBResponsive, specularIllumination.xyz, specSurfaceResponsiveAlpha); - float accumulatedSpecularM2SMB = lerp(prevSpecularIlluminationAnd2ndMomentSMB.a, specular2ndMoment, specSurfaceAlpha); - - // Thin lens equation for adjusting reflection HitT - float pixelSize = PixelRadiusToWorld(gUnproject, gIsOrtho, 1.0, currentLinearZ); - curvature *= NoV / pixelSize; - float hitDist = specularIllumination.a; - hitDist = lerp(minHitDist3x3, minHitDist5x5, STL::Math::SmoothStep(0.04, 0.08, currentRoughnessModified)); - hitDist = clamp(hitDist, specM1.a - specSigma.a * 3.0, specM1.a + specSigma.a * 3.0); - float divider = 0.5 + curvature * hitDist; - float hitDistFocused = max(0.001, 0.5 * hitDist / (divider == 0 ? 1.0 : divider)); - - // Limiting hitDist in ortho case to avoid extreme amounts of motion in reflection - if (gIsOrtho != 0) hitDistFocused = min(currentLinearZ, hitDistFocused); - - // Loading specular data based on virtual motion - float4 prevSpecularIlluminationAnd2ndMomentVMB; - float3 prevSpecularIlluminationAnd2ndMomentVMBResponsive; - float3 prevNormalVMB; - float prevRoughnessVMB; - float prevReflectionHitTVMB; - float2 prevUVVMB; - - float virtualHistoryConfidence = loadVirtualMotionBasedPrevData( - ipos, - currentWorldPos, - currentNormal, - currentLinearZ, - hitDistFocused, - currentViewVector, - prevWorldPosSMB, - surfaceMotionBasedReprojectionFound == 2.0 ? true : false, - prevSpecularIlluminationAnd2ndMomentVMB, - prevSpecularIlluminationAnd2ndMomentVMBResponsive, - prevNormalVMB, - prevRoughnessVMB, - prevReflectionHitTVMB, - prevUVVMB - ); - - // Normal weight for virtual history - float fresnelFactor = STL::BRDF::Pow5(NoV); - float normalWeightRenorm = lerp(0.9, 1.0, STL::Math::LinearStep(0.0, 0.15, currentRoughnessModified)); // mitigate imprecision problems introduced by normals encoded with different precision (test #6 and #12) - float virtualLobeScale = lerp(0.5, 1.0, fresnelFactor); - float specNormalParams = STL::ImportanceSampling::GetSpecularLobeHalfAngle(currentRoughnessModified); - specNormalParams *= virtualLobeScale; - specNormalParams = 1.0 / max(specNormalParams, STL::Math::DegToRad(1.5)); - float virtualNormalWeight = GetNormalWeight(specNormalParams, currentNormal, prevNormalVMB); - - virtualHistoryConfidence *= lerp(virtualNormalWeight, 1.0, saturate(fresnelFactor * parallax)); - -#if( RELAX_USE_BICUBIC_FOR_VIRTUAL_MOTION_SPECULAR == 0 ) - // Artificially decreasing virtual motion confidence by 50% if there is no parallax to avoid overblurring - // due to bilinear filtering used for virtual motion based reprojection, - // this will put more weight to surface based reprojection which uses higher order filter - float noParallaxSharpener = 0.5 + 0.5 * STL::Math::LinearStep(0.5, 1.0, parallaxInPixels); - virtualHistoryConfidence *= noParallaxSharpener; -#endif - - // Amount of virtual motion - dominant factor - float4 D = STL::ImportanceSampling::GetSpecularDominantDirection(currentNormal, V, currentRoughness, RELAX_SPEC_DOMINANT_DIRECTION); - float virtualHistoryAmount = virtualHistoryConfidence * D.w; - - // Virtual history confidence & amount - roughness - float2 roughnessParams = GetRoughnessWeightParams(currentRoughness); - float rw = GetRoughnessWeight(roughnessParams, prevRoughnessVMB); - float virtualRoughnessWeight = 0.75 + 0.25 * rw; - virtualHistoryConfidence *= virtualRoughnessWeight; - virtualHistoryAmount *= (gIsOrtho == 0) ? rw * 0.9 + 0.1 : 1.0; - - // Decreasing virtual history amount for ortho case - virtualHistoryAmount *= (gIsOrtho == 0) ? 1.0 : 0.5; - - // Virtual history confidence - hit distance - float maxDist = max(prevReflectionHitTVMB, prevReflectionHitTSMB); - float dHitT = max(0, sqrt(abs(prevReflectionHitTVMB - prevReflectionHitTSMB)) - 1.0 * specSigma.a); - float virtualHistoryHitDistConfidence = 1.0 - saturate(10.0 * dHitT / (currentLinearZ + maxDist)); - virtualHistoryConfidence *= virtualHistoryHitDistConfidence; - - // "Looking back" 1 and 2 frames and applying normal weight to decrease lags - float2 uvDiff = prevUVVMB - prevUVSMB; - float2 backUV1 = prevUVVMB + 1.0 * uvDiff; - float2 backUV2 = prevUVVMB + 2.0 * uvDiff; - backUV1 *= (gInvResourceSize * gRectSizePrev); // Taking in account resolution scale - backUV2 *= (gInvResourceSize * gRectSizePrev); - float3 backNormal1 = UnpackPrevNormalRoughness(gPrevNormalRoughness.SampleLevel(gLinearClamp, backUV1, 0)).rgb; - float3 backNormal2 = UnpackPrevNormalRoughness(gPrevNormalRoughness.SampleLevel(gLinearClamp, backUV2, 0)).rgb; - float backNormalWeight1 = GetNormalWeight(specNormalParams, currentNormal, backNormal1); - float backNormalWeight2 = GetNormalWeight(specNormalParams, currentNormal, backNormal2); - float backNormalWeight = backNormalWeight1 * backNormalWeight2; - virtualHistoryConfidence *= backNormalWeight; - - // Clamping specular virtual history to current specular signal - float4 specHistoryVirtual = float4(prevSpecularIlluminationAnd2ndMomentVMB.rgb, prevReflectionHitTVMB); - if(gVirtualHistoryClampingEnabled != 0) - { - float SMC = STL::Math::SmoothStep(0.15, 0.25, currentRoughnessModified); - float sigmaScale = lerp(2.0, 6.0, SMC); - sigmaScale *= 1.0 + 7.0 * SMC * max(gFramerateScale, 1.0); // Looks aggressive, but it will be balanced by virtualUnclampedAmount - float4 specHistoryVirtualClamped = STL::Color::Clamp(specM1, specSigma * sigmaScale, specHistoryVirtual); - float3 specHistoryVirtualResponsiveClamped = STL::Color::Clamp(specM1, specSigma * sigmaScale, prevSpecularIlluminationAnd2ndMomentVMBResponsive.rgbb).rgb; - - float virtualUnclampedAmount = GetSpecMagicCurve(currentRoughnessModified) * virtualHistoryConfidence; - virtualUnclampedAmount += gFramerateScale * (0.2 + 0.33 * GetSpecMagicCurve(currentRoughnessModified) * (1.0 - virtualHistoryHitDistConfidence)); - virtualUnclampedAmount = saturate(virtualUnclampedAmount); - - specHistoryVirtual = lerp(specHistoryVirtualClamped, specHistoryVirtual, virtualUnclampedAmount); - specHistoryVirtual.a = specHistoryVirtualClamped.a; - prevSpecularIlluminationAnd2ndMomentVMBResponsive = lerp(specHistoryVirtualResponsiveClamped, prevSpecularIlluminationAnd2ndMomentVMBResponsive, virtualUnclampedAmount); - - // Clamping 2nd moment too - float specM2VirtualClamped = STL::Color::Clamp(specular2ndMoment, max(max(specSigma.r, specSigma.g), specSigma.b) * sigmaScale * 2.0, prevSpecularIlluminationAnd2ndMomentVMB.a); - prevSpecularIlluminationAnd2ndMomentVMB.a = lerp(specM2VirtualClamped, prevSpecularIlluminationAnd2ndMomentVMB.a, virtualUnclampedAmount); - } - - // Current specular signal ( virtual motion ) - float specVirtualFrames = specHistoryFrames * virtualRoughnessWeight * (0.1 + 0.9 * backNormalWeight); - float specVirtualResponsiveFrames = specHistoryResponsiveFrames * virtualRoughnessWeight * (0.0 + 1.0 * backNormalWeight); - - // Artificially decreasing virtual history frames if FPS is lower than 60 and virtual confidence is low, to decrease lags - float fpsScaler = lerp(max(0.25, min(gFramerateScale * gFramerateScale, 1.0)), 1.0, virtualHistoryConfidence); - specVirtualResponsiveFrames *= fpsScaler; - specVirtualFrames *= fpsScaler; - - float specVirtualAlpha = 1.0 / (specVirtualFrames + 1.0); - float specVirtualResponsiveAlpha = 1.0 / (specVirtualResponsiveFrames + 1.0); - - if (!specHasData) - { - // Adjusting virtual motion based specular accumulation weights for checkerboard - specVirtualAlpha *= 1.0 - gCheckerboardResolveAccumSpeed * virtualHistoryConfidence; - specVirtualResponsiveAlpha *= 1.0 - gCheckerboardResolveAccumSpeed * virtualHistoryConfidence; - } - - float4 accumulatedSpecularVMB; - accumulatedSpecularVMB.xyz = lerp(specHistoryVirtual.xyz, specularIllumination.xyz, specVirtualAlpha); - accumulatedSpecularVMB.w = lerp(specHistoryVirtual.w, specularIllumination.w, max(specVirtualAlpha, RELAX_HIT_DIST_MIN_ACCUM_SPEED(currentRoughnessModified))); - float3 accumulatedSpecularVMBResponsive = lerp(prevSpecularIlluminationAnd2ndMomentVMBResponsive, specularIllumination.xyz, specVirtualResponsiveAlpha); - float accumulatedSpecularM2VMB = lerp(prevSpecularIlluminationAnd2ndMomentVMB.a, specular2ndMoment, specVirtualAlpha); - - // Temporal accumulation of reflection HitT - float accumulatedReflectionHitT = lerp(accumulatedSpecularSMB.w, accumulatedSpecularVMB.w, virtualHistoryAmount * hitDistToSurfaceRatio); - - // Temporal accumulation of specular illumination - float3 accumulatedSpecularIllumination = lerp(accumulatedSpecularSMB.xyz, accumulatedSpecularVMB.xyz, virtualHistoryAmount); - float3 accumulatedSpecularIlluminationResponsive = lerp(accumulatedSpecularSMBResponsive.xyz, accumulatedSpecularVMBResponsive.xyz, virtualHistoryAmount); - float accumulatedSpecular2ndMoment = lerp(accumulatedSpecularM2SMB, accumulatedSpecularM2VMB, virtualHistoryAmount); - - // If zero specular sample (color = 0), artificially adding variance for pixels with low reprojection confidence - float specularHistoryConfidence = saturate(virtualHistoryConfidence + surfaceHistoryConfidence); - if (accumulatedSpecular2ndMoment == 0) accumulatedSpecular2ndMoment = gSpecularVarianceBoost * (1.0 - specularHistoryConfidence); - - // Write out the results - gOutSpecularIllumination[ipos] = float4(accumulatedSpecularIllumination, accumulatedSpecular2ndMoment); - gOutSpecularIlluminationResponsive[ipos] = float4(accumulatedSpecularIlluminationResponsive, 0); - - gOutReflectionHitT[ipos] = accumulatedReflectionHitT; - gOutSpecularReprojectionConfidence[ipos] = specularHistoryConfidence; -} diff --git a/Source/Shaders/RELAX_Specular_SpatialVarianceEstimation.cs.hlsl b/Source/Shaders/RELAX_Specular_SpatialVarianceEstimation.cs.hlsl deleted file mode 100644 index f8c33e6..0000000 --- a/Source/Shaders/RELAX_Specular_SpatialVarianceEstimation.cs.hlsl +++ /dev/null @@ -1,196 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_SpatialVarianceEstimation.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -#define THREAD_GROUP_SIZE 16 -#define SKIRT 2 - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -groupshared float4 sharedSpecularAnd2ndMoment[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; -groupshared float4 sharedNormalViewZ[THREAD_GROUP_SIZE + SKIRT * 2][THREAD_GROUP_SIZE + SKIRT * 2]; - -float computeDepthWeight(float depthCenter, float depthP, float depthThreshold) -{ - return 1; -} - -float computeNormalWeight(float3 normalCenter, float3 normalP, float phiNormal) -{ - return phiNormal == 0.0f ? 1.0f : pow(saturate(dot(normalCenter, normalP)), phiNormal); -} - -[numthreads(THREAD_GROUP_SIZE, THREAD_GROUP_SIZE, 1)] -NRD_EXPORT void NRD_CS_MAIN(uint3 dispatchThreadId : SV_DispatchThreadId, uint3 groupThreadId : SV_GroupThreadId, uint3 groupId : SV_GroupId) -{ - const int2 ipos = dispatchThreadId.xy; - - // Populating shared memory - uint linearThreadIndex = groupThreadId.y * THREAD_GROUP_SIZE + groupThreadId.x; - uint newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - uint newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - uint blockXStart = groupId.x * THREAD_GROUP_SIZE; - uint blockYStart = groupId.y * THREAD_GROUP_SIZE; - - // First stage - int ox = newIdxX; - int oy = newIdxY; - int xx = blockXStart + newIdxX - SKIRT; - int yy = blockYStart + newIdxY - SKIRT; - - float4 specular = 0; - float3 normal = 0; - float viewZ = 0; - - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specular = gSpecularIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZ[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedSpecularAnd2ndMoment[oy][ox] = specular; - sharedNormalViewZ[oy][ox] = float4(normal, viewZ); - - // Second stage - linearThreadIndex += THREAD_GROUP_SIZE * THREAD_GROUP_SIZE; - newIdxX = linearThreadIndex % (THREAD_GROUP_SIZE + SKIRT * 2); - newIdxY = linearThreadIndex / (THREAD_GROUP_SIZE + SKIRT * 2); - - ox = newIdxX; - oy = newIdxY; - xx = blockXStart + newIdxX - SKIRT; - yy = blockYStart + newIdxY - SKIRT; - - specular = 0; - normal = 0; - viewZ = 0; - - if (linearThreadIndex < (THREAD_GROUP_SIZE + SKIRT * 2) * (THREAD_GROUP_SIZE + SKIRT * 2)) - { - if ((xx >= 0) && (yy >= 0) && (xx < (int)gRectSize.x) && (yy < (int)gRectSize.y)) - { - specular = gSpecularIllumination[int2(xx, yy)]; - normal = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[int2(xx, yy)]).rgb; - viewZ = gViewZ[int2(xx, yy)] / NRD_FP16_VIEWZ_SCALE; - } - sharedSpecularAnd2ndMoment[oy][ox] = specular; - sharedNormalViewZ[oy][ox] = float4(normal, viewZ); - } - - // Ensuring all the writes to shared memory are done by now - GroupMemoryBarrierWithGroupSync(); - - // - // Shared memory is populated now and can be used for filtering - // - - int2 sharedMemoryCenterIndex = groupThreadId.xy + int2(SKIRT, SKIRT); - - // Repacking normal and roughness to prev normal roughness to be used in the next frame - float4 normalRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gNormalRoughness[ipos]); - gOutNormalRoughness[ipos] = PackPrevNormalRoughness(normalRoughness); - - // Using diffuse history length for spatial variance estimation - float historyLength = 255.0 * gHistoryLength[ipos]; - - float4 centerSpecularAnd2ndMoment = sharedSpecularAnd2ndMoment[sharedMemoryCenterIndex.y][sharedMemoryCenterIndex.x]; - float3 centerSpecularIllumination = centerSpecularAnd2ndMoment.rgb; - float centerSpecular1stMoment = STL::Color::Luminance(centerSpecularIllumination); - float centerSpecular2ndMoment = centerSpecularAnd2ndMoment.a; - - [branch] - if (historyLength >= float(gHistoryThreshold)) - { - // If we have enough temporal history available, - // we pass illumination data unmodified - // and calculate variance based on temporally accumulated moments - float specularVariance = centerSpecular2ndMoment - centerSpecular1stMoment * centerSpecular1stMoment; - - gOutSpecularIlluminationAndVariance[ipos] = float4(centerSpecularIllumination, specularVariance); - return; - } - - float4 centerNormalViewZ = sharedNormalViewZ[sharedMemoryCenterIndex.y][sharedMemoryCenterIndex.x]; - float3 centerNormal = centerNormalViewZ.xyz; - float centerViewZ = centerNormalViewZ.a; - - // Early out if linearZ is beyond denoising range - [branch] - if (centerViewZ > gDenoisingRange) - { - return; - } - - float sumWSpecularIllumination = 0; - float3 sumSpecularIllumination = 0; - - float sumSpecular1stMoment = 0; - float sumSpecular2ndMoment = 0; - - // Compute first and second moment spatially. This code also applies cross-bilateral - // filtering on the input illumination. - [unroll] - for (int cy = -2; cy <= 2; cy++) - { - [unroll] - for (int cx = -2; cx <= 2; cx++) - { - int2 sharedMemoryIndex = groupThreadId.xy + int2(SKIRT + cx, SKIRT + cy); - - // Fetching sample data - float3 sampleNormal = sharedNormalViewZ[sharedMemoryIndex.y][sharedMemoryIndex.x].rgb; - - float4 sampleSpecular = sharedSpecularAnd2ndMoment[sharedMemoryIndex.y][sharedMemoryIndex.x]; - float3 sampleSpecularIllumination = sampleSpecular.rgb; - float sampleSpecular1stMoment = STL::Color::Luminance(sampleSpecularIllumination); - float sampleSpecular2ndMoment = sampleSpecular.a; - - - // Calculating weights - float depthW = 1.0;// TODO: should we take in account depth here? - float normalW = computeNormalWeight(centerNormal, sampleNormal, gPhiNormal); - - float specularW = normalW * depthW; - - // Accumulating - sumWSpecularIllumination += specularW; - sumSpecularIllumination += sampleSpecularIllumination.rgb * specularW; - sumSpecular1stMoment += sampleSpecular1stMoment * specularW; - sumSpecular2ndMoment += sampleSpecular2ndMoment * specularW; - } - } - - // Clamp sum to >0 to avoid NaNs. - sumWSpecularIllumination = max(sumWSpecularIllumination, 1e-6f); - - sumSpecularIllumination /= sumWSpecularIllumination; - sumSpecular1stMoment /= sumWSpecularIllumination; - sumSpecular2ndMoment /= sumWSpecularIllumination; - - // compute variance using the first and second moments - float specularVariance = abs(sumSpecular2ndMoment - sumSpecular1stMoment * sumSpecular1stMoment); - - // give the variance a boost for the first frames - float boost = max(1.0, 4.0 / (historyLength + 1.0)); - specularVariance *= boost; - - gOutSpecularIlluminationAndVariance[ipos] = float4(sumSpecularIllumination, specularVariance); -} diff --git a/Source/Shaders/RELAX_Specular_SplitScreen.cs.hlsl b/Source/Shaders/RELAX_Specular_SplitScreen.cs.hlsl deleted file mode 100644 index 7fc8dcf..0000000 --- a/Source/Shaders/RELAX_Specular_SplitScreen.cs.hlsl +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. - -NVIDIA CORPORATION and its licensors retain all intellectual property -and proprietary rights in and to this software, related documentation -and any modifications thereto. Any use, reproduction, disclosure or -distribution of this software and related documentation without an express -license agreement from NVIDIA CORPORATION is strictly prohibited. -*/ - -#include "NRD.hlsli" -#include "STL.hlsli" -#include "RELAX_Specular_SplitScreen.resources.hlsli" - -NRD_DECLARE_CONSTANTS - -#include "NRD_Common.hlsli" -NRD_DECLARE_SAMPLERS -#include "RELAX_Common.hlsli" - -NRD_DECLARE_INPUT_TEXTURES -NRD_DECLARE_OUTPUT_TEXTURES - -[numthreads( 16, 16, 1)] -NRD_EXPORT void NRD_CS_MAIN( uint2 pixelPos : SV_DispatchThreadId) -{ - float2 pixelUv = float2( pixelPos + 0.5 ) * gInvRectSize; - uint2 pixelPosUser = gRectOrigin + pixelPos; - - if( pixelUv.x > gSplitScreen ) - return; - - float viewZ = gIn_ViewZ[ pixelPosUser ]; - - uint2 checkerboardPos = pixelPos; - - checkerboardPos.x = pixelPos.x >> (gSpecularCheckerboard != 2 ? 1 : 0); - float3 specResult = gIn_Spec[gRectOrigin + checkerboardPos]; - gOut_Spec[pixelPos] = specResult * float(viewZ < gDenoisingRange); -} diff --git a/Source/Shaders/SIGMA_Shadow_Blur.cs.hlsl b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_Blur.cs.hlsl similarity index 89% rename from Source/Shaders/SIGMA_Shadow_Blur.cs.hlsl rename to Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_Blur.cs.hlsl index 178d969..6ccee78 100644 --- a/Source/Shaders/SIGMA_Shadow_Blur.cs.hlsl +++ b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_Blur.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "SIGMA_Shadow_Blur.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_Blur.hlsli" diff --git a/Source/Shaders/SIGMA_Shadow_ClassifyTiles.cs.hlsl b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.cs.hlsl similarity index 88% rename from Source/Shaders/SIGMA_Shadow_ClassifyTiles.cs.hlsl rename to Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.cs.hlsl index e2908c1..6d3ea04 100644 --- a/Source/Shaders/SIGMA_Shadow_ClassifyTiles.cs.hlsl +++ b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "SIGMA_Shadow_ClassifyTiles.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.hlsli" diff --git a/Source/Shaders/SIGMA_Shadow_PreBlur.cs.hlsl b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_PreBlur.cs.hlsl similarity index 90% rename from Source/Shaders/SIGMA_Shadow_PreBlur.cs.hlsl rename to Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_PreBlur.cs.hlsl index 09d4f08..a92c424 100644 --- a/Source/Shaders/SIGMA_Shadow_PreBlur.cs.hlsl +++ b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_PreBlur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define SIGMA_FIRST_PASS -#include "SIGMA_Shadow_Blur.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_Blur.hlsli" diff --git a/Source/Shaders/SIGMA_Shadow_SmoothTiles.cs.hlsl b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_SmoothTiles.cs.hlsl similarity index 96% rename from Source/Shaders/SIGMA_Shadow_SmoothTiles.cs.hlsl rename to Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_SmoothTiles.cs.hlsl index b6b147f..c332706 100644 --- a/Source/Shaders/SIGMA_Shadow_SmoothTiles.cs.hlsl +++ b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_SmoothTiles.cs.hlsl @@ -10,7 +10,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "SIGMA_Shadow_SmoothTiles.resources.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_SmoothTiles.resources.hlsli" NRD_DECLARE_CONSTANTS diff --git a/Source/Shaders/SIGMA_Shadow_SplitScreen.cs.hlsl b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_SplitScreen.cs.hlsl similarity index 88% rename from Source/Shaders/SIGMA_Shadow_SplitScreen.cs.hlsl rename to Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_SplitScreen.cs.hlsl index 7bbf2c9..bf78477 100644 --- a/Source/Shaders/SIGMA_Shadow_SplitScreen.cs.hlsl +++ b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_SplitScreen.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "SIGMA_Shadow_SplitScreen.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_SplitScreen.hlsli" diff --git a/Source/Shaders/SIGMA_Shadow_TemporalStabilization.cs.hlsl b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.cs.hlsl similarity index 86% rename from Source/Shaders/SIGMA_Shadow_TemporalStabilization.cs.hlsl rename to Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.cs.hlsl index 32a96ab..0595003 100644 --- a/Source/Shaders/SIGMA_Shadow_TemporalStabilization.cs.hlsl +++ b/Source/Shaders/SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.cs.hlsl @@ -8,4 +8,4 @@ distribution of this software and related documentation without an express license agreement from NVIDIA CORPORATION is strictly prohibited. */ -#include "SIGMA_Shadow_TemporalStabilization.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.hlsli" diff --git a/Source/Shaders/SIGMA_ShadowTranslucency_Blur.cs.hlsl b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_Blur.cs.hlsl similarity index 90% rename from Source/Shaders/SIGMA_ShadowTranslucency_Blur.cs.hlsl rename to Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_Blur.cs.hlsl index 078cb8b..0ad6302 100644 --- a/Source/Shaders/SIGMA_ShadowTranslucency_Blur.cs.hlsl +++ b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_Blur.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define SIGMA_TRANSLUCENT -#include "SIGMA_Shadow_Blur.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_Blur.hlsli" diff --git a/Source/Shaders/SIGMA_ShadowTranslucency_ClassifyTiles.cs.hlsl b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_ClassifyTiles.cs.hlsl similarity index 88% rename from Source/Shaders/SIGMA_ShadowTranslucency_ClassifyTiles.cs.hlsl rename to Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_ClassifyTiles.cs.hlsl index d7cef97..3d9bc5f 100644 --- a/Source/Shaders/SIGMA_ShadowTranslucency_ClassifyTiles.cs.hlsl +++ b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_ClassifyTiles.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define SIGMA_TRANSLUCENT -#include "SIGMA_Shadow_ClassifyTiles.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_ClassifyTiles.hlsli" diff --git a/Source/Shaders/SIGMA_ShadowTranslucency_PreBlur.cs.hlsl b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_PreBlur.cs.hlsl similarity index 90% rename from Source/Shaders/SIGMA_ShadowTranslucency_PreBlur.cs.hlsl rename to Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_PreBlur.cs.hlsl index 8eb3415..fb89185 100644 --- a/Source/Shaders/SIGMA_ShadowTranslucency_PreBlur.cs.hlsl +++ b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_PreBlur.cs.hlsl @@ -11,4 +11,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define SIGMA_TRANSLUCENT #define SIGMA_FIRST_PASS -#include "SIGMA_Shadow_Blur.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_Blur.hlsli" diff --git a/Source/Shaders/SIGMA_ShadowTranslucency_SplitScreen.cs.hlsl b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_SplitScreen.cs.hlsl similarity index 89% rename from Source/Shaders/SIGMA_ShadowTranslucency_SplitScreen.cs.hlsl rename to Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_SplitScreen.cs.hlsl index 0a9ac0e..5432306 100644 --- a/Source/Shaders/SIGMA_ShadowTranslucency_SplitScreen.cs.hlsl +++ b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_SplitScreen.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define SIGMA_TRANSLUCENT -#include "SIGMA_Shadow_SplitScreen.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_SplitScreen.hlsli" diff --git a/Source/Shaders/SIGMA_ShadowTranslucency_TemporalStabilization.cs.hlsl b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_TemporalStabilization.cs.hlsl similarity index 87% rename from Source/Shaders/SIGMA_ShadowTranslucency_TemporalStabilization.cs.hlsl rename to Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_TemporalStabilization.cs.hlsl index fbed31c..9c99451 100644 --- a/Source/Shaders/SIGMA_ShadowTranslucency_TemporalStabilization.cs.hlsl +++ b/Source/Shaders/SIGMA_ShadowTranslucency/SIGMA_ShadowTranslucency_TemporalStabilization.cs.hlsl @@ -10,4 +10,4 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #define SIGMA_TRANSLUCENT -#include "SIGMA_Shadow_TemporalStabilization.hlsli" +#include "SIGMA_Shadow/SIGMA_Shadow_TemporalStabilization.hlsli" diff --git a/Source/Shaders/NRD_Clear_f.cs.hlsl b/Source/Shaders/Shared/NRD_Clear_f.cs.hlsl similarity index 92% rename from Source/Shaders/NRD_Clear_f.cs.hlsl rename to Source/Shaders/Shared/NRD_Clear_f.cs.hlsl index 38cd04f..949f280 100644 --- a/Source/Shaders/NRD_Clear_f.cs.hlsl +++ b/Source/Shaders/Shared/NRD_Clear_f.cs.hlsl @@ -9,7 +9,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. */ #include "NRD.hlsli" -#include "NRD_Clear_f.resources.hlsli" +#include "Shared/NRD_Clear_f.resources.hlsli" NRD_DECLARE_OUTPUT_TEXTURES diff --git a/Source/Shaders/NRD_Clear_ui.cs.hlsl b/Source/Shaders/Shared/NRD_Clear_ui.cs.hlsl similarity index 92% rename from Source/Shaders/NRD_Clear_ui.cs.hlsl rename to Source/Shaders/Shared/NRD_Clear_ui.cs.hlsl index ca26864..9d9fb3f 100644 --- a/Source/Shaders/NRD_Clear_ui.cs.hlsl +++ b/Source/Shaders/Shared/NRD_Clear_ui.cs.hlsl @@ -9,7 +9,7 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. */ #include "NRD.hlsli" -#include "NRD_Clear_ui.resources.hlsli" +#include "Shared/NRD_Clear_ui.resources.hlsli" NRD_DECLARE_OUTPUT_TEXTURES diff --git a/Source/Shaders/NRD_MipGeneration_Float2.cs.hlsl b/Source/Shaders/Shared/NRD_MipGeneration_Float2.cs.hlsl similarity index 68% rename from Source/Shaders/NRD_MipGeneration_Float2.cs.hlsl rename to Source/Shaders/Shared/NRD_MipGeneration_Float2.cs.hlsl index 0e6b8c9..fdd01cb 100644 --- a/Source/Shaders/NRD_MipGeneration_Float2.cs.hlsl +++ b/Source/Shaders/Shared/NRD_MipGeneration_Float2.cs.hlsl @@ -10,10 +10,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "NRD_MipGeneration_Float2.resources.hlsli" +#include "Shared/NRD_MipGeneration_Float2.resources.hlsli" NRD_DECLARE_CONSTANTS +#include "NRD_Common.hlsli" + NRD_DECLARE_INPUT_TEXTURES NRD_DECLARE_OUTPUT_TEXTURES @@ -21,19 +23,19 @@ groupshared float2 s_TempA[ 17 ][ 17 ]; #define DO_REDUCTION \ { \ - float4 w = float4( abs( float4( a00.y, a10.y, a01.y, a11.y ) / NRD_FP16_VIEWZ_SCALE ) < gInf ); \ + float4 w = float4( abs( float4( a00.y, a10.y, a01.y, a11.y ) ) < gDenoisingRange * NRD_FP16_VIEWZ_SCALE ); \ float sum = dot( w, 1.0 ); \ - float invSum = STL::Math::PositiveRcp( sum ); \ + w *= rcp( sum + 1e-7 ); \ a = a00 * w.x + a10 * w.y + a01 * w.z + a11 * w.w; \ - a *= invSum; \ a.y = sum == 0.0 ? NRD_FP16_MAX : a.y; \ } -[numthreads( 16, 16, 1 )] +[numthreads( GROUP_X, GROUP_Y, 1 )] NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_GroupIndex ) { - uint2 localID = uint2( threadID & 15, threadID >> 4 ); - uint2 globalID = groupID * 16 + localID; + uint2 DIMS = uint2( GROUP_X, GROUP_Y ); + uint2 localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + uint2 globalID = groupID * DIMS + localID; uint2 coord = globalID << 1; uint4 coords = min( coord.xyxy + uint4( 0, 0, 1, 1 ), gRectSize.xyxy - 1 ); @@ -52,10 +54,11 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou gOut_A_x2[ globalID ] = a; - if( threadID < 64 ) + DIMS >>= 1; + if( threadID < DIMS.x * DIMS.y ) { - localID = uint2( threadID & 7, threadID >> 3 ); - globalID = groupID * 8 + localID; + localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + globalID = groupID * DIMS + localID; uint2 id = localID << 1; uint2 id1 = id + 1; @@ -75,10 +78,11 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou GroupMemoryBarrierWithGroupSync( ); - if( threadID < 16 ) + DIMS >>= 1; + if( threadID < DIMS.x * DIMS.y ) { - localID = uint2( threadID & 3, threadID >> 2 ); - globalID = groupID * 4 + localID; + localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + globalID = groupID * DIMS + localID; uint2 id = localID << 2; uint2 id1 = id + 2; @@ -95,24 +99,4 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou localID <<= 2; s_TempA[ localID.y ][ localID.x ] = a; } - - GroupMemoryBarrier( ); - - if( threadID < 4 ) - { - localID = uint2( threadID & 1, threadID >> 1 ); - globalID = groupID * 2 + localID; - - uint2 id = localID << 3; - uint2 id1 = id + 4; - - a00 = s_TempA[ id.y ][ id.x ]; - a10 = s_TempA[ id.y ][ id1.x ]; - a01 = s_TempA[ id1.y ][ id.x ]; - a11 = s_TempA[ id1.y ][ id1.x ]; - - DO_REDUCTION; - - gOut_A_x16[ globalID ] = a; - } } diff --git a/Source/Shaders/NRD_MipGeneration_Float2_Float2.cs.hlsl b/Source/Shaders/Shared/NRD_MipGeneration_Float2_Float2.cs.hlsl similarity index 71% rename from Source/Shaders/NRD_MipGeneration_Float2_Float2.cs.hlsl rename to Source/Shaders/Shared/NRD_MipGeneration_Float2_Float2.cs.hlsl index dbc955b..bec03ad 100644 --- a/Source/Shaders/NRD_MipGeneration_Float2_Float2.cs.hlsl +++ b/Source/Shaders/Shared/NRD_MipGeneration_Float2_Float2.cs.hlsl @@ -10,10 +10,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "NRD_MipGeneration_Float2_Float2.resources.hlsli" +#include "Shared/NRD_MipGeneration_Float2_Float2.resources.hlsli" NRD_DECLARE_CONSTANTS +#include "NRD_Common.hlsli" + NRD_DECLARE_INPUT_TEXTURES NRD_DECLARE_OUTPUT_TEXTURES @@ -22,22 +24,21 @@ groupshared float2 s_TempB[ 17 ][ 17 ]; #define DO_REDUCTION \ { \ - float4 w = float4( abs( float4( a00.y, a10.y, a01.y, a11.y ) / NRD_FP16_VIEWZ_SCALE ) < gInf ); \ + float4 w = float4( abs( float4( a00.y, a10.y, a01.y, a11.y ) ) < gDenoisingRange * NRD_FP16_VIEWZ_SCALE ); \ float sum = dot( w, 1.0 ); \ - float invSum = STL::Math::PositiveRcp( sum ); \ + w *= rcp( sum + 1e-7 ); \ a = a00 * w.x + a10 * w.y + a01 * w.z + a11 * w.w; \ - a *= invSum; \ a.y = sum == 0.0 ? NRD_FP16_MAX : a.y; \ b = b00 * w.x + b10 * w.y + b01 * w.z + b11 * w.w; \ - b *= invSum; \ b.y = sum == 0.0 ? NRD_FP16_MAX : b.y; \ } -[numthreads( 16, 16, 1 )] +[numthreads( GROUP_X, GROUP_Y, 1 )] NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_GroupIndex ) { - uint2 localID = uint2( threadID & 15, threadID >> 4 ); - uint2 globalID = groupID * 16 + localID; + uint2 DIMS = uint2( GROUP_X, GROUP_Y ); + uint2 localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + uint2 globalID = groupID * DIMS + localID; uint2 coord = globalID << 1; uint4 coords = min( coord.xyxy + uint4( 0, 0, 1, 1 ), gRectSize.xyxy - 1 ); @@ -64,10 +65,11 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou gOut_A_x2[ globalID ] = a; gOut_B_x2[ globalID ] = b; - if( threadID < 64 ) + DIMS >>= 1; + if( threadID < DIMS.x * DIMS.y ) { - localID = uint2( threadID & 7, threadID >> 3 ); - globalID = groupID * 8 + localID; + localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + globalID = groupID * DIMS + localID; uint2 id = localID << 1; uint2 id1 = id + 1; @@ -94,10 +96,11 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou GroupMemoryBarrierWithGroupSync( ); - if( threadID < 16 ) + DIMS >>= 1; + if( threadID < DIMS.x * DIMS.y ) { - localID = uint2( threadID & 3, threadID >> 2 ); - globalID = groupID * 4 + localID; + localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + globalID = groupID * DIMS + localID; uint2 id = localID << 2; uint2 id1 = id + 2; @@ -121,30 +124,4 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou s_TempA[ localID.y ][ localID.x ] = a; s_TempB[ localID.y ][ localID.x ] = b; } - - GroupMemoryBarrier( ); - - if( threadID < 4 ) - { - localID = uint2( threadID & 1, threadID >> 1 ); - globalID = groupID * 2 + localID; - - uint2 id = localID << 3; - uint2 id1 = id + 4; - - a00 = s_TempA[ id.y ][ id.x ]; - a10 = s_TempA[ id.y ][ id1.x ]; - a01 = s_TempA[ id1.y ][ id.x ]; - a11 = s_TempA[ id1.y ][ id1.x ]; - - b00 = s_TempB[ id.y ][ id.x ]; - b10 = s_TempB[ id.y ][ id1.x ]; - b01 = s_TempB[ id1.y ][ id.x ]; - b11 = s_TempB[ id1.y ][ id1.x ]; - - DO_REDUCTION; - - gOut_A_x16[ globalID ] = a; - gOut_B_x16[ globalID ] = b; - } } diff --git a/Source/Shaders/NRD_MipGeneration_Float4_Float.cs.hlsl b/Source/Shaders/Shared/NRD_MipGeneration_Float4_Float.cs.hlsl similarity index 69% rename from Source/Shaders/NRD_MipGeneration_Float4_Float.cs.hlsl rename to Source/Shaders/Shared/NRD_MipGeneration_Float4_Float.cs.hlsl index f055f5e..29a5281 100644 --- a/Source/Shaders/NRD_MipGeneration_Float4_Float.cs.hlsl +++ b/Source/Shaders/Shared/NRD_MipGeneration_Float4_Float.cs.hlsl @@ -10,10 +10,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "NRD_MipGeneration_Float4_Float.resources.hlsli" +#include "Shared/NRD_MipGeneration_Float4_Float.resources.hlsli" NRD_DECLARE_CONSTANTS +#include "NRD_Common.hlsli" + NRD_DECLARE_INPUT_TEXTURES NRD_DECLARE_OUTPUT_TEXTURES @@ -22,21 +24,20 @@ groupshared float s_TempZ[ 17 ][ 17 ]; #define DO_REDUCTION \ { \ - float4 w = float4( abs( float4( z00, z10, z01, z11 ) / NRD_FP16_VIEWZ_SCALE ) < gInf ); \ + float4 w = float4( abs( float4( z00, z10, z01, z11 ) ) < gDenoisingRange * NRD_FP16_VIEWZ_SCALE ); \ float sum = dot( w, 1.0 ); \ - float invSum = STL::Math::PositiveRcp( sum ); \ + w *= rcp( sum + 1e-7 ); \ a = a00 * w.x + a10 * w.y + a01 * w.z + a11 * w.w; \ - a *= invSum; \ z = z00 * w.x + z10 * w.y + z01 * w.z + z11 * w.w; \ - z *= invSum; \ z = sum == 0.0 ? NRD_FP16_MAX : z; \ } -[numthreads( 16, 16, 1 )] +[numthreads( GROUP_X, GROUP_Y, 1 )] NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_GroupIndex ) { - uint2 localID = uint2( threadID & 15, threadID >> 4 ); - uint2 globalID = groupID * 16 + localID; + uint2 DIMS = uint2( GROUP_X, GROUP_Y ); + uint2 localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + uint2 globalID = groupID * DIMS + localID; uint2 coord = globalID << 1; uint4 coords = min( coord.xyxy + uint4( 0, 0, 1, 1 ), gRectSize.xyxy - 1 ); @@ -63,10 +64,11 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou gOut_A_x2[ globalID ] = a; gOut_ScaledViewZ_x2[ globalID ] = z; - if( threadID < 64 ) + DIMS >>= 1; + if( threadID < DIMS.x * DIMS.y ) { - localID = uint2( threadID & 7, threadID >> 3 ); - globalID = groupID * 8 + localID; + localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + globalID = groupID * DIMS + localID; uint2 id = localID << 1; uint2 id1 = id + 1; @@ -93,10 +95,11 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou GroupMemoryBarrierWithGroupSync( ); - if( threadID < 16 ) + DIMS >>= 1; + if( threadID < DIMS.x * DIMS.y ) { - localID = uint2( threadID & 3, threadID >> 2 ); - globalID = groupID * 4 + localID; + localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + globalID = groupID * DIMS + localID; uint2 id = localID << 2; uint2 id1 = id + 2; @@ -120,30 +123,4 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou gOut_A_x8[ globalID ] = a; gOut_ScaledViewZ_x8[ globalID ] = z; } - - GroupMemoryBarrier( ); - - if( threadID < 4 ) - { - localID = uint2( threadID & 1, threadID >> 1 ); - globalID = groupID * 2 + localID; - - uint2 id = localID << 3; - uint2 id1 = id + 4; - - a00 = s_TempA[ id.y ][ id.x ]; - a10 = s_TempA[ id.y ][ id1.x ]; - a01 = s_TempA[ id1.y ][ id.x ]; - a11 = s_TempA[ id1.y ][ id1.x ]; - - z00 = s_TempZ[ id.y ][ id.x ]; - z10 = s_TempZ[ id.y ][ id1.x ]; - z01 = s_TempZ[ id1.y ][ id.x ]; - z11 = s_TempZ[ id1.y ][ id1.x ]; - - DO_REDUCTION; - - gOut_A_x16[ globalID ] = a; - gOut_ScaledViewZ_x16[ globalID ] = z; - } } diff --git a/Source/Shaders/NRD_MipGeneration_Float4_Float4_Float.cs.hlsl b/Source/Shaders/Shared/NRD_MipGeneration_Float4_Float4_Float.cs.hlsl similarity index 71% rename from Source/Shaders/NRD_MipGeneration_Float4_Float4_Float.cs.hlsl rename to Source/Shaders/Shared/NRD_MipGeneration_Float4_Float4_Float.cs.hlsl index 2f5a38a..8a422aa 100644 --- a/Source/Shaders/NRD_MipGeneration_Float4_Float4_Float.cs.hlsl +++ b/Source/Shaders/Shared/NRD_MipGeneration_Float4_Float4_Float.cs.hlsl @@ -10,10 +10,12 @@ license agreement from NVIDIA CORPORATION is strictly prohibited. #include "NRD.hlsli" #include "STL.hlsli" -#include "NRD_MipGeneration_Float4_Float4_Float.resources.hlsli" +#include "Shared/NRD_MipGeneration_Float4_Float4_Float.resources.hlsli" NRD_DECLARE_CONSTANTS +#include "NRD_Common.hlsli" + NRD_DECLARE_INPUT_TEXTURES NRD_DECLARE_OUTPUT_TEXTURES @@ -23,23 +25,21 @@ groupshared float s_TempZ[ 17 ][ 17 ]; #define DO_REDUCTION \ { \ - float4 w = float4( abs( float4( z00, z10, z01, z11 ) / NRD_FP16_VIEWZ_SCALE ) < gInf ); \ + float4 w = float4( abs( float4( z00, z10, z01, z11 ) ) < gDenoisingRange * NRD_FP16_VIEWZ_SCALE ); \ float sum = dot( w, 1.0 ); \ - float invSum = STL::Math::PositiveRcp( sum ); \ + w *= rcp( sum + 1e-7 ); \ a = a00 * w.x + a10 * w.y + a01 * w.z + a11 * w.w; \ - a *= invSum; \ b = b00 * w.x + b10 * w.y + b01 * w.z + b11 * w.w; \ - b *= invSum; \ z = z00 * w.x + z10 * w.y + z01 * w.z + z11 * w.w; \ - z *= invSum; \ z = sum == 0.0 ? NRD_FP16_MAX : z; \ } -[numthreads( 16, 16, 1 )] +[numthreads( GROUP_X, GROUP_Y, 1 )] NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_GroupIndex ) { - uint2 localID = uint2( threadID & 15, threadID >> 4 ); - uint2 globalID = groupID * 16 + localID; + uint2 DIMS = uint2( GROUP_X, GROUP_Y ); + uint2 localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + uint2 globalID = groupID * DIMS + localID; uint2 coord = globalID << 1; uint4 coords = min( coord.xyxy + uint4( 0, 0, 1, 1 ), gRectSize.xyxy - 1 ); @@ -74,10 +74,11 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou gOut_B_x2[ globalID ] = b; gOut_ScaledViewZ_x2[ globalID ] = z; - if( threadID < 64 ) + DIMS >>= 1; + if( threadID < DIMS.x * DIMS.y ) { - localID = uint2( threadID & 7, threadID >> 3 ); - globalID = groupID * 8 + localID; + localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + globalID = groupID * DIMS + localID; uint2 id = localID << 1; uint2 id1 = id + 1; @@ -111,10 +112,11 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou GroupMemoryBarrierWithGroupSync( ); - if( threadID < 16 ) + DIMS >>= 1; + if( threadID < DIMS.x * DIMS.y ) { - localID = uint2( threadID & 3, threadID >> 2 ); - globalID = groupID * 4 + localID; + localID = uint2( threadID % DIMS.x, threadID / DIMS.x ); + globalID = groupID * DIMS + localID; uint2 id = localID << 2; uint2 id1 = id + 2; @@ -145,36 +147,4 @@ NRD_EXPORT void NRD_CS_MAIN( uint2 groupID : SV_GroupId, uint threadID : SV_Grou gOut_B_x8[ globalID ] = b; gOut_ScaledViewZ_x8[ globalID ] = z; } - - GroupMemoryBarrier( ); - - if( threadID < 4 ) - { - localID = uint2( threadID & 1, threadID >> 1 ); - globalID = groupID * 2 + localID; - - uint2 id = localID << 3; - uint2 id1 = id + 4; - - a00 = s_TempA[ id.y ][ id.x ]; - a10 = s_TempA[ id.y ][ id1.x ]; - a01 = s_TempA[ id1.y ][ id.x ]; - a11 = s_TempA[ id1.y ][ id1.x ]; - - b00 = s_TempB[ id.y ][ id.x ]; - b10 = s_TempB[ id.y ][ id1.x ]; - b01 = s_TempB[ id1.y ][ id.x ]; - b11 = s_TempB[ id1.y ][ id1.x ]; - - z00 = s_TempZ[ id.y ][ id.x ]; - z10 = s_TempZ[ id.y ][ id1.x ]; - z01 = s_TempZ[ id1.y ][ id.x ]; - z11 = s_TempZ[ id1.y ][ id1.x ]; - - DO_REDUCTION; - - gOut_A_x16[ globalID ] = a; - gOut_B_x16[ globalID ] = b; - gOut_ScaledViewZ_x16[ globalID ] = z; - } } diff --git a/Source/Shaders/SpecularReflectionMv/SpecularReflectionMv_Compute.cs.hlsl b/Source/Shaders/SpecularReflectionMv/SpecularReflectionMv_Compute.cs.hlsl new file mode 100644 index 0000000..2fdfd44 --- /dev/null +++ b/Source/Shaders/SpecularReflectionMv/SpecularReflectionMv_Compute.cs.hlsl @@ -0,0 +1,161 @@ +/* +Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + +NVIDIA CORPORATION and its licensors retain all intellectual property +and proprietary rights in and to this software, related documentation +and any modifications thereto. Any use, reproduction, disclosure or +distribution of this software and related documentation without an express +license agreement from NVIDIA CORPORATION is strictly prohibited. +*/ + +#include "NRD.hlsli" +#include "STL.hlsli" +#include "SpecularReflectionMv/SpecularReflectionMv_Compute.resources.hlsli" + +NRD_DECLARE_CONSTANTS + +#include "NRD_Common.hlsli" + +NRD_DECLARE_SAMPLERS + +NRD_DECLARE_INPUT_TEXTURES +NRD_DECLARE_OUTPUT_TEXTURES + +// TODO: The below utility functions are copied over from REBLUR_Common.hlsli, perhaps they should be moved to something like NRD_Common.hlsli? +float3 GetViewVector(float3 X, bool isViewSpace = false) +{ + return gOrthoMode == 0.0 ? normalize(-X) : (isViewSpace ? float3(0, 0, -1) : gViewVectorWorld.xyz); +} + +float4 GetXvirtual( float3 X, float3 V, float NoV, float roughness, float hitDist, float viewZ, float c ) +{ + /* + The lens equation: + - c - local curvature + - C - curvature = c / edgeLength + - O - object height + - I - image height + - F - focal distance + [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 ) + + Real curvature from local curvature: + edgeLength = pixelSize / NoV + C = c * NoV / pixelSize + */ + + // TODO: better use "edge" from EstimateCurvature? + float pixelSize = PixelRadiusToWorld( gUnproject, gOrthoMode, 1.0, viewZ ); + c *= NoV / pixelSize; + + float denom = 0.5 + c * hitDist; + denom = abs( denom ) < 1e-6 ? 0.5 : denom; // fixing imprecision problems + float hitDistFocused = 0.5 * hitDist / denom; + + // "saturate" is needed to clamp values > 1 if curvature is negative + float compressionRatio = saturate( ( abs( hitDistFocused ) + 1e-6 ) / ( hitDist + 1e-6 ) ); + + // TODO: more complicated method is needed, because if elongation is very small X should become Xprev (signal starts to follow with surface motion) + float f = STL::ImportanceSampling::GetSpecularDominantFactor( NoV, roughness, STL_SPECULAR_DOMINANT_DIRECTION_G2); + float3 Xvirtual = X - V * hitDistFocused * f; + + return float4( Xvirtual, compressionRatio ); +} + +/* +Based on: +https://computergraphics.stackexchange.com/questions/1718/what-is-the-simplest-way-to-compute-principal-curvature-for-a-mesh-triangle + +curvature = 1 / R = localCurvature / edgeLength +localCurvature ( unsigned ) = length( N[i] - N ) +localCurvature ( signed ) = dot( N[i] - N, X[i] - X ) / length( X[i] - X ) +edgeLength = length( X[i] - X ) +To fit into 8-bits only local curvature is encoded +*/ + +float EstimateCurvature(float3 Ni, float3 Vi, float3 N, float3 X) +{ + float3 Xi = 0 + Vi * dot(X - 0, N) / dot(Vi, N); + float3 edge = Xi - X; + float curvature = dot(Ni - N, edge) * rsqrt(STL::Math::LengthSquared(edge)); + + // TODO: potentially imprecision mitigation is needed here... + + return curvature; +} + +[numthreads(GROUP_X, GROUP_Y, 1)] +NRD_EXPORT void NRD_CS_MAIN(uint2 pixelPos : SV_DispatchThreadId) +{ + float2 pixelUv = float2(pixelPos + 0.5) * gInvRectSize; + uint2 pixelPosUser = gRectOrigin + pixelPos; + + float viewZ = gIn_ViewZ[pixelPosUser]; + float4 normalAndRoughness = NRD_FrontEnd_UnpackNormalAndRoughness(gIn_Normal_Roughness[pixelPosUser]); + float3 motionVector = gIn_ObjectMotion[pixelPosUser] * gMotionVectorScale.xyy; + float hitDist = gIn_HitDist[pixelPosUser]; + + // Current position + float3 Xv = STL::Geometry::ReconstructViewPosition(pixelUv, gFrustum, viewZ, gOrthoMode); + float3 X = STL::Geometry::AffineTransform(gViewToWorld, Xv); + float3 V = GetViewVector(X); + float3 N = normalAndRoughness.xyz; + float roughness = normalAndRoughness.w; + + // Curvature + float3 Nflat = N; + float curvature = 0.f; + float curvatureSum = 0.f; + for (int dy = -1; dy <= 1; dy++) + { + for (int dx = -1; dx <= 1; dx++) + { + if (dx == 0 && dy == 0) + continue; + + float3 n = NRD_FrontEnd_UnpackNormalAndRoughness(gIn_Normal_Roughness[pixelPosUser + int2(dx, dy)]).xyz; + Nflat += n; + + float2 d = float2( dx, dy ); + float3 xv = STL::Geometry::ReconstructViewPosition( pixelUv + d * gInvRectSize, gFrustum, 1.0, gOrthoMode ); + float3 x = STL::Geometry::AffineTransform( gViewToWorld, xv ); + float3 v = GetViewVector( x ); + float c = EstimateCurvature( n, v, N, X ); + + float w = exp2( -0.5 * STL::Math::LengthSquared( d ) ); + curvature += c * w; + curvatureSum += w; + } + } + + curvature /= curvatureSum; + curvature *= STL::Math::LinearStep(0.0, NRD_ENCODING_ERRORS.y, abs(curvature)); + + float3 Navg = Nflat / 9.f; + float roughnessModified = STL::Filtering::GetModifiedRoughnessFromNormalVariance(roughness, Navg); + + // Virtual motion + float NoV = abs(dot(N, V)); + float4 Xvirtual = GetXvirtual(X, V, NoV, roughnessModified, hitDist, viewZ, curvature); + float2 pixelUvVirtualPrev = STL::Geometry::GetScreenUv(gWorldToClipPrev, Xvirtual.xyz, false); + + gOut_SpecularReflectionMv[pixelPos] = pixelUvVirtualPrev - pixelUv; +} diff --git a/Source/StdAllocator.h b/Source/StdAllocator.h index ab71ff6..9983f86 100644 --- a/Source/StdAllocator.h +++ b/Source/StdAllocator.h @@ -193,12 +193,6 @@ constexpr uint32_t GetCountOf(const std::array& v) return (uint32_t)v.size(); } -template -constexpr uint32_t GetOffsetOf(U T::*member) -{ - return (uint32_t)((const char*)&((T*)nullptr->*member) - (const char*)nullptr); -} - template constexpr void Construct(T* objects, size_t number, Args&&... args) { diff --git a/Source/Wrapper.cpp b/Source/Wrapper.cpp index 633a42f..6178428 100644 --- a/Source/Wrapper.cpp +++ b/Source/Wrapper.cpp @@ -32,7 +32,9 @@ constexpr std::array g_NrdSupportedMe nrd::Method::RELAX_DIFFUSE, nrd::Method::RELAX_SPECULAR, nrd::Method::RELAX_DIFFUSE_SPECULAR, - nrd::Method::REFERENCE + nrd::Method::REFERENCE, + nrd::Method::SPEC_REFLECTION_MV, + nrd::Method::DELTA_OPTIMIZATION_MV }; constexpr nrd::LibraryDesc g_NrdLibraryDesc = diff --git a/UPDATE.md b/UPDATE.md new file mode 100644 index 0000000..516a8fd --- /dev/null +++ b/UPDATE.md @@ -0,0 +1,28 @@ +# HOW TO UPDATE? + +This guide has been designed to simplify migration to a newer version. + +## v2.12 to v3.0 + +- `NRD_USE_MATERIAL_ID_AWARE_FILTERING` renamed to `NRD_USE_MATERIAL_ID` +- `NRD_NORMAL_ENCODING` simplified to `NRD_NORMAL_ENCODING_UNORM` and `NRD_NORMAL_ENCODING_OCT` +- `NRD_MATERIAL_ID_AWARE_FILTERING` renamed to `NRD_USE_MATERIAL_ID` +- changed parameters in `NRD_GetCorrectedHitDist` +- *REFERENCE*: + - denoiser input & output changed to dedicated `IN_RADIANCE` and `OUT_RADIANCE` +- *REBLUR*: + - settings collapsed to `ReblurSettings` shared across all *REBLUR* denoisers + - `LobeTrimmingParameters` renamed to `SpecularLobeTrimmingParameters` + - `normalWeightStrictness` replaced by `lobeAngleFraction` (a different value with similar meaning) + - `materialMask` replaced with `enableMaterialTestForDiffuse` and `enableMaterialTestForSpecular` + - exposed `minConvergedStateBaseRadiusScale` + - exposed `roughnessFraction` + - exposed `responsiveAccumulationRoughnessThreshold` + - exposed `inoutMix` + - exposed `enablePerformanceMode` +- *RELAX*: + - `rejectDiffuseHistoryNormalThreshold` renamed to `diffuseHistoryRejectionNormalThreshold` + - `enableSkipReprojectionTestWithoutMotion` renamed to `enableReprojectionTestSkippingWithoutMotion` + - `phiNormal` replaced by `diffuseLobeAngleFraction` (a different value with similar meaning) + - exposed `roughnessFraction` + - exposed `enableMaterialTest`