60 changed files with 3921 additions and 3113 deletions
-
57Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_accumulate_pass.hlsl
-
17Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_autogen_reactive_pass.hlsl
-
34Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_debug_view_pass.hlsl
-
2Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_debug_view_pass.hlsl.meta
-
59Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_luma_instability_pass.hlsl
-
2Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_luma_instability_pass.hlsl.meta
-
31Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_luma_pyramid_pass.hlsl
-
2Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_luma_pyramid_pass.hlsl.meta
-
44Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_prepare_inputs_pass.hlsl
-
2Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_prepare_inputs_pass.hlsl.meta
-
49Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_prepare_reactivity_pass.hlsl
-
7Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_prepare_reactivity_pass.hlsl.meta
-
24Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_rcas_pass.hlsl
-
52Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_shading_change_pass.hlsl
-
7Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_shading_change_pass.hlsl.meta
-
63Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_shading_change_pyramid_pass.hlsl
-
7Assets/Shaders/FSR3/shaders/ffx_fsr3upscaler_shading_change_pyramid_pass.hlsl.meta
-
154Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_common_types.h
-
14Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_core.h
-
338Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_core_cpu.h
-
65Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_core_cpu.h.meta
-
318Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_core_gpu_common.h
-
68Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_core_gpu_common_half.h
-
341Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_core_hlsl.h
-
33Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_core_portability.h
-
315Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_accumulate.h
-
882Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_glsl.h
-
27Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_glsl.h.meta
-
799Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h
-
379Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_common.h
-
65Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_compute_luminance_pyramid.h.meta
-
159Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_debug_view.h
-
27Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_debug_view.h.meta
-
259Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_depth_clip.h
-
65Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_depth_clip.h.meta
-
116Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_lock.h
-
65Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_lock.h.meta
-
115Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_luma_instability.h
-
27Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_luma_instability.h.meta
-
80Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_luma_pyramid.h
-
27Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_luma_pyramid.h.meta
-
107Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_postprocess_lock_status.h
-
65Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_postprocess_lock_status.h.meta
-
152Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_prepare_inputs.h
-
27Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_prepare_inputs.h.meta
-
270Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_prepare_reactivity.h
-
27Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_prepare_reactivity.h.meta
-
18Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_rcas.h
-
146Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_reconstruct_dilated_velocity_and_previous_depth.h
-
65Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_reconstruct_dilated_velocity_and_previous_depth.h.meta
-
111Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_reproject.h
-
106Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_resources.h
-
34Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_sample.h
-
68Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_shading_change.h
-
27Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_shading_change.h.meta
-
297Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_shading_change_pyramid.h
-
27Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_shading_change_pyramid.h.meta
-
191Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_upsample.h
-
56Assets/Shaders/FSR3/shaders/fsr3upscaler/fsr1/ffx_fsr1.h
-
43Assets/Shaders/FSR3/shaders/fsr3upscaler/spd/ffx_spd.h
@ -1,5 +1,5 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 98d2cbbda5e90dd4ebd1d70abbb63a09 |
|||
guid: 6e10b90cb8c2cd74dabb4a577faa7c67 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
@ -0,0 +1,59 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
#define FSR3UPSCALER_BIND_SRV_INPUT_EXPOSURE 0 |
|||
#define FSR3UPSCALER_BIND_SRV_DILATED_REACTIVE_MASKS 1 |
|||
#define FSR3UPSCALER_BIND_SRV_DILATED_MOTION_VECTORS 2 |
|||
#define FSR3UPSCALER_BIND_SRV_FRAME_INFO 3 |
|||
#define FSR3UPSCALER_BIND_SRV_LUMA_HISTORY 4 |
|||
#define FSR3UPSCALER_BIND_SRV_FARTHEST_DEPTH_MIP1 5 |
|||
#define FSR3UPSCALER_BIND_SRV_CURRENT_LUMA 6 |
|||
|
|||
#define FSR3UPSCALER_BIND_UAV_LUMA_HISTORY 0 |
|||
#define FSR3UPSCALER_BIND_UAV_LUMA_INSTABILITY 1 |
|||
|
|||
#define FSR3UPSCALER_BIND_CB_FSR3UPSCALER 0 |
|||
|
|||
#include "fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h" |
|||
#include "fsr3upscaler/ffx_fsr3upscaler_common.h" |
|||
#include "fsr3upscaler/ffx_fsr3upscaler_luma_instability.h" |
|||
|
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH 8 |
|||
#endif // #ifndef FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT 8 |
|||
#endif // FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_FSR3UPSCALER_NUM_THREADS |
|||
#define FFX_FSR3UPSCALER_NUM_THREADS [numthreads(FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH, FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT, FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_FSR3UPSCALER_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_FSR3UPSCALER_NUM_THREADS |
|||
FFX_FSR3UPSCALER_EMBED_ROOTSIG_CONTENT |
|||
void CS(int2 iDispatchThreadId : SV_DispatchThreadID) |
|||
{ |
|||
LumaInstability(iDispatchThreadId); |
|||
} |
|||
@ -1,5 +1,5 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 2d149b52ba0f5bb468a94a71dbbcb66f |
|||
guid: 78e3794a851a9c4409a622bc569b195d |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
@ -1,5 +1,5 @@ |
|||
fileFormatVersion: 2 |
|||
guid: bafb3726a76b97a49bb343d8a4323754 |
|||
guid: 781aaeb95f903984a905ef657085a673 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
@ -1,5 +1,5 @@ |
|||
fileFormatVersion: 2 |
|||
guid: da435b71cf57e2247b80ae0f0f86d1f8 |
|||
guid: 71725b1aad250484a83d8124d0d8bef1 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 38d0f427c34ecfa4bad25b31adc7d0f8 |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,52 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
#define FSR3UPSCALER_BIND_SRV_SPD_MIPS 0 |
|||
|
|||
#define FSR3UPSCALER_BIND_UAV_SHADING_CHANGE 0 |
|||
|
|||
#define FSR3UPSCALER_BIND_CB_FSR3UPSCALER 0 |
|||
|
|||
#include "fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h" |
|||
#include "fsr3upscaler/ffx_fsr3upscaler_common.h" |
|||
#include "fsr3upscaler/ffx_fsr3upscaler_shading_change.h" |
|||
|
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH 8 |
|||
#endif // #ifndef FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT 8 |
|||
#endif // #ifndef FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_FSR3UPSCALER_NUM_THREADS |
|||
#define FFX_FSR3UPSCALER_NUM_THREADS [numthreads(FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH, FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT, FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_FSR3UPSCALER_NUM_THREADS |
|||
|
|||
FFX_PREFER_WAVE64 |
|||
FFX_FSR3UPSCALER_NUM_THREADS |
|||
FFX_FSR3UPSCALER_EMBED_ROOTSIG_CONTENT |
|||
void CS(int2 iDispatchThreadId : SV_DispatchThreadID) |
|||
{ |
|||
ShadingChange(iDispatchThreadId); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 6edf1f8a51b98f84d858abb0cefb255f |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,63 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
#define FSR3UPSCALER_BIND_SRV_CURRENT_LUMA 0 |
|||
#define FSR3UPSCALER_BIND_SRV_PREVIOUS_LUMA 1 |
|||
#define FSR3UPSCALER_BIND_SRV_DILATED_MOTION_VECTORS 2 |
|||
#define FSR3UPSCALER_BIND_SRV_INPUT_EXPOSURE 3 |
|||
|
|||
|
|||
#define FSR3UPSCALER_BIND_UAV_SPD_GLOBAL_ATOMIC 0 |
|||
#define FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_0 1 |
|||
#define FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_1 2 |
|||
#define FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_2 3 |
|||
#define FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_3 4 |
|||
#define FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_4 5 |
|||
#define FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_5 6 |
|||
|
|||
|
|||
#define FSR3UPSCALER_BIND_CB_FSR3UPSCALER 0 |
|||
#define FSR3UPSCALER_BIND_CB_SPD 1 |
|||
|
|||
#include "fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h" |
|||
#include "fsr3upscaler/ffx_fsr3upscaler_common.h" |
|||
#include "fsr3upscaler/ffx_fsr3upscaler_shading_change_pyramid.h" |
|||
|
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH 256 |
|||
#endif // #ifndef FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH |
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT 1 |
|||
#endif // #ifndef FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT |
|||
#ifndef FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH |
|||
#define FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH 1 |
|||
#endif // #ifndef FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH |
|||
#ifndef FFX_FSR3UPSCALER_NUM_THREADS |
|||
#define FFX_FSR3UPSCALER_NUM_THREADS [numthreads(FFX_FSR3UPSCALER_THREAD_GROUP_WIDTH, FFX_FSR3UPSCALER_THREAD_GROUP_HEIGHT, FFX_FSR3UPSCALER_THREAD_GROUP_DEPTH)] |
|||
#endif // #ifndef FFX_FSR3UPSCALER_NUM_THREADS |
|||
|
|||
FFX_FSR3UPSCALER_NUM_THREADS |
|||
FFX_FSR3UPSCALER_EMBED_CB2_ROOTSIG_CONTENT |
|||
void CS(uint3 WorkGroupId : SV_GroupID, uint LocalThreadIndex : SV_GroupIndex) |
|||
{ |
|||
ComputeShadingChangePyramid(WorkGroupId, LocalThreadIndex); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 3fd145d1d6d4dfd4d9441cee231689bd |
|||
ShaderIncludeImporter: |
|||
externalObjects: {} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -1,338 +0,0 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files (the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions: |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
|
|||
/// A define for a true value in a boolean expression. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
#define FFX_TRUE (1) |
|||
|
|||
/// A define for a false value in a boolean expression. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
#define FFX_FALSE (0) |
|||
|
|||
#if !defined(FFX_STATIC) |
|||
/// A define to abstract declaration of static variables and functions. |
|||
/// |
|||
/// @ingroup CPUTypes |
|||
#define FFX_STATIC static |
|||
#endif // #if !defined(FFX_STATIC) |
|||
|
|||
/// @defgroup CPUCore CPU Core |
|||
/// Core CPU-side defines and functions |
|||
/// |
|||
/// @ingroup ffxHost |
|||
|
|||
#ifdef __clang__ |
|||
#pragma clang diagnostic ignored "-Wunused-variable" |
|||
#endif |
|||
|
|||
/// Interpret the bit layout of an IEEE-754 floating point value as an unsigned integer. |
|||
/// |
|||
/// @param [in] x A 32bit floating value. |
|||
/// |
|||
/// @returns |
|||
/// An unsigned 32bit integer value containing the bit pattern of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxUInt32 ffxAsUInt32(FfxFloat32 x) |
|||
{ |
|||
union |
|||
{ |
|||
FfxFloat32 f; |
|||
FfxUInt32 u; |
|||
} bits; |
|||
|
|||
bits.f = x; |
|||
return bits.u; |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxDot2(FfxFloat32x2 a, FfxFloat32x2 b) |
|||
{ |
|||
return a[0] * b[0] + a[1] * b[1]; |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxDot3(FfxFloat32x3 a, FfxFloat32x3 b) |
|||
{ |
|||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxDot4(FfxFloat32x4 a, FfxFloat32x4 b) |
|||
{ |
|||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; |
|||
} |
|||
|
|||
/// Compute the linear interopation between two values. |
|||
/// |
|||
/// Implemented by calling the GLSL <c><i>mix</i></c> instrinsic function. Implements the |
|||
/// following math: |
|||
/// |
|||
/// (1 - t) * x + t * y |
|||
/// |
|||
/// @param [in] x The first value to lerp between. |
|||
/// @param [in] y The second value to lerp between. |
|||
/// @param [in] t The value to determine how much of <c><i>x</i></c> and how much of <c><i>y</i></c>. |
|||
/// |
|||
/// @returns |
|||
/// A linearly interpolated value between <c><i>x</i></c> and <c><i>y</i></c> according to <c><i>t</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxLerp(FfxFloat32 x, FfxFloat32 y, FfxFloat32 t) |
|||
{ |
|||
return y * t + (-x * t + x); |
|||
} |
|||
|
|||
/// Compute the reciprocal of a value. |
|||
/// |
|||
/// @param [in] x The value to compute the reciprocal for. |
|||
/// |
|||
/// @returns |
|||
/// The reciprocal value of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxReciprocal(FfxFloat32 x) |
|||
{ |
|||
return 1.0f / x; |
|||
} |
|||
|
|||
/// Compute the square root of a value. |
|||
/// |
|||
/// @param [in] x The first value to compute the min of. |
|||
/// |
|||
/// @returns |
|||
/// The the square root of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxSqrt(FfxFloat32 x) |
|||
{ |
|||
return sqrt(x); |
|||
} |
|||
|
|||
FFX_STATIC FfxUInt32 AShrSU1(FfxUInt32 a, FfxUInt32 b) |
|||
{ |
|||
return FfxUInt32(FfxInt32(a) >> FfxInt32(b)); |
|||
} |
|||
|
|||
/// Compute the factional part of a decimal value. |
|||
/// |
|||
/// This function calculates <c><i>x - floor(x)</i></c>. |
|||
/// |
|||
/// @param [in] x The value to compute the fractional part from. |
|||
/// |
|||
/// @returns |
|||
/// The fractional part of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxFract(FfxFloat32 x) |
|||
{ |
|||
return x - floor(x); |
|||
} |
|||
|
|||
/// Compute the reciprocal square root of a value. |
|||
/// |
|||
/// @param [in] x The value to compute the reciprocal for. |
|||
/// |
|||
/// @returns |
|||
/// The reciprocal square root value of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 rsqrt(FfxFloat32 x) |
|||
{ |
|||
return ffxReciprocal(ffxSqrt(x)); |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxMin(FfxFloat32 x, FfxFloat32 y) |
|||
{ |
|||
return x < y ? x : y; |
|||
} |
|||
|
|||
FFX_STATIC FfxUInt32 ffxMin(FfxUInt32 x, FfxUInt32 y) |
|||
{ |
|||
return x < y ? x : y; |
|||
} |
|||
|
|||
FFX_STATIC FfxFloat32 ffxMax(FfxFloat32 x, FfxFloat32 y) |
|||
{ |
|||
return x > y ? x : y; |
|||
} |
|||
|
|||
FFX_STATIC FfxUInt32 ffxMax(FfxUInt32 x, FfxUInt32 y) |
|||
{ |
|||
return x > y ? x : y; |
|||
} |
|||
|
|||
/// Clamp a value to a [0..1] range. |
|||
/// |
|||
/// @param [in] x The value to clamp to [0..1] range. |
|||
/// |
|||
/// @returns |
|||
/// The clamped version of <c><i>x</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxFloat32 ffxSaturate(FfxFloat32 x) |
|||
{ |
|||
return ffxMin(1.0f, ffxMax(0.0f, x)); |
|||
} |
|||
|
|||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
FFX_STATIC void opAAddOneF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b) |
|||
{ |
|||
d[0] = a[0] + b; |
|||
d[1] = a[1] + b; |
|||
d[2] = a[2] + b; |
|||
return; |
|||
} |
|||
|
|||
FFX_STATIC void opACpyF3(FfxFloat32x3 d, FfxFloat32x3 a) |
|||
{ |
|||
d[0] = a[0]; |
|||
d[1] = a[1]; |
|||
d[2] = a[2]; |
|||
return; |
|||
} |
|||
|
|||
FFX_STATIC void opAMulF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32x3 b) |
|||
{ |
|||
d[0] = a[0] * b[0]; |
|||
d[1] = a[1] * b[1]; |
|||
d[2] = a[2] * b[2]; |
|||
return; |
|||
} |
|||
|
|||
FFX_STATIC void opAMulOneF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b) |
|||
{ |
|||
d[0] = a[0] * b; |
|||
d[1] = a[1] * b; |
|||
d[2] = a[2] * b; |
|||
return; |
|||
} |
|||
|
|||
FFX_STATIC void opARcpF3(FfxFloat32x3 d, FfxFloat32x3 a) |
|||
{ |
|||
d[0] = ffxReciprocal(a[0]); |
|||
d[1] = ffxReciprocal(a[1]); |
|||
d[2] = ffxReciprocal(a[2]); |
|||
return; |
|||
} |
|||
|
|||
/// Convert FfxFloat32 to half (in lower 16-bits of output). |
|||
/// |
|||
/// This function implements the same fast technique that is documented here: ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf |
|||
/// |
|||
/// The function supports denormals. |
|||
/// |
|||
/// Some conversion rules are to make computations possibly "safer" on the GPU, |
|||
/// -INF & -NaN -> -65504 |
|||
/// +INF & +NaN -> +65504 |
|||
/// |
|||
/// @param [in] f The 32bit floating point value to convert. |
|||
/// |
|||
/// @returns |
|||
/// The closest 16bit floating point value to <c><i>f</i></c>. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxUInt32 f32tof16(FfxFloat32 f) |
|||
{ |
|||
static FfxUInt16 base[512] = { |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, |
|||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, |
|||
0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00, 0x2000, 0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x4400, 0x4800, 0x4c00, 0x5000, |
|||
0x5400, 0x5800, 0x5c00, 0x6000, 0x6400, 0x6800, 0x6c00, 0x7000, 0x7400, 0x7800, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, |
|||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, |
|||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002, |
|||
0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, 0x8200, 0x8400, 0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00, 0xa000, 0xa400, 0xa800, 0xac00, |
|||
0xb000, 0xb400, 0xb800, 0xbc00, 0xc000, 0xc400, 0xc800, 0xcc00, 0xd000, 0xd400, 0xd800, 0xdc00, 0xe000, 0xe400, 0xe800, 0xec00, 0xf000, 0xf400, 0xf800, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, |
|||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff |
|||
}; |
|||
|
|||
static FfxUInt8 shift[512] = { |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, |
|||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, |
|||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, |
|||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 |
|||
}; |
|||
|
|||
union |
|||
{ |
|||
FfxFloat32 f; |
|||
FfxUInt32 u; |
|||
} bits; |
|||
|
|||
bits.f = f; |
|||
FfxUInt32 u = bits.u; |
|||
FfxUInt32 i = u >> 23; |
|||
return (FfxUInt32)(base[i]) + ((u & 0x7fffff) >> shift[i]); |
|||
} |
|||
|
|||
/// Pack 2x32-bit floating point values in a single 32bit value. |
|||
/// |
|||
/// This function first converts each component of <c><i>value</i></c> into their nearest 16-bit floating |
|||
/// point representation, and then stores the X and Y components in the lower and upper 16 bits of the |
|||
/// 32bit unsigned integer respectively. |
|||
/// |
|||
/// @param [in] x A 2-dimensional floating point value to convert and pack. |
|||
/// |
|||
/// @returns |
|||
/// A packed 32bit value containing 2 16bit floating point values. |
|||
/// |
|||
/// @ingroup CPUCore |
|||
FFX_STATIC FfxUInt32 packHalf2x16(FfxFloat32x2 x) |
|||
{ |
|||
return f32tof16(x[0]) + (f32tof16(x[1]) << 16); |
|||
} |
|||
@ -1,65 +0,0 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 4c88c0b7a4dec1e479272449c19ca981 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
: Any |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
Exclude Editor: 1 |
|||
Exclude GameCoreScarlett: 1 |
|||
Exclude GameCoreXboxOne: 1 |
|||
Exclude Linux64: 1 |
|||
Exclude OSXUniversal: 1 |
|||
Exclude PS4: 1 |
|||
Exclude PS5: 1 |
|||
Exclude Win: 1 |
|||
Exclude Win64: 1 |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 0 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
- first: |
|||
Standalone: Linux64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: OSXUniversal |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,882 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
#include "ffx_fsr3upscaler_resources.h" |
|||
|
|||
#if defined(FFX_GPU) |
|||
#include "ffx_core.h" |
|||
#endif // #if defined(FFX_GPU) |
|||
|
|||
#if defined(FFX_GPU) |
|||
#ifndef FFX_PREFER_WAVE64 |
|||
#define FFX_PREFER_WAVE64 |
|||
#endif // FFX_PREFER_WAVE64 |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_CB_FSR3UPSCALER) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_CB_FSR3UPSCALER, std140) uniform cbFSR3UPSCALER_t |
|||
{ |
|||
FfxInt32x2 iRenderSize; |
|||
FfxInt32x2 iPreviousFrameRenderSize; |
|||
|
|||
FfxInt32x2 iUpscaleSize; |
|||
FfxInt32x2 iPreviousFrameUpscaleSize; |
|||
|
|||
FfxInt32x2 iMaxRenderSize; |
|||
FfxInt32x2 iMaxUpscaleSize; |
|||
|
|||
FfxFloat32x4 fDeviceToViewDepth; |
|||
|
|||
FfxFloat32x2 fJitter; |
|||
FfxFloat32x2 fPreviousFrameJitter; |
|||
|
|||
FfxFloat32x2 fMotionVectorScale; |
|||
FfxFloat32x2 fDownscaleFactor; |
|||
|
|||
FfxFloat32x2 fMotionVectorJitterCancellation; |
|||
FfxFloat32 fTanHalfFOV; |
|||
FfxFloat32 fJitterSequenceLength; |
|||
|
|||
FfxFloat32 fDeltaTime; |
|||
FfxFloat32 fDeltaPreExposure; |
|||
FfxFloat32 fViewSpaceToMetersFactor; |
|||
FfxFloat32 fFrameIndex; |
|||
} cbFSR3Upscaler; |
|||
|
|||
|
|||
FfxInt32x2 RenderSize() |
|||
{ |
|||
return cbFSR3Upscaler.iRenderSize; |
|||
} |
|||
|
|||
FfxInt32x2 PreviousFrameRenderSize() |
|||
{ |
|||
return cbFSR3Upscaler.iPreviousFrameRenderSize; |
|||
} |
|||
|
|||
FfxInt32x2 MaxRenderSize() |
|||
{ |
|||
return cbFSR3Upscaler.iMaxRenderSize; |
|||
} |
|||
|
|||
FfxInt32x2 UpscaleSize() |
|||
{ |
|||
return cbFSR3Upscaler.iUpscaleSize; |
|||
} |
|||
|
|||
FfxInt32x2 PreviousFrameUpscaleSize() |
|||
{ |
|||
return cbFSR3Upscaler.iPreviousFrameUpscaleSize; |
|||
} |
|||
|
|||
FfxInt32x2 MaxUpscaleSize() |
|||
{ |
|||
return cbFSR3Upscaler.iMaxUpscaleSize; |
|||
} |
|||
|
|||
FfxFloat32x2 Jitter() |
|||
{ |
|||
return cbFSR3Upscaler.fJitter; |
|||
} |
|||
|
|||
FfxFloat32x2 PreviousFrameJitter() |
|||
{ |
|||
return cbFSR3Upscaler.fPreviousFrameJitter; |
|||
} |
|||
|
|||
FfxFloat32x4 DeviceToViewSpaceTransformFactors() |
|||
{ |
|||
return cbFSR3Upscaler.fDeviceToViewDepth; |
|||
} |
|||
|
|||
FfxFloat32x2 MotionVectorScale() |
|||
{ |
|||
return cbFSR3Upscaler.fMotionVectorScale; |
|||
} |
|||
|
|||
FfxFloat32x2 DownscaleFactor() |
|||
{ |
|||
return cbFSR3Upscaler.fDownscaleFactor; |
|||
} |
|||
|
|||
FfxFloat32x2 MotionVectorJitterCancellation() |
|||
{ |
|||
return cbFSR3Upscaler.fMotionVectorJitterCancellation; |
|||
} |
|||
|
|||
FfxFloat32 TanHalfFoV() |
|||
{ |
|||
return cbFSR3Upscaler.fTanHalfFOV; |
|||
} |
|||
|
|||
FfxFloat32 JitterSequenceLength() |
|||
{ |
|||
return cbFSR3Upscaler.fJitterSequenceLength; |
|||
} |
|||
|
|||
FfxFloat32 DeltaTime() |
|||
{ |
|||
return cbFSR3Upscaler.fDeltaTime; |
|||
} |
|||
|
|||
FfxFloat32 DeltaPreExposure() |
|||
{ |
|||
return cbFSR3Upscaler.fDeltaPreExposure; |
|||
} |
|||
|
|||
FfxFloat32 ViewSpaceToMetersFactor() |
|||
{ |
|||
return cbFSR3Upscaler.fViewSpaceToMetersFactor; |
|||
} |
|||
|
|||
FfxFloat32 FrameIndex() |
|||
{ |
|||
return cbFSR3Upscaler.fFrameIndex; |
|||
} |
|||
|
|||
#endif // #if defined(FSR3UPSCALER_BIND_CB_FSR3UPSCALER) |
|||
|
|||
|
|||
#if defined(FSR3UPSCALER_BIND_CB_AUTOREACTIVE) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_CB_AUTOREACTIVE, std140) uniform cbGenerateReactive_t |
|||
{ |
|||
FfxFloat32 fTcThreshold; // 0.1 is a good starting value, lower will result in more TC pixels |
|||
FfxFloat32 fTcScale; |
|||
FfxFloat32 fReactiveScale; |
|||
FfxFloat32 fReactiveMax; |
|||
} cbGenerateReactive; |
|||
|
|||
FfxFloat32 TcThreshold() |
|||
{ |
|||
return cbGenerateReactive.fTcThreshold; |
|||
} |
|||
|
|||
FfxFloat32 TcScale() |
|||
{ |
|||
return cbGenerateReactive.fTcScale; |
|||
} |
|||
|
|||
FfxFloat32 ReactiveScale() |
|||
{ |
|||
return cbGenerateReactive.fReactiveScale; |
|||
} |
|||
|
|||
FfxFloat32 ReactiveMax() |
|||
{ |
|||
return cbGenerateReactive.fReactiveMax; |
|||
} |
|||
#endif // #if defined(FSR3UPSCALER_BIND_CB_AUTOREACTIVE) |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_CB_RCAS) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_CB_RCAS, std140) uniform cbRCAS_t |
|||
{ |
|||
FfxUInt32x4 rcasConfig; |
|||
} cbRCAS; |
|||
|
|||
FfxUInt32x4 RCASConfig() |
|||
{ |
|||
return cbRCAS.rcasConfig; |
|||
} |
|||
#endif // #if defined(FSR3UPSCALER_BIND_CB_RCAS) |
|||
|
|||
|
|||
#if defined(FSR3UPSCALER_BIND_CB_REACTIVE) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_CB_REACTIVE, std140) uniform cbGenerateReactive_t |
|||
{ |
|||
FfxFloat32 gen_reactive_scale; |
|||
FfxFloat32 gen_reactive_threshold; |
|||
FfxFloat32 gen_reactive_binaryValue; |
|||
FfxUInt32 gen_reactive_flags; |
|||
} cbGenerateReactive; |
|||
|
|||
FfxFloat32 GenReactiveScale() |
|||
{ |
|||
return cbGenerateReactive.gen_reactive_scale; |
|||
} |
|||
|
|||
FfxFloat32 GenReactiveThreshold() |
|||
{ |
|||
return cbGenerateReactive.gen_reactive_threshold; |
|||
} |
|||
|
|||
FfxFloat32 GenReactiveBinaryValue() |
|||
{ |
|||
return cbGenerateReactive.gen_reactive_binaryValue; |
|||
} |
|||
|
|||
FfxUInt32 GenReactiveFlags() |
|||
{ |
|||
return cbGenerateReactive.gen_reactive_flags; |
|||
} |
|||
#endif // #if defined(FSR3UPSCALER_BIND_CB_REACTIVE) |
|||
|
|||
|
|||
#if defined(FSR3UPSCALER_BIND_CB_SPD) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_CB_SPD, std140) uniform cbSPD_t |
|||
{ |
|||
FfxUInt32 mips; |
|||
FfxUInt32 numWorkGroups; |
|||
FfxUInt32x2 workGroupOffset; |
|||
FfxUInt32x2 renderSize; |
|||
} cbSPD; |
|||
|
|||
FfxUInt32 MipCount() |
|||
{ |
|||
return cbSPD.mips; |
|||
} |
|||
|
|||
FfxUInt32 NumWorkGroups() |
|||
{ |
|||
return cbSPD.numWorkGroups; |
|||
} |
|||
|
|||
FfxUInt32x2 WorkGroupOffset() |
|||
{ |
|||
return cbSPD.workGroupOffset; |
|||
} |
|||
|
|||
FfxUInt32x2 SPD_RenderSize() |
|||
{ |
|||
return cbSPD.renderSize; |
|||
} |
|||
#endif // #if defined(FSR3UPSCALER_BIND_CB_SPD) |
|||
|
|||
layout (set = 0, binding = 1000) uniform sampler s_PointClamp; |
|||
layout (set = 0, binding = 1001) uniform sampler s_LinearClamp; |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_SPD_MIPS) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_SPD_MIPS) uniform texture2D r_spd_mips; |
|||
|
|||
FfxInt32x2 GetSPDMipDimensions(FfxUInt32 uMipLevel) |
|||
{ |
|||
return textureSize(r_spd_mips, int(uMipLevel)).xy; |
|||
} |
|||
|
|||
FfxFloat32x2 SampleSPDMipLevel(FfxFloat32x2 fUV, FfxUInt32 mipLevel) |
|||
{ |
|||
return textureLod(sampler2D(r_spd_mips, s_LinearClamp), fUV, float(mipLevel)).rg; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_INPUT_DEPTH) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_INPUT_DEPTH) uniform texture2D r_input_depth; |
|||
|
|||
FfxFloat32 LoadInputDepth(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_input_depth, iPxPos, 0).r; |
|||
} |
|||
|
|||
FfxFloat32 SampleInputDepth(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_input_depth, s_LinearClamp), fUV, 0.0).x; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_REACTIVE_MASK) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_REACTIVE_MASK) uniform texture2D r_reactive_mask; |
|||
|
|||
FfxFloat32 LoadReactiveMask(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_reactive_mask, FfxInt32x2(iPxPos), 0).r; |
|||
} |
|||
|
|||
FfxInt32x2 GetReactiveMaskResourceDimensions() |
|||
{ |
|||
return textureSize(r_reactive_mask, 0).xy; |
|||
} |
|||
|
|||
FfxFloat32 SampleReactiveMask(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_reactive_mask, s_LinearClamp), fUV, 0.0).x; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_TRANSPARENCY_AND_COMPOSITION_MASK) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_TRANSPARENCY_AND_COMPOSITION_MASK) uniform texture2D r_transparency_and_composition_mask; |
|||
|
|||
FfxFloat32 LoadTransparencyAndCompositionMask(FfxUInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_transparency_and_composition_mask, FfxInt32x2(iPxPos), 0).r; |
|||
} |
|||
|
|||
FfxInt32x2 GetTransparencyAndCompositionMaskResourceDimensions() |
|||
{ |
|||
return textureSize(r_transparency_and_composition_mask, 0).xy; |
|||
} |
|||
|
|||
FfxFloat32 SampleTransparencyAndCompositionMask(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_transparency_and_composition_mask, s_LinearClamp), fUV, 0.0).x; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_INPUT_COLOR) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_INPUT_COLOR) uniform texture2D r_input_color_jittered; |
|||
|
|||
FfxFloat32x3 LoadInputColor(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_input_color_jittered, iPxPos, 0).rgb; |
|||
} |
|||
|
|||
FfxFloat32x3 SampleInputColor(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_input_color_jittered, s_LinearClamp), fUV, 0.0).rgb; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_INPUT_MOTION_VECTORS) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_INPUT_MOTION_VECTORS) uniform texture2D r_input_motion_vectors; |
|||
|
|||
FfxFloat32x2 LoadInputMotionVector(FfxInt32x2 iPxDilatedMotionVectorPos) |
|||
{ |
|||
FfxFloat32x2 fSrcMotionVector = texelFetch(r_input_motion_vectors, iPxDilatedMotionVectorPos, 0).xy; |
|||
|
|||
FfxFloat32x2 fUvMotionVector = fSrcMotionVector * MotionVectorScale(); |
|||
|
|||
#if FFX_FSR3UPSCALER_OPTION_JITTERED_MOTION_VECTORS |
|||
fUvMotionVector -= MotionVectorJitterCancellation(); |
|||
#endif |
|||
|
|||
return fUvMotionVector; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_INTERNAL_UPSCALED) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_INTERNAL_UPSCALED) uniform texture2D r_internal_upscaled_color; |
|||
|
|||
FfxFloat32x4 LoadHistory(FfxInt32x2 iPxHistory) |
|||
{ |
|||
return texelFetch(r_internal_upscaled_color, iPxHistory, 0); |
|||
} |
|||
|
|||
FfxFloat32x4 SampleHistory(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_internal_upscaled_color, s_LinearClamp), fUV, 0.0); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_LUMA_HISTORY) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_LUMA_HISTORY, rgba8) uniform image2D rw_luma_history; |
|||
|
|||
void StoreLumaHistory(FfxInt32x2 iPxPos, FfxFloat32x4 fLumaHistory) |
|||
{ |
|||
imageStore(rw_luma_history, iPxPos, fLumaHistory); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_LUMA_HISTORY) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_LUMA_HISTORY) uniform texture2D r_luma_history; |
|||
|
|||
FfxFloat32x4 LoadLumaHistory(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_luma_history, iPxPos, 0); |
|||
} |
|||
|
|||
FfxFloat32x4 SampleLumaHistory(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_luma_history, s_LinearClamp), fUV, 0.0); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_RCAS_INPUT) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_RCAS_INPUT) uniform texture2D r_rcas_input; |
|||
|
|||
FfxFloat32x4 LoadRCAS_Input(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_rcas_input, iPxPos, 0); |
|||
} |
|||
|
|||
FfxFloat32x3 SampleRCAS_Input(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_rcas_input, s_LinearClamp), fUV, 0.0).rgb; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_INTERNAL_UPSCALED) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_INTERNAL_UPSCALED, rgba16f) writeonly uniform image2D rw_internal_upscaled_color; |
|||
|
|||
void StoreReprojectedHistory(FfxInt32x2 iPxHistory, FfxFloat32x4 fHistory) |
|||
{ |
|||
imageStore(rw_internal_upscaled_color, iPxHistory, fHistory); |
|||
} |
|||
|
|||
void StoreInternalColorAndWeight(FfxInt32x2 iPxPos, FfxFloat32x4 fColorAndWeight) |
|||
{ |
|||
imageStore(rw_internal_upscaled_color, iPxPos, fColorAndWeight); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_UPSCALED_OUTPUT) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_UPSCALED_OUTPUT /* app controlled format */) writeonly uniform image2D rw_upscaled_output; |
|||
|
|||
void StoreUpscaledOutput(FfxInt32x2 iPxPos, FfxFloat32x3 fColor) |
|||
{ |
|||
imageStore(rw_upscaled_output, iPxPos, FfxFloat32x4(fColor, 1.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_ACCUMULATION) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_ACCUMULATION) uniform texture2D r_accumulation; |
|||
|
|||
FfxFloat32 SampleAccumulation(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_accumulation, s_LinearClamp), fUV, 0.0).x; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_ACCUMULATION) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_ACCUMULATION, r8) uniform image2D rw_accumulation; |
|||
|
|||
void StoreAccumulation(FfxInt32x2 iPxPos, FfxFloat32 fAccumulation) |
|||
{ |
|||
imageStore(rw_accumulation, iPxPos, vec4(fAccumulation, 0.0, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_SHADING_CHANGE) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_SHADING_CHANGE) uniform texture2D r_shading_change; |
|||
|
|||
FfxFloat32 LoadShadingChange(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_shading_change, iPxPos, 0).x; |
|||
} |
|||
|
|||
FfxFloat32 SampleShadingChange(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_shading_change, s_LinearClamp), fUV, 0.0).x; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_SHADING_CHANGE) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_SHADING_CHANGE, r8) uniform image2D rw_shading_change; |
|||
|
|||
void StoreShadingChange(FfxInt32x2 iPxPos, FfxFloat32 fShadingChange) |
|||
{ |
|||
imageStore(rw_shading_change, iPxPos, vec4(fShadingChange, 0.0, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_FARTHEST_DEPTH) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_FARTHEST_DEPTH) uniform texture2D r_farthest_depth; |
|||
|
|||
FfxInt32x2 GetFarthestDepthResourceDimensions() |
|||
{ |
|||
return textureSize(r_farthest_depth, 0).xy; |
|||
} |
|||
|
|||
FfxFloat32 LoadFarthestDepth(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_farthest_depth, iPxPos, 0).x; |
|||
} |
|||
|
|||
FfxFloat32 SampleFarthestDepth(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_farthest_depth, s_LinearClamp), fUV, 0.0).x; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_FARTHEST_DEPTH) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_FARTHEST_DEPTH, r16f) uniform image2D rw_farthest_depth; |
|||
|
|||
void StoreFarthestDepth(FfxInt32x2 iPxPos, FfxFloat32 fDepth) |
|||
{ |
|||
imageStore(rw_farthest_depth, iPxPos, vec4(fDepth, 0.0, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_FARTHEST_DEPTH_MIP1) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_FARTHEST_DEPTH_MIP1) uniform texture2D r_farthest_depth_mip1; |
|||
|
|||
FfxInt32x2 GetFarthestDepthMip1ResourceDimensions() |
|||
{ |
|||
return textureSize(r_farthest_depth_mip1, 0).xy; |
|||
} |
|||
|
|||
FfxFloat32 LoadFarthestDepthMip1(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_farthest_depth_mip1, iPxPos, 0).x; |
|||
} |
|||
|
|||
FfxFloat32 SampleFarthestDepthMip1(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_farthest_depth_mip1, s_LinearClamp), fUV, 0.0).x; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_FARTHEST_DEPTH_MIP1) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_FARTHEST_DEPTH_MIP1, r16f) uniform image2D rw_farthest_depth_mip1; |
|||
|
|||
void StoreFarthestDepthMip1(FfxInt32x2 iPxPos, FfxFloat32 fDepth) |
|||
{ |
|||
imageStore(rw_farthest_depth_mip1, iPxPos, vec4(fDepth, 0.0, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_CURRENT_LUMA) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_CURRENT_LUMA) uniform texture2D r_current_luma; |
|||
|
|||
FfxFloat32 LoadCurrentLuma(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_current_luma, iPxPos, 0).r; |
|||
} |
|||
|
|||
FfxFloat32 SampleCurrentLuma(FfxFloat32x2 uv) |
|||
{ |
|||
return textureLod(sampler2D(r_current_luma, s_LinearClamp), uv, 0.0).r; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_CURRENT_LUMA) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_CURRENT_LUMA, r16f) uniform image2D rw_current_luma; |
|||
|
|||
void StoreCurrentLuma(FfxInt32x2 iPxPos, FfxFloat32 fLuma) |
|||
{ |
|||
imageStore(rw_current_luma, iPxPos, vec4(fLuma, 0.0, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_LUMA_INSTABILITY) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_LUMA_INSTABILITY) uniform texture2D r_luma_instability; |
|||
|
|||
FfxFloat32 SampleLumaInstability(FfxFloat32x2 uv) |
|||
{ |
|||
return textureLod(sampler2D(r_luma_instability, s_LinearClamp), uv, 0.0).x; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_LUMA_INSTABILITY) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_LUMA_INSTABILITY, r16f) uniform image2D rw_luma_instability; |
|||
|
|||
void StoreLumaInstability(FfxInt32x2 iPxPos, FfxFloat32 fLumaInstability) |
|||
{ |
|||
imageStore(rw_luma_instability, iPxPos, vec4(fLumaInstability, 0.0, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_PREVIOUS_LUMA) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_PREVIOUS_LUMA) uniform texture2D r_previous_luma; |
|||
|
|||
FfxFloat32 LoadPreviousLuma(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_previous_luma, iPxPos, 0).r; |
|||
} |
|||
|
|||
FfxFloat32 SamplePreviousLuma(FfxFloat32x2 uv) |
|||
{ |
|||
return textureLod(sampler2D(r_previous_luma, s_LinearClamp), uv, 0.0).r; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_NEW_LOCKS) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_NEW_LOCKS) uniform texture2D r_new_locks; |
|||
|
|||
FfxFloat32 LoadNewLocks(FfxInt32x2 iPxPos) |
|||
{ |
|||
return texelFetch(r_new_locks, iPxPos, 0).r; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_NEW_LOCKS) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_UAV_NEW_LOCKS, r8) uniform image2D rw_new_locks; |
|||
|
|||
FfxFloat32 LoadRwNewLocks(FfxInt32x2 iPxPos) |
|||
{ |
|||
return imageLoad(rw_new_locks, iPxPos).r; |
|||
} |
|||
|
|||
void StoreNewLocks(FfxInt32x2 iPxPos, FfxFloat32 newLock) |
|||
{ |
|||
imageStore(rw_new_locks, iPxPos, vec4(newLock, 0, 0, 0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_RECONSTRUCTED_PREV_NEAREST_DEPTH) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_RECONSTRUCTED_PREV_NEAREST_DEPTH) uniform utexture2D r_reconstructed_previous_nearest_depth; |
|||
|
|||
FfxFloat32 LoadReconstructedPrevDepth(FfxInt32x2 iPxPos) |
|||
{ |
|||
return uintBitsToFloat(texelFetch(r_reconstructed_previous_nearest_depth, iPxPos, 0).r); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_RECONSTRUCTED_PREV_NEAREST_DEPTH) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_RECONSTRUCTED_PREV_NEAREST_DEPTH, r32ui) uniform uimage2D rw_reconstructed_previous_nearest_depth; |
|||
|
|||
void StoreReconstructedDepth(FfxInt32x2 iPxSample, FfxFloat32 fDepth) |
|||
{ |
|||
FfxUInt32 uDepth = floatBitsToUint(fDepth); |
|||
|
|||
#if FFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH |
|||
imageAtomicMax(rw_reconstructed_previous_nearest_depth, iPxSample, uDepth); |
|||
#else |
|||
imageAtomicMin(rw_reconstructed_previous_nearest_depth, iPxSample, uDepth); // min for standard, max for inverted depth |
|||
#endif |
|||
} |
|||
|
|||
void SetReconstructedDepth(FfxInt32x2 iPxSample, FfxUInt32 uValue) |
|||
{ |
|||
imageStore(rw_reconstructed_previous_nearest_depth, iPxSample, uvec4(uValue, 0, 0, 0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_DILATED_DEPTH) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_DILATED_DEPTH, r16f) writeonly uniform image2D rw_dilated_depth; |
|||
|
|||
void StoreDilatedDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32 fDepth) |
|||
{ |
|||
imageStore(rw_dilated_depth, iPxPos, vec4(fDepth, 0.0, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_DILATED_MOTION_VECTORS) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_DILATED_MOTION_VECTORS, rg16f) writeonly uniform image2D rw_dilated_motion_vectors; |
|||
|
|||
void StoreDilatedMotionVector(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x2 fMotionVector) |
|||
{ |
|||
imageStore(rw_dilated_motion_vectors, iPxPos, vec4(fMotionVector, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_DILATED_MOTION_VECTORS) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_DILATED_MOTION_VECTORS) uniform texture2D r_dilated_motion_vectors; |
|||
|
|||
FfxFloat32x2 LoadDilatedMotionVector(FfxInt32x2 iPxInput) |
|||
{ |
|||
return texelFetch(r_dilated_motion_vectors, iPxInput, 0).xy; |
|||
} |
|||
|
|||
FfxFloat32x2 SampleDilatedMotionVector(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_dilated_motion_vectors, s_LinearClamp), fUV, 0.0).xy; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_DILATED_DEPTH) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_DILATED_DEPTH) uniform texture2D r_dilated_depth; |
|||
|
|||
FfxFloat32 LoadDilatedDepth(FfxInt32x2 iPxInput) |
|||
{ |
|||
return texelFetch(r_dilated_depth, iPxInput, 0).r; |
|||
} |
|||
|
|||
FfxFloat32 SampleDilatedDepth(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_dilated_depth, s_LinearClamp), fUV, 0.0).r; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_INPUT_EXPOSURE) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_INPUT_EXPOSURE) uniform texture2D r_input_exposure; |
|||
|
|||
FfxFloat32 Exposure() |
|||
{ |
|||
FfxFloat32 exposure = texelFetch(r_input_exposure, FfxInt32x2(0, 0), 0).x; |
|||
|
|||
if (exposure == 0.0) { |
|||
exposure = 1.0; |
|||
} |
|||
|
|||
return exposure; |
|||
} |
|||
#endif |
|||
|
|||
// BEGIN: FSR3UPSCALER_BIND_SRV_LANCZOS_LUT |
|||
#if defined(FSR3UPSCALER_BIND_SRV_LANCZOS_LUT) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_LANCZOS_LUT) uniform texture2D r_lanczos_lut; |
|||
#endif |
|||
|
|||
FfxFloat32 SampleLanczos2Weight(FfxFloat32 x) |
|||
{ |
|||
#if defined(FSR3UPSCALER_BIND_SRV_LANCZOS_LUT) |
|||
return textureLod(sampler2D(r_lanczos_lut, s_LinearClamp), FfxFloat32x2(x / 2.0, 0.5), 0.0).x; |
|||
#else |
|||
return 0.f; |
|||
#endif |
|||
} |
|||
// END: FSR3UPSCALER_BIND_SRV_LANCZOS_LUT |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_DILATED_REACTIVE_MASKS) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_DILATED_REACTIVE_MASKS) uniform texture2D r_dilated_reactive_masks; |
|||
|
|||
FfxFloat32x4 SampleDilatedReactiveMasks(FfxFloat32x2 fUV) |
|||
{ |
|||
return textureLod(sampler2D(r_dilated_reactive_masks, s_LinearClamp), fUV, 0.0); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_DILATED_REACTIVE_MASKS) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_DILATED_REACTIVE_MASKS, rgba8) writeonly uniform image2D rw_dilated_reactive_masks; |
|||
|
|||
void StoreDilatedReactiveMasks(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x4 fDilatedReactiveMasks) |
|||
{ |
|||
imageStore(rw_dilated_reactive_masks, iPxPos, fDilatedReactiveMasks); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_INPUT_OPAQUE_ONLY) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_SRV_INPUT_OPAQUE_ONLY) uniform texture2D r_input_opaque_only; |
|||
|
|||
FfxFloat32x3 LoadOpaqueOnly(FFX_PARAMETER_IN FFX_MIN16_I2 iPxPos) |
|||
{ |
|||
return texelFetch(r_input_opaque_only, iPxPos, 0).xyz; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_PREV_PRE_ALPHA_COLOR) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_PREV_PRE_ALPHA_COLOR) uniform texture2D r_input_prev_color_pre_alpha; |
|||
|
|||
FfxFloat32x3 LoadPrevPreAlpha(FFX_PARAMETER_IN FFX_MIN16_I2 iPxPos) |
|||
{ |
|||
return texelFetch(r_input_prev_color_pre_alpha, iPxPos, 0).xyz; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_PREV_POST_ALPHA_COLOR) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_PREV_POST_ALPHA_COLOR) uniform texture2D r_input_prev_color_post_alpha; |
|||
|
|||
FfxFloat32x3 LoadPrevPostAlpha(FFX_PARAMETER_IN FFX_MIN16_I2 iPxPos) |
|||
{ |
|||
return texelFetch(r_input_prev_color_post_alpha, iPxPos, 0).xyz; |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_AUTOREACTIVE) && \ |
|||
defined(FSR3UPSCALER_BIND_UAV_AUTOCOMPOSITION) |
|||
|
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_UAV_AUTOREACTIVE, r32f) uniform image2D rw_output_autoreactive; |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_UAV_AUTOCOMPOSITION, r32f) uniform image2D rw_output_autocomposition; |
|||
|
|||
void StoreAutoReactive(FFX_PARAMETER_IN FFX_MIN16_I2 iPxPos, FFX_PARAMETER_IN FFX_MIN16_F2 fReactive) |
|||
{ |
|||
imageStore(rw_output_autoreactive, iPxPos, FfxFloat32x4(FfxFloat32(fReactive.x), 0.0, 0.0, 0.0)); |
|||
|
|||
imageStore(rw_output_autocomposition, iPxPos, FfxFloat32x4(FfxFloat32(fReactive.y), 0.0, 0.0, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_PREV_PRE_ALPHA_COLOR) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_UAV_PREV_PRE_ALPHA_COLOR, r11f_g11f_b10f) uniform image2D rw_output_prev_color_pre_alpha; |
|||
|
|||
void StorePrevPreAlpha(FFX_PARAMETER_IN FFX_MIN16_I2 iPxPos, FFX_PARAMETER_IN FFX_MIN16_F3 color) |
|||
{ |
|||
imageStore(rw_output_prev_color_pre_alpha, iPxPos, FfxFloat32x4(color, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_PREV_POST_ALPHA_COLOR) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_UAV_PREV_POST_ALPHA_COLOR, r11f_g11f_b10f) uniform image2D rw_output_prev_color_post_alpha; |
|||
|
|||
void StorePrevPostAlpha(FFX_PARAMETER_IN FFX_MIN16_I2 iPxPos, FFX_PARAMETER_IN FFX_MIN16_F3 color) |
|||
{ |
|||
imageStore(rw_output_prev_color_post_alpha, iPxPos, FfxFloat32x4(color, 0.0)); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_FRAME_INFO) |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_FRAME_INFO, rgba32f) uniform image2D rw_frame_info; |
|||
|
|||
FfxFloat32x4 LoadFrameInfo() |
|||
{ |
|||
return imageLoad(rw_frame_info, ivec2(0, 0)); |
|||
} |
|||
|
|||
void StoreFrameInfo(FfxFloat32x4 fInfo) |
|||
{ |
|||
imageStore(rw_frame_info, ivec2(0, 0), fInfo); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_SRV_FRAME_INFO) |
|||
layout(set = 0, binding = FSR3UPSCALER_BIND_SRV_FRAME_INFO) uniform texture2D r_frame_info; |
|||
|
|||
FfxFloat32x4 FrameInfo() |
|||
{ |
|||
return texelFetch(r_frame_info, ivec2(0, 0), 0); |
|||
} |
|||
#endif |
|||
|
|||
#if defined(FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_0) && \ |
|||
defined(FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_1) && \ |
|||
defined(FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_2) && \ |
|||
defined(FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_3) && \ |
|||
defined(FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_4) && \ |
|||
defined(FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_5) |
|||
|
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_0, rg16f) uniform image2D rw_spd_mip0; |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_1, rg16f) uniform image2D rw_spd_mip1; |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_2, rg16f) uniform image2D rw_spd_mip2; |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_3, rg16f) uniform image2D rw_spd_mip3; |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_4, rg16f) uniform image2D rw_spd_mip4; |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_SPD_MIPS_LEVEL_5, rg16f) coherent uniform image2D rw_spd_mip5; |
|||
|
|||
FfxFloat32x2 RWLoadPyramid(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 index) |
|||
{ |
|||
#define LOAD(idx) \ |
|||
if (index == idx) \ |
|||
{ \ |
|||
return imageLoad(rw_spd_mip##idx, iPxPos).xy; \ |
|||
} |
|||
LOAD(0); |
|||
LOAD(1); |
|||
LOAD(2); |
|||
LOAD(3); |
|||
LOAD(4); |
|||
LOAD(5); |
|||
|
|||
return FfxFloat32x2(0.0, 0.0); |
|||
|
|||
#undef LOAD |
|||
} |
|||
|
|||
void StorePyramid(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x2 outValue, FFX_PARAMETER_IN FfxUInt32 index) |
|||
{ |
|||
#define STORE(idx) \ |
|||
if (index == idx) \ |
|||
{ \ |
|||
imageStore(rw_spd_mip##idx, iPxPos, vec4(outValue, 0.0, 0.0)); \ |
|||
} |
|||
|
|||
STORE(0); |
|||
STORE(1); |
|||
STORE(2); |
|||
STORE(3); |
|||
STORE(4); |
|||
STORE(5); |
|||
|
|||
#undef STORE |
|||
} |
|||
#endif |
|||
|
|||
#if defined FSR3UPSCALER_BIND_UAV_SPD_GLOBAL_ATOMIC |
|||
layout (set = 0, binding = FSR3UPSCALER_BIND_UAV_SPD_GLOBAL_ATOMIC, r32ui) coherent uniform uimage2D rw_spd_global_atomic; |
|||
|
|||
void SPD_IncreaseAtomicCounter(inout FfxUInt32 spdCounter) |
|||
{ |
|||
spdCounter = imageAtomicAdd(rw_spd_global_atomic, ivec2(0, 0), 1); |
|||
} |
|||
|
|||
void SPD_ResetAtomicCounter() |
|||
{ |
|||
imageStore(rw_spd_global_atomic, ivec2(0, 0), uvec4(0)); |
|||
} |
|||
#endif |
|||
|
|||
#endif // #if defined(FFX_GPU) |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 792c5fd8e080de44a8d66c330e46d7c0 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
799
Assets/Shaders/FSR3/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,65 +0,0 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 61bd10363d44ee2478461c9e9efbcb67 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
: Any |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
Exclude Editor: 1 |
|||
Exclude GameCoreScarlett: 1 |
|||
Exclude GameCoreXboxOne: 1 |
|||
Exclude Linux64: 1 |
|||
Exclude OSXUniversal: 1 |
|||
Exclude PS4: 1 |
|||
Exclude PS5: 1 |
|||
Exclude Win: 1 |
|||
Exclude Win64: 1 |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 0 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
- first: |
|||
Standalone: Linux64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: OSXUniversal |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,159 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
struct FfxDebugViewport |
|||
{ |
|||
FfxInt32x2 offset; |
|||
FfxInt32x2 size; |
|||
}; |
|||
|
|||
// Macro to cull and draw debug viewport |
|||
#define DRAW_VIEWPORT(function, pos, vp) \ |
|||
{ \ |
|||
if (pointIsInsideViewport(pos, vp)) \ |
|||
{ \ |
|||
function(pos, vp); \ |
|||
} \ |
|||
} |
|||
|
|||
FfxFloat32x2 getTransformedUv(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxFloat32x2 fUv = (FfxFloat32x2(iPxPos - vp.offset) + 0.5f) / vp.size; |
|||
|
|||
return fUv; |
|||
} |
|||
|
|||
FfxFloat32x3 getMotionVectorColor(FfxFloat32x2 fMotionVector) |
|||
{ |
|||
return FfxFloat32x3(0.5f + fMotionVector * RenderSize() * 0.5f, 0.5f); |
|||
} |
|||
|
|||
FfxFloat32x4 getUnusedIndicationColor(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxInt32x2 basePos = iPxPos - vp.offset; |
|||
|
|||
FfxFloat32 ar = FfxFloat32(vp.size.x) / FfxFloat32(vp.size.y); |
|||
|
|||
return FfxFloat32x4(basePos.x == FfxInt32(basePos.y * ar), 0, 0, 1); |
|||
} |
|||
|
|||
void drawDilatedMotionVectors(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp); |
|||
|
|||
FfxFloat32x2 fUv_HW = ClampUv(fUv, RenderSize(), MaxRenderSize()); |
|||
|
|||
FfxFloat32x2 fMotionVector = SampleDilatedMotionVector(fUv_HW); |
|||
|
|||
StoreUpscaledOutput(iPxPos, getMotionVectorColor(fMotionVector)); |
|||
} |
|||
|
|||
void drawDisocclusionMask(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp); |
|||
|
|||
FfxFloat32x2 fUv_HW = ClampUv(fUv, RenderSize(), MaxRenderSize()); |
|||
|
|||
FfxFloat32 fDisocclusionFactor = ffxSaturate(SampleDilatedReactiveMasks(fUv_HW)[DISOCCLUSION]); |
|||
|
|||
StoreUpscaledOutput(iPxPos, FfxFloat32x3(0, fDisocclusionFactor, 0)); |
|||
} |
|||
|
|||
void drawDetailProtectionTakedown(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp); |
|||
|
|||
FfxFloat32x2 fUv_HW = ClampUv(fUv, RenderSize(), MaxRenderSize()); |
|||
|
|||
FfxFloat32 fProtectionTakedown = ffxSaturate(SampleDilatedReactiveMasks(fUv_HW)[REACTIVE]); |
|||
|
|||
StoreUpscaledOutput(iPxPos, FfxFloat32x3(0, fProtectionTakedown, 0)); |
|||
} |
|||
|
|||
void drawReactiveness(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp); |
|||
|
|||
FfxFloat32x2 fUv_HW = ClampUv(fUv, RenderSize(), MaxRenderSize()); |
|||
|
|||
FfxFloat32 fShadingChange = ffxSaturate(SampleDilatedReactiveMasks(fUv_HW)[SHADING_CHANGE]); |
|||
|
|||
StoreUpscaledOutput(iPxPos, FfxFloat32x3(0, fShadingChange, 0)); |
|||
} |
|||
|
|||
void drawProtectedAreas(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp); |
|||
|
|||
FfxFloat32 fProtection = ffxSaturate(SampleHistory(fUv).w - fLockThreshold); |
|||
|
|||
StoreUpscaledOutput(iPxPos, FfxFloat32x3(fProtection, 0, 0)); |
|||
} |
|||
|
|||
void drawDilatedDepthInMeters(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp); |
|||
|
|||
FfxFloat32x2 fUv_HW = ClampUv(fUv, RenderSize(), MaxRenderSize()); |
|||
|
|||
const FfxFloat32 fDilatedDepth = SampleDilatedDepth(fUv_HW); |
|||
const FfxFloat32 fDepthInMeters = GetViewSpaceDepthInMeters(fDilatedDepth); |
|||
|
|||
StoreUpscaledOutput(iPxPos, FfxFloat32x3(ffxSaturate(fDepthInMeters / 25.0f), 0, 0)); |
|||
} |
|||
|
|||
FfxBoolean pointIsInsideViewport(FfxInt32x2 iPxPos, FfxDebugViewport vp) |
|||
{ |
|||
FfxInt32x2 extent = vp.offset + vp.size; |
|||
|
|||
return (iPxPos.x >= vp.offset.x && iPxPos.x < extent.x) && (iPxPos.y >= vp.offset.y && iPxPos.y < extent.y); |
|||
} |
|||
|
|||
void DebugView(FfxInt32x2 iPxPos) |
|||
{ |
|||
#define VIEWPORT_GRID_SIZE_X 3 |
|||
#define VIEWPORT_GRID_SIZE_Y 3 |
|||
|
|||
FfxFloat32x2 fViewportScale = FfxFloat32x2(1.0f / VIEWPORT_GRID_SIZE_X, 1.0f / VIEWPORT_GRID_SIZE_Y); |
|||
FfxInt32x2 iViewportSize = FfxInt32x2(UpscaleSize() * fViewportScale); |
|||
|
|||
// compute grid [y][x] for easier placement of viewports |
|||
FfxDebugViewport vp[VIEWPORT_GRID_SIZE_Y][VIEWPORT_GRID_SIZE_X]; |
|||
for (FfxInt32 y = 0; y < VIEWPORT_GRID_SIZE_Y; y++) |
|||
{ |
|||
for (FfxInt32 x = 0; x < VIEWPORT_GRID_SIZE_X; x++) |
|||
{ |
|||
vp[y][x].offset = iViewportSize * FfxInt32x2(x, y); |
|||
vp[y][x].size = iViewportSize; |
|||
} |
|||
} |
|||
|
|||
// top row |
|||
DRAW_VIEWPORT(drawDilatedMotionVectors, iPxPos, vp[0][0]); |
|||
DRAW_VIEWPORT(drawProtectedAreas, iPxPos, vp[0][1]); |
|||
DRAW_VIEWPORT(drawDilatedDepthInMeters, iPxPos, vp[0][2]); |
|||
|
|||
// bottom row |
|||
DRAW_VIEWPORT(drawDisocclusionMask, iPxPos, vp[2][0]); |
|||
DRAW_VIEWPORT(drawReactiveness, iPxPos, vp[2][1]); |
|||
DRAW_VIEWPORT(drawDetailProtectionTakedown, iPxPos, vp[2][2]); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 182c05fb699007e4cb9010b200259150 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -1,259 +0,0 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files (the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions: |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
|
|||
#ifndef FFX_FSR3UPSCALER_DEPTH_CLIP_H |
|||
#define FFX_FSR3UPSCALER_DEPTH_CLIP_H |
|||
|
|||
FFX_STATIC const FfxFloat32 DepthClipBaseScale = 4.0f; |
|||
|
|||
FfxFloat32 ComputeDepthClip(FfxFloat32x2 fUvSample, FfxFloat32 fCurrentDepthSample) |
|||
{ |
|||
FfxFloat32 fCurrentDepthViewSpace = GetViewSpaceDepth(fCurrentDepthSample); |
|||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fUvSample, RenderSize()); |
|||
|
|||
FfxFloat32 fDilatedSum = 0.0f; |
|||
FfxFloat32 fDepth = 0.0f; |
|||
FfxFloat32 fWeightSum = 0.0f; |
|||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++) { |
|||
|
|||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex]; |
|||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset; |
|||
|
|||
if (IsOnScreen(iSamplePos, RenderSize())) { |
|||
const FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex]; |
|||
if (fWeight > fReconstructedDepthBilinearWeightThreshold) { |
|||
|
|||
const FfxFloat32 fPrevDepthSample = LoadReconstructedPrevDepth(iSamplePos); |
|||
const FfxFloat32 fPrevNearestDepthViewSpace = GetViewSpaceDepth(fPrevDepthSample); |
|||
|
|||
const FfxFloat32 fDepthDiff = fCurrentDepthViewSpace - fPrevNearestDepthViewSpace; |
|||
|
|||
if (fDepthDiff > 0.0f) { |
|||
|
|||
#if FFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH |
|||
const FfxFloat32 fPlaneDepth = ffxMin(fPrevDepthSample, fCurrentDepthSample); |
|||
#else |
|||
const FfxFloat32 fPlaneDepth = ffxMax(fPrevDepthSample, fCurrentDepthSample); |
|||
#endif |
|||
|
|||
const FfxFloat32x3 fCenter = GetViewSpacePosition(FfxInt32x2(RenderSize() * 0.5f), RenderSize(), fPlaneDepth); |
|||
const FfxFloat32x3 fCorner = GetViewSpacePosition(FfxInt32x2(0, 0), RenderSize(), fPlaneDepth); |
|||
|
|||
const FfxFloat32 fHalfViewportWidth = length(FfxFloat32x2(RenderSize())); |
|||
const FfxFloat32 fDepthThreshold = ffxMax(fCurrentDepthViewSpace, fPrevNearestDepthViewSpace); |
|||
|
|||
const FfxFloat32 Ksep = 1.37e-05f; |
|||
const FfxFloat32 Kfov = length(fCorner) / length(fCenter); |
|||
const FfxFloat32 fRequiredDepthSeparation = Ksep * Kfov * fHalfViewportWidth * fDepthThreshold; |
|||
|
|||
const FfxFloat32 fResolutionFactor = ffxSaturate(length(FfxFloat32x2(RenderSize())) / length(FfxFloat32x2(1920.0f, 1080.0f))); |
|||
const FfxFloat32 fPower = ffxLerp(1.0f, 3.0f, fResolutionFactor); |
|||
fDepth += ffxPow(ffxSaturate(FfxFloat32(fRequiredDepthSeparation / fDepthDiff)), fPower) * fWeight; |
|||
fWeightSum += fWeight; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
return (fWeightSum > 0) ? ffxSaturate(1.0f - fDepth / fWeightSum) : 0.0f; |
|||
} |
|||
|
|||
FfxFloat32 ComputeMotionDivergence(FfxInt32x2 iPxPos, FfxInt32x2 iPxInputMotionVectorSize) |
|||
{ |
|||
FfxFloat32 minconvergence = 1.0f; |
|||
|
|||
FfxFloat32x2 fMotionVectorNucleus = LoadInputMotionVector(iPxPos); |
|||
FfxFloat32 fNucleusVelocityLr = length(fMotionVectorNucleus * RenderSize()); |
|||
FfxFloat32 fMaxVelocityUv = length(fMotionVectorNucleus); |
|||
|
|||
const FfxFloat32 MotionVectorVelocityEpsilon = 1e-02f; |
|||
|
|||
if (fNucleusVelocityLr > MotionVectorVelocityEpsilon) { |
|||
for (FfxInt32 y = -1; y <= 1; ++y) { |
|||
for (FfxInt32 x = -1; x <= 1; ++x) { |
|||
|
|||
FfxInt32x2 sp = ClampLoad(iPxPos, FfxInt32x2(x, y), iPxInputMotionVectorSize); |
|||
|
|||
FfxFloat32x2 fMotionVector = LoadInputMotionVector(sp); |
|||
FfxFloat32 fVelocityUv = length(fMotionVector); |
|||
|
|||
fMaxVelocityUv = ffxMax(fVelocityUv, fMaxVelocityUv); |
|||
fVelocityUv = ffxMax(fVelocityUv, fMaxVelocityUv); |
|||
minconvergence = ffxMin(minconvergence, dot(fMotionVector / fVelocityUv, fMotionVectorNucleus / fVelocityUv)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return ffxSaturate(1.0f - minconvergence) * ffxSaturate(fMaxVelocityUv / 0.01f); |
|||
} |
|||
|
|||
FfxFloat32 ComputeDepthDivergence(FfxInt32x2 iPxPos) |
|||
{ |
|||
const FfxFloat32 fMaxDistInMeters = GetMaxDistanceInMeters(); |
|||
FfxFloat32 fDepthMax = 0.0f; |
|||
FfxFloat32 fDepthMin = fMaxDistInMeters; |
|||
|
|||
FfxInt32 iMaxDistFound = 0; |
|||
|
|||
for (FfxInt32 y = -1; y < 2; y++) { |
|||
for (FfxInt32 x = -1; x < 2; x++) { |
|||
|
|||
const FfxInt32x2 iOffset = FfxInt32x2(x, y); |
|||
const FfxInt32x2 iSamplePos = iPxPos + iOffset; |
|||
|
|||
const FfxFloat32 fOnScreenFactor = IsOnScreen(iSamplePos, RenderSize()) ? 1.0f : 0.0f; |
|||
FfxFloat32 fDepth = GetViewSpaceDepthInMeters(LoadDilatedDepth(iSamplePos)) * fOnScreenFactor; |
|||
|
|||
iMaxDistFound |= FfxInt32(fMaxDistInMeters == fDepth); |
|||
|
|||
fDepthMin = ffxMin(fDepthMin, fDepth); |
|||
fDepthMax = ffxMax(fDepthMax, fDepth); |
|||
} |
|||
} |
|||
|
|||
return (1.0f - fDepthMin / fDepthMax) * (FfxBoolean(iMaxDistFound) ? 0.0f : 1.0f); |
|||
} |
|||
|
|||
FfxFloat32 ComputeTemporalMotionDivergence(FfxInt32x2 iPxPos) |
|||
{ |
|||
const FfxFloat32x2 fUv = FfxFloat32x2(iPxPos + 0.5f) / RenderSize(); |
|||
|
|||
FfxFloat32x2 fMotionVector = LoadDilatedMotionVector(iPxPos); |
|||
FfxFloat32x2 fReprojectedUv = fUv + fMotionVector; |
|||
fReprojectedUv = ClampUv(fReprojectedUv, RenderSize(), MaxRenderSize()); |
|||
FfxFloat32x2 fPrevMotionVector = SamplePreviousDilatedMotionVector(fReprojectedUv); |
|||
|
|||
float fPxDistance = length(fMotionVector * DisplaySize()); |
|||
return fPxDistance > 1.0f ? ffxLerp(0.0f, 1.0f - ffxSaturate(length(fPrevMotionVector) / length(fMotionVector)), ffxSaturate(ffxPow(fPxDistance / 20.0f, 3.0f))) : 0; |
|||
} |
|||
|
|||
void PreProcessReactiveMasks(FfxInt32x2 iPxLrPos, FfxFloat32 fMotionDivergence) |
|||
{ |
|||
// Compensate for bilinear sampling in accumulation pass |
|||
|
|||
FfxFloat32x3 fReferenceColor = LoadInputColor(iPxLrPos).xyz; |
|||
FfxFloat32x2 fReactiveFactor = FfxFloat32x2(0.0f, fMotionDivergence); |
|||
|
|||
float fMasksSum = 0.0f; |
|||
|
|||
FfxFloat32x3 fColorSamples[9]; |
|||
FfxFloat32 fReactiveSamples[9]; |
|||
FfxFloat32 fTransparencyAndCompositionSamples[9]; |
|||
|
|||
FFX_UNROLL |
|||
for (FfxInt32 y = -1; y < 2; y++) { |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = -1; x < 2; x++) { |
|||
|
|||
const FfxInt32x2 sampleCoord = ClampLoad(iPxLrPos, FfxInt32x2(x, y), FfxInt32x2(RenderSize())); |
|||
|
|||
FfxInt32 sampleIdx = (y + 1) * 3 + x + 1; |
|||
|
|||
FfxFloat32x3 fColorSample = LoadInputColor(sampleCoord).xyz; |
|||
FfxFloat32 fReactiveSample = LoadReactiveMask(sampleCoord); |
|||
FfxFloat32 fTransparencyAndCompositionSample = LoadTransparencyAndCompositionMask(sampleCoord); |
|||
|
|||
fColorSamples[sampleIdx] = fColorSample; |
|||
fReactiveSamples[sampleIdx] = fReactiveSample; |
|||
fTransparencyAndCompositionSamples[sampleIdx] = fTransparencyAndCompositionSample; |
|||
|
|||
fMasksSum += (fReactiveSample + fTransparencyAndCompositionSample); |
|||
} |
|||
} |
|||
|
|||
if (fMasksSum > 0) |
|||
{ |
|||
for (FfxInt32 sampleIdx = 0; sampleIdx < 9; sampleIdx++) |
|||
{ |
|||
FfxFloat32x3 fColorSample = fColorSamples[sampleIdx]; |
|||
FfxFloat32 fReactiveSample = fReactiveSamples[sampleIdx]; |
|||
FfxFloat32 fTransparencyAndCompositionSample = fTransparencyAndCompositionSamples[sampleIdx]; |
|||
|
|||
const FfxFloat32 fMaxLenSq = ffxMax(dot(fReferenceColor, fReferenceColor), dot(fColorSample, fColorSample)); |
|||
const FfxFloat32 fSimilarity = dot(fReferenceColor, fColorSample) / fMaxLenSq; |
|||
|
|||
// Increase power for non-similar samples |
|||
const FfxFloat32 fPowerBiasMax = 6.0f; |
|||
const FfxFloat32 fSimilarityPower = 1.0f + (fPowerBiasMax - fSimilarity * fPowerBiasMax); |
|||
const FfxFloat32 fWeightedReactiveSample = ffxPow(fReactiveSample, fSimilarityPower); |
|||
const FfxFloat32 fWeightedTransparencyAndCompositionSample = ffxPow(fTransparencyAndCompositionSample, fSimilarityPower); |
|||
|
|||
fReactiveFactor = ffxMax(fReactiveFactor, FfxFloat32x2(fWeightedReactiveSample, fWeightedTransparencyAndCompositionSample)); |
|||
} |
|||
} |
|||
|
|||
StoreDilatedReactiveMasks(iPxLrPos, fReactiveFactor); |
|||
} |
|||
|
|||
FfxFloat32x3 ComputePreparedInputColor(FfxInt32x2 iPxLrPos) |
|||
{ |
|||
//We assume linear data. if non-linear input (sRGB, ...), |
|||
//then we should convert to linear first and back to sRGB on output. |
|||
FfxFloat32x3 fRgb = ffxMax(FfxFloat32x3(0, 0, 0), LoadInputColor(iPxLrPos)); |
|||
|
|||
fRgb = PrepareRgb(fRgb, Exposure(), PreExposure()); |
|||
|
|||
const FfxFloat32x3 fPreparedYCoCg = RGBToYCoCg(fRgb); |
|||
|
|||
return fPreparedYCoCg; |
|||
} |
|||
|
|||
FfxFloat32 EvaluateSurface(FfxInt32x2 iPxPos, FfxFloat32x2 fMotionVector) |
|||
{ |
|||
FfxFloat32 d0 = GetViewSpaceDepth(LoadReconstructedPrevDepth(iPxPos + FfxInt32x2(0, -1))); |
|||
FfxFloat32 d1 = GetViewSpaceDepth(LoadReconstructedPrevDepth(iPxPos + FfxInt32x2(0, 0))); |
|||
FfxFloat32 d2 = GetViewSpaceDepth(LoadReconstructedPrevDepth(iPxPos + FfxInt32x2(0, 1))); |
|||
|
|||
return 1.0f - FfxFloat32(((d0 - d1) > (d1 * 0.01f)) && ((d1 - d2) > (d2 * 0.01f))); |
|||
} |
|||
|
|||
void DepthClip(FfxInt32x2 iPxPos) |
|||
{ |
|||
FfxFloat32x2 fDepthUv = (iPxPos + 0.5f) / RenderSize(); |
|||
FfxFloat32x2 fMotionVector = LoadDilatedMotionVector(iPxPos); |
|||
|
|||
// Discard tiny mvs |
|||
fMotionVector *= FfxFloat32(length(fMotionVector * DisplaySize()) > 0.01f); |
|||
|
|||
const FfxFloat32x2 fDilatedUv = fDepthUv + fMotionVector; |
|||
const FfxFloat32 fDilatedDepth = LoadDilatedDepth(iPxPos); |
|||
const FfxFloat32 fCurrentDepthViewSpace = GetViewSpaceDepth(LoadInputDepth(iPxPos)); |
|||
|
|||
// Compute prepared input color and depth clip |
|||
FfxFloat32 fDepthClip = ComputeDepthClip(fDilatedUv, fDilatedDepth) * EvaluateSurface(iPxPos, fMotionVector); |
|||
FfxFloat32x3 fPreparedYCoCg = ComputePreparedInputColor(iPxPos); |
|||
StorePreparedInputColor(iPxPos, FfxFloat32x4(fPreparedYCoCg, fDepthClip)); |
|||
|
|||
// Compute dilated reactive mask |
|||
#if FFX_FSR3UPSCALER_OPTION_LOW_RESOLUTION_MOTION_VECTORS |
|||
FfxInt32x2 iSamplePos = iPxPos; |
|||
#else |
|||
FfxInt32x2 iSamplePos = ComputeHrPosFromLrPos(iPxPos); |
|||
#endif |
|||
|
|||
FfxFloat32 fMotionDivergence = ComputeMotionDivergence(iSamplePos, RenderSize()); |
|||
FfxFloat32 fTemporalMotionDifference = ffxSaturate(ComputeTemporalMotionDivergence(iPxPos) - ComputeDepthDivergence(iPxPos)); |
|||
|
|||
PreProcessReactiveMasks(iPxPos, ffxMax(fTemporalMotionDifference, fMotionDivergence)); |
|||
} |
|||
|
|||
#endif //!defined( FFX_FSR3UPSCALER_DEPTH_CLIPH ) |
|||
@ -1,65 +0,0 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 7c662249d70c4434da4f2da00e432c38 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
: Any |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
Exclude Editor: 1 |
|||
Exclude GameCoreScarlett: 1 |
|||
Exclude GameCoreXboxOne: 1 |
|||
Exclude Linux64: 1 |
|||
Exclude OSXUniversal: 1 |
|||
Exclude PS4: 1 |
|||
Exclude PS5: 1 |
|||
Exclude Win: 1 |
|||
Exclude Win64: 1 |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 0 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
- first: |
|||
Standalone: Linux64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: OSXUniversal |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -1,116 +0,0 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files (the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions: |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
|
|||
#ifndef FFX_FSR3UPSCALER_LOCK_H |
|||
#define FFX_FSR3UPSCALER_LOCK_H |
|||
|
|||
void ClearResourcesForNextFrame(in FfxInt32x2 iPxHrPos) |
|||
{ |
|||
if (all(FFX_LESS_THAN(iPxHrPos, FfxInt32x2(RenderSize())))) |
|||
{ |
|||
#if FFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH |
|||
const FfxUInt32 farZ = 0x0; |
|||
#else |
|||
const FfxUInt32 farZ = 0x3f800000; |
|||
#endif |
|||
SetReconstructedDepth(iPxHrPos, farZ); |
|||
} |
|||
} |
|||
|
|||
FfxBoolean ComputeThinFeatureConfidence(FfxInt32x2 pos) |
|||
{ |
|||
const FfxInt32 RADIUS = 1; |
|||
|
|||
FfxFloat32 fNucleus = LoadLockInputLuma(pos); |
|||
|
|||
FfxFloat32 similar_threshold = 1.05f; |
|||
FfxFloat32 dissimilarLumaMin = FSR3UPSCALER_FLT_MAX; |
|||
FfxFloat32 dissimilarLumaMax = 0; |
|||
|
|||
/* |
|||
0 1 2 |
|||
3 4 5 |
|||
6 7 8 |
|||
*/ |
|||
|
|||
#define SETBIT(x) (1U << x) |
|||
|
|||
FfxUInt32 mask = SETBIT(4); //flag fNucleus as similar |
|||
|
|||
const FfxUInt32 uNumRejectionMasks = 4; |
|||
const FfxUInt32 uRejectionMasks[uNumRejectionMasks] = { |
|||
SETBIT(0) | SETBIT(1) | SETBIT(3) | SETBIT(4), //Upper left |
|||
SETBIT(1) | SETBIT(2) | SETBIT(4) | SETBIT(5), //Upper right |
|||
SETBIT(3) | SETBIT(4) | SETBIT(6) | SETBIT(7), //Lower left |
|||
SETBIT(4) | SETBIT(5) | SETBIT(7) | SETBIT(8), //Lower right |
|||
}; |
|||
|
|||
FfxInt32 idx = 0; |
|||
FFX_UNROLL |
|||
for (FfxInt32 y = -RADIUS; y <= RADIUS; y++) { |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = -RADIUS; x <= RADIUS; x++, idx++) { |
|||
if (x == 0 && y == 0) continue; |
|||
|
|||
FfxInt32x2 samplePos = ClampLoad(pos, FfxInt32x2(x, y), FfxInt32x2(RenderSize())); |
|||
|
|||
FfxFloat32 sampleLuma = LoadLockInputLuma(samplePos); |
|||
FfxFloat32 difference = ffxMax(sampleLuma, fNucleus) / ffxMin(sampleLuma, fNucleus); |
|||
|
|||
if (difference > 0 && (difference < similar_threshold)) { |
|||
mask |= SETBIT(idx); |
|||
} else { |
|||
dissimilarLumaMin = ffxMin(dissimilarLumaMin, sampleLuma); |
|||
dissimilarLumaMax = ffxMax(dissimilarLumaMax, sampleLuma); |
|||
} |
|||
} |
|||
} |
|||
|
|||
FfxBoolean isRidge = fNucleus > dissimilarLumaMax || fNucleus < dissimilarLumaMin; |
|||
|
|||
if (FFX_FALSE == isRidge) { |
|||
|
|||
return false; |
|||
} |
|||
|
|||
FFX_UNROLL |
|||
for (FfxInt32 i = 0; i < 4; i++) { |
|||
|
|||
if ((mask & uRejectionMasks[i]) == uRejectionMasks[i]) { |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
void ComputeLock(FfxInt32x2 iPxLrPos) |
|||
{ |
|||
if (ComputeThinFeatureConfidence(iPxLrPos)) |
|||
{ |
|||
StoreNewLocks(ComputeHrPosFromLrPos(iPxLrPos), 1.f); |
|||
} |
|||
|
|||
// ClearResourcesForNextFrame(iPxLrPos); |
|||
} |
|||
|
|||
#endif // FFX_FSR3UPSCALER_LOCK_H |
|||
@ -1,65 +0,0 @@ |
|||
fileFormatVersion: 2 |
|||
guid: c7e9f53dd040b2645af5ccd936a94b0e |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
: Any |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
Exclude Editor: 1 |
|||
Exclude GameCoreScarlett: 1 |
|||
Exclude GameCoreXboxOne: 1 |
|||
Exclude Linux64: 1 |
|||
Exclude OSXUniversal: 1 |
|||
Exclude PS4: 1 |
|||
Exclude PS5: 1 |
|||
Exclude Win: 1 |
|||
Exclude Win64: 1 |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 0 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
- first: |
|||
Standalone: Linux64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: OSXUniversal |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,115 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
struct LumaInstabilityFactorData |
|||
{ |
|||
FfxFloat32x4 fLumaHistory; |
|||
FfxFloat32 fLumaInstabilityFactor; |
|||
}; |
|||
|
|||
LumaInstabilityFactorData ComputeLumaInstabilityFactor(LumaInstabilityFactorData data, FfxFloat32 fCurrentFrameLuma, FfxFloat32 fFarthestDepthInMeters) |
|||
{ |
|||
const FfxInt32 N_MINUS_1 = 0; |
|||
const FfxInt32 N_MINUS_2 = 1; |
|||
const FfxInt32 N_MINUS_3 = 2; |
|||
const FfxInt32 N_MINUS_4 = 3; |
|||
|
|||
FfxFloat32 fLumaInstability = 0.0f; |
|||
const FfxFloat32 fDiffs0 = (fCurrentFrameLuma - data.fLumaHistory[N_MINUS_1]); |
|||
const FfxFloat32 fSimilarity0 = MinDividedByMax(fCurrentFrameLuma, data.fLumaHistory[N_MINUS_1], 1.0f); |
|||
|
|||
FfxFloat32 fMaxSimilarity = fSimilarity0; |
|||
|
|||
if (fSimilarity0 < 1.0f) { |
|||
for (int i = N_MINUS_2; i <= N_MINUS_4; i++) { |
|||
const FfxFloat32 fDiffs1 = (fCurrentFrameLuma - data.fLumaHistory[i]); |
|||
const FfxFloat32 fSimilarity1 = MinDividedByMax(fCurrentFrameLuma, data.fLumaHistory[i]); |
|||
|
|||
if (sign(fDiffs0) == sign(fDiffs1)) { |
|||
|
|||
fMaxSimilarity = ffxMax(fMaxSimilarity, fSimilarity1); |
|||
} |
|||
} |
|||
|
|||
fLumaInstability = FfxFloat32(fMaxSimilarity > fSimilarity0); |
|||
} |
|||
|
|||
// Shift history |
|||
data.fLumaHistory[N_MINUS_4] = data.fLumaHistory[N_MINUS_3]; |
|||
data.fLumaHistory[N_MINUS_3] = data.fLumaHistory[N_MINUS_2]; |
|||
data.fLumaHistory[N_MINUS_2] = data.fLumaHistory[N_MINUS_1]; |
|||
data.fLumaHistory[N_MINUS_1] = fCurrentFrameLuma; |
|||
|
|||
data.fLumaHistory /= Exposure(); |
|||
|
|||
data.fLumaInstabilityFactor = fLumaInstability * FfxFloat32(data.fLumaHistory[N_MINUS_4] != 0); |
|||
|
|||
return data; |
|||
} |
|||
|
|||
void LumaInstability(FfxInt32x2 iPxPos) |
|||
{ |
|||
LumaInstabilityFactorData data; |
|||
data.fLumaInstabilityFactor = 0.0f; |
|||
data.fLumaHistory = FfxFloat32x4(0.0f, 0.0f, 0.0f, 0.0f); |
|||
|
|||
const FfxFloat32x2 fDilatedMotionVector = LoadDilatedMotionVector(iPxPos); |
|||
const FfxFloat32x2 fUv = (iPxPos + 0.5f) / RenderSize(); |
|||
const FfxFloat32x2 fUvCurrFrameJittered = fUv + Jitter() / RenderSize(); |
|||
const FfxFloat32x2 fUvPrevFrameJittered = fUv + PreviousFrameJitter() / PreviousFrameRenderSize(); |
|||
const FfxFloat32x2 fReprojectedUv = fUvPrevFrameJittered + fDilatedMotionVector; |
|||
|
|||
if (IsUvInside(fReprojectedUv)) |
|||
{ |
|||
const FfxFloat32x2 fUvReactive_HW = ClampUv(fUvCurrFrameJittered, RenderSize(), MaxRenderSize()); |
|||
|
|||
const FfxFloat32x4 fDilatedReactiveMasks = SampleDilatedReactiveMasks(fUvReactive_HW); |
|||
const FfxFloat32 fReactiveMask = ffxSaturate(fDilatedReactiveMasks[REACTIVE]); |
|||
const FfxFloat32 fDisocclusion = ffxSaturate(fDilatedReactiveMasks[DISOCCLUSION]); |
|||
const FfxFloat32 fShadingChange = ffxSaturate(fDilatedReactiveMasks[SHADING_CHANGE]); |
|||
const FfxFloat32 fAccumulation = ffxSaturate(fDilatedReactiveMasks[ACCUMULAION]); |
|||
|
|||
const FfxBoolean bAccumulationFactor = fAccumulation > 0.9f; |
|||
|
|||
const FfxBoolean bComputeInstability = bAccumulationFactor; |
|||
|
|||
if (bComputeInstability) { |
|||
|
|||
const FfxFloat32x2 fUv_HW = ClampUv(fUvCurrFrameJittered, RenderSize(), MaxRenderSize()); |
|||
const FfxFloat32 fCurrentFrameLuma = SampleCurrentLuma(fUv_HW) * Exposure(); |
|||
|
|||
const FfxFloat32x2 fReprojectedUv_HW = ClampUv(fReprojectedUv, PreviousFrameRenderSize(), MaxRenderSize()); |
|||
data.fLumaHistory = SampleLumaHistory(fReprojectedUv_HW) * DeltaPreExposure() * Exposure(); |
|||
|
|||
const FfxFloat32x2 fFarthestDepthUv_HW = ClampUv(fUvCurrFrameJittered, RenderSize() / 2, GetFarthestDepthMip1ResourceDimensions()); |
|||
const FfxFloat32 fFarthestDepthInMeters = SampleFarthestDepthMip1(fFarthestDepthUv_HW); |
|||
|
|||
data = ComputeLumaInstabilityFactor(data, fCurrentFrameLuma, fFarthestDepthInMeters); |
|||
|
|||
const FfxFloat32 fVelocityWeight = 1.0f - ffxSaturate(Get4KVelocity(fDilatedMotionVector) / 20.0f); |
|||
data.fLumaInstabilityFactor *= fVelocityWeight * (1.0f - fDisocclusion) * (1.0f - fReactiveMask) * (1.0f - fShadingChange); |
|||
} |
|||
} |
|||
|
|||
StoreLumaHistory(iPxPos, data.fLumaHistory); |
|||
StoreLumaInstability(iPxPos, data.fLumaInstabilityFactor); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: ccf5158f46f46d040b6142a6c7cb1d75 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 3f5a9f1fd09f2e54a978bc20e89ea326 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -1,107 +0,0 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files (the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions: |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
|
|||
#ifndef FFX_FSR3UPSCALER_POSTPROCESS_LOCK_STATUS_H |
|||
#define FFX_FSR3UPSCALER_POSTPROCESS_LOCK_STATUS_H |
|||
|
|||
FfxFloat32x4 WrapShadingChangeLuma(FfxInt32x2 iPxSample) |
|||
{ |
|||
return FfxFloat32x4(LoadMipLuma(iPxSample, LumaMipLevelToUse()), 0, 0, 0); |
|||
} |
|||
|
|||
#if FFX_HALF |
|||
FFX_MIN16_F4 WrapShadingChangeLuma(FFX_MIN16_I2 iPxSample) |
|||
{ |
|||
return FFX_MIN16_F4(LoadMipLuma(iPxSample, LumaMipLevelToUse()), 0, 0, 0); |
|||
} |
|||
#endif |
|||
|
|||
#if FFX_FSR3UPSCALER_OPTION_POSTPROCESSLOCKSTATUS_SAMPLERS_USE_DATA_HALF && FFX_HALF |
|||
DeclareCustomFetchBilinearSamplesMin16(FetchShadingChangeLumaSamples, WrapShadingChangeLuma) |
|||
#else |
|||
DeclareCustomFetchBicubicSamples(FetchShadingChangeLumaSamples, WrapShadingChangeLuma) |
|||
#endif |
|||
DeclareCustomTextureSample(ShadingChangeLumaSample, Lanczos2, FetchShadingChangeLumaSamples) |
|||
|
|||
FfxFloat32 GetShadingChangeLuma(FfxInt32x2 iPxHrPos, FfxFloat32x2 fUvCoord) |
|||
{ |
|||
FfxFloat32 fShadingChangeLuma = 0; |
|||
|
|||
#if 0 |
|||
fShadingChangeLuma = Exposure() * exp(ShadingChangeLumaSample(fUvCoord, LumaMipDimensions()).x); |
|||
#else |
|||
|
|||
const FfxFloat32 fDiv = FfxFloat32(2u << LumaMipLevelToUse()); |
|||
FfxInt32x2 iMipRenderSize = FfxInt32x2(RenderSize() / fDiv); |
|||
|
|||
fUvCoord = ClampUv(fUvCoord, iMipRenderSize, LumaMipDimensions()); |
|||
fShadingChangeLuma = Exposure() * exp(FfxFloat32(SampleMipLuma(fUvCoord, LumaMipLevelToUse()))); |
|||
#endif |
|||
|
|||
fShadingChangeLuma = ffxPow(fShadingChangeLuma, 1.0f / 6.0f); |
|||
|
|||
return fShadingChangeLuma; |
|||
} |
|||
|
|||
void UpdateLockStatus(AccumulationPassCommonParams params, |
|||
FFX_PARAMETER_INOUT FfxFloat32 fReactiveFactor, LockState state, |
|||
FFX_PARAMETER_INOUT FfxFloat32x2 fLockStatus, |
|||
FFX_PARAMETER_OUT FfxFloat32 fLockContributionThisFrame, |
|||
FFX_PARAMETER_OUT FfxFloat32 fLuminanceDiff) { |
|||
|
|||
const FfxFloat32 fShadingChangeLuma = GetShadingChangeLuma(params.iPxHrPos, params.fHrUv); |
|||
|
|||
//init temporal shading change factor, init to -1 or so in reproject to know if "true new"? |
|||
fLockStatus[LOCK_TEMPORAL_LUMA] = (fLockStatus[LOCK_TEMPORAL_LUMA] == FfxFloat32(0.0f)) ? fShadingChangeLuma : fLockStatus[LOCK_TEMPORAL_LUMA]; |
|||
|
|||
FfxFloat32 fPreviousShadingChangeLuma = fLockStatus[LOCK_TEMPORAL_LUMA]; |
|||
|
|||
fLuminanceDiff = 1.0f - MinDividedByMax(fPreviousShadingChangeLuma, fShadingChangeLuma); |
|||
|
|||
if (state.NewLock) { |
|||
fLockStatus[LOCK_TEMPORAL_LUMA] = fShadingChangeLuma; |
|||
|
|||
fLockStatus[LOCK_LIFETIME_REMAINING] = (fLockStatus[LOCK_LIFETIME_REMAINING] != 0.0f) ? 2.0f : 1.0f; |
|||
} |
|||
else if(fLockStatus[LOCK_LIFETIME_REMAINING] <= 1.0f) { |
|||
fLockStatus[LOCK_TEMPORAL_LUMA] = ffxLerp(fLockStatus[LOCK_TEMPORAL_LUMA], FfxFloat32(fShadingChangeLuma), 0.5f); |
|||
} |
|||
else { |
|||
if (fLuminanceDiff > 0.1f) { |
|||
KillLock(fLockStatus); |
|||
} |
|||
} |
|||
|
|||
fReactiveFactor = ffxMax(fReactiveFactor, ffxSaturate((fLuminanceDiff - 0.1f) * 10.0f)); |
|||
fLockStatus[LOCK_LIFETIME_REMAINING] *= (1.0f - fReactiveFactor); |
|||
|
|||
fLockStatus[LOCK_LIFETIME_REMAINING] *= ffxSaturate(1.0f - params.fAccumulationMask); |
|||
fLockStatus[LOCK_LIFETIME_REMAINING] *= FfxFloat32(params.fDepthClipFactor < 0.1f); |
|||
|
|||
// Compute this frame lock contribution |
|||
const FfxFloat32 fLifetimeContribution = ffxSaturate(fLockStatus[LOCK_LIFETIME_REMAINING] - 1.0f); |
|||
const FfxFloat32 fShadingChangeContribution = ffxSaturate(MinDividedByMax(fLockStatus[LOCK_TEMPORAL_LUMA], fShadingChangeLuma)); |
|||
|
|||
fLockContributionThisFrame = ffxSaturate(ffxSaturate(fLifetimeContribution * 4.0f) * fShadingChangeContribution); |
|||
} |
|||
|
|||
#endif //!defined( FFX_FSR3UPSCALER_POSTPROCESS_LOCK_STATUS_H ) |
|||
@ -1,65 +0,0 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 67a8b72ceb93d634f883b086fdccb348 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
: Any |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
Exclude Editor: 1 |
|||
Exclude GameCoreScarlett: 1 |
|||
Exclude GameCoreXboxOne: 1 |
|||
Exclude Linux64: 1 |
|||
Exclude OSXUniversal: 1 |
|||
Exclude PS4: 1 |
|||
Exclude PS5: 1 |
|||
Exclude Win: 1 |
|||
Exclude Win64: 1 |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 0 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
- first: |
|||
Standalone: Linux64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: OSXUniversal |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,152 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
void ReconstructPrevDepth(FfxInt32x2 iPxPos, FfxFloat32 fDepth, FfxFloat32x2 fMotionVector) |
|||
{ |
|||
const FfxFloat32 fNearestDepthInMeters = ffxMin(GetViewSpaceDepthInMeters(fDepth), FSR3UPSCALER_FP16_MAX); |
|||
const FfxFloat32 fReconstructedDeptMvThreshold = ReconstructedDepthMvPxThreshold(fNearestDepthInMeters); |
|||
|
|||
// Discard small mvs |
|||
fMotionVector *= FfxFloat32(Get4KVelocity(fMotionVector) > fReconstructedDeptMvThreshold); |
|||
|
|||
const FfxFloat32x2 fUv = (iPxPos + FfxFloat32(0.5)) / RenderSize(); |
|||
const FfxFloat32x2 fReprojectedUv = fUv + fMotionVector; |
|||
const BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fReprojectedUv, RenderSize()); |
|||
|
|||
// Project current depth into previous frame locations. |
|||
// Push to all pixels having some contribution if reprojection is using bilinear logic. |
|||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++) { |
|||
|
|||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex]; |
|||
const FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex]; |
|||
|
|||
if (fWeight > fReconstructedDepthBilinearWeightThreshold) { |
|||
|
|||
const FfxInt32x2 iStorePos = bilinearInfo.iBasePos + iOffset; |
|||
if (IsOnScreen(iStorePos, RenderSize())) { |
|||
StoreReconstructedDepth(iStorePos, fDepth); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
struct DepthExtents |
|||
{ |
|||
FfxFloat32 fNearest; |
|||
FfxInt32x2 fNearestCoord; |
|||
FfxFloat32 fFarthest; |
|||
}; |
|||
|
|||
DepthExtents FindDepthExtents(FFX_PARAMETER_IN FfxInt32x2 iPxPos) |
|||
{ |
|||
DepthExtents extents; |
|||
const FfxInt32 iSampleCount = 9; |
|||
const FfxInt32x2 iSampleOffsets[iSampleCount] = { |
|||
FfxInt32x2(+0, +0), |
|||
FfxInt32x2(+1, +0), |
|||
FfxInt32x2(+0, +1), |
|||
FfxInt32x2(+0, -1), |
|||
FfxInt32x2(-1, +0), |
|||
FfxInt32x2(-1, +1), |
|||
FfxInt32x2(+1, +1), |
|||
FfxInt32x2(-1, -1), |
|||
FfxInt32x2(+1, -1), |
|||
}; |
|||
|
|||
// pull out the depth loads to allow SC to batch them |
|||
FfxFloat32 depth[9]; |
|||
FfxInt32 iSampleIndex = 0; |
|||
FFX_UNROLL |
|||
for (iSampleIndex = 0; iSampleIndex < iSampleCount; ++iSampleIndex) { |
|||
|
|||
FfxInt32x2 iPos = iPxPos + iSampleOffsets[iSampleIndex]; |
|||
depth[iSampleIndex] = LoadInputDepth(iPos); |
|||
} |
|||
|
|||
// find closest depth |
|||
extents.fNearestCoord = iPxPos; |
|||
extents.fNearest = depth[0]; |
|||
extents.fFarthest = depth[0]; |
|||
FFX_UNROLL |
|||
for (iSampleIndex = 1; iSampleIndex < iSampleCount; ++iSampleIndex) { |
|||
|
|||
const FfxInt32x2 iPos = iPxPos + iSampleOffsets[iSampleIndex]; |
|||
if (IsOnScreen(iPos, RenderSize())) { |
|||
|
|||
FfxFloat32 fNdDepth = depth[iSampleIndex]; |
|||
#if FFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH |
|||
if (fNdDepth > extents.fNearest) { |
|||
extents.fFarthest = ffxMin(extents.fFarthest, fNdDepth); |
|||
#else |
|||
if (fNdDepth < extents.fNearest) { |
|||
extents.fFarthest = ffxMax(extents.fFarthest, fNdDepth); |
|||
#endif |
|||
extents.fNearestCoord = iPos; |
|||
extents.fNearest = fNdDepth; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return extents; |
|||
} |
|||
|
|||
FfxFloat32x2 DilateMotionVector(FfxInt32x2 iPxPos, const DepthExtents depthExtents) |
|||
{ |
|||
#if FFX_FSR3UPSCALER_OPTION_LOW_RESOLUTION_MOTION_VECTORS |
|||
const FfxInt32x2 iSamplePos = iPxPos; |
|||
const FfxInt32x2 iMotionVectorPos = depthExtents.fNearestCoord; |
|||
#else |
|||
const FfxInt32x2 iSamplePos = ComputeHrPosFromLrPos(iPxPos); |
|||
const FfxInt32x2 iMotionVectorPos = ComputeHrPosFromLrPos(depthExtents.fNearestCoord); |
|||
#endif |
|||
|
|||
const FfxFloat32x2 fDilatedMotionVector = LoadInputMotionVector(iMotionVectorPos); |
|||
|
|||
return fDilatedMotionVector; |
|||
} |
|||
|
|||
FfxFloat32 GetCurrentFrameLuma(FfxInt32x2 iPxPos) |
|||
{ |
|||
//We assume linear data. if non-linear input (sRGB, ...), |
|||
//then we should convert to linear first and back to sRGB on output. |
|||
const FfxFloat32x3 fRgb = ffxMax(FfxFloat32x3(0, 0, 0), LoadInputColor(iPxPos)); |
|||
const FfxFloat32 fLuma = RGBToLuma(fRgb); |
|||
|
|||
return fLuma; |
|||
} |
|||
|
|||
void PrepareInputs(FfxInt32x2 iPxPos) |
|||
{ |
|||
const DepthExtents depthExtents = FindDepthExtents(iPxPos); |
|||
const FfxFloat32x2 fDilatedMotionVector = DilateMotionVector(iPxPos, depthExtents); |
|||
|
|||
ReconstructPrevDepth(iPxPos, depthExtents.fNearest, fDilatedMotionVector); |
|||
|
|||
StoreDilatedMotionVector(iPxPos, fDilatedMotionVector); |
|||
StoreDilatedDepth(iPxPos, depthExtents.fNearest); |
|||
|
|||
const FfxFloat32 fFarthestDepthInMeters = ffxMin(GetViewSpaceDepthInMeters(depthExtents.fFarthest), FSR3UPSCALER_FP16_MAX); |
|||
StoreFarthestDepth(iPxPos, fFarthestDepthInMeters); |
|||
|
|||
const FfxFloat32 fLuma = GetCurrentFrameLuma(iPxPos); |
|||
StoreCurrentLuma(iPxPos, fLuma); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 8c3e6a508446fc34590d9b426d75ae30 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,270 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
FfxFloat32 ComputeDisocclusions(FfxFloat32x2 fUv, FfxFloat32x2 fMotionVector, FfxFloat32 fCurrentDepthViewSpace) |
|||
{ |
|||
const FfxFloat32 fNearestDepthInMeters = ffxMin(fCurrentDepthViewSpace * ViewSpaceToMetersFactor(), FSR3UPSCALER_FP16_MAX); |
|||
const FfxFloat32 fReconstructedDeptMvThreshold = ReconstructedDepthMvPxThreshold(fNearestDepthInMeters); |
|||
|
|||
fMotionVector *= FfxFloat32(Get4KVelocity(fMotionVector) > fReconstructedDeptMvThreshold); |
|||
|
|||
const FfxFloat32x2 fReprojectedUv = fUv + fMotionVector; |
|||
const BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fReprojectedUv, RenderSize()); |
|||
|
|||
FfxFloat32 fDisocclusion = 0.0f; |
|||
FfxFloat32 fWeightSum = 0.0f; |
|||
FfxBoolean bPotentialDisocclusion = true; |
|||
|
|||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4 && bPotentialDisocclusion; iSampleIndex++) |
|||
{ |
|||
|
|||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex]; |
|||
const FfxInt32x2 iSamplePos = ClampLoad(bilinearInfo.iBasePos, iOffset, FfxInt32x2(RenderSize())); |
|||
|
|||
if (IsOnScreen(iSamplePos, RenderSize())) { |
|||
const FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex]; |
|||
if (fWeight > fReconstructedDepthBilinearWeightThreshold) { |
|||
|
|||
const FfxFloat32 fPrevNearestDepthViewSpace = GetViewSpaceDepth(LoadReconstructedPrevDepth(iSamplePos)); |
|||
const FfxFloat32 fDepthDifference = fCurrentDepthViewSpace - fPrevNearestDepthViewSpace; |
|||
|
|||
bPotentialDisocclusion = bPotentialDisocclusion && (fDepthDifference > FSR3UPSCALER_FP32_MIN); |
|||
|
|||
if (bPotentialDisocclusion) { |
|||
const FfxFloat32 fHalfViewportWidth = length(FfxFloat32x2(RenderSize()) * 0.5f); |
|||
const FfxFloat32 fDepthThreshold = ffxMax(fCurrentDepthViewSpace, fPrevNearestDepthViewSpace); |
|||
|
|||
const FfxFloat32 Ksep = 1.37e-05f; |
|||
const FfxFloat32 fRequiredDepthSeparation = Ksep * fHalfViewportWidth * fDepthThreshold; |
|||
|
|||
fDisocclusion += ffxSaturate(FfxFloat32(fRequiredDepthSeparation / fDepthDifference)) * fWeight; |
|||
fWeightSum += fWeight; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
fDisocclusion = (bPotentialDisocclusion && fWeightSum > 0) ? ffxSaturate(1.0f - fDisocclusion / fWeightSum) : 0.0f; |
|||
|
|||
return fDisocclusion; |
|||
} |
|||
|
|||
FfxFloat32 ComputeMotionDivergence(FfxFloat32x2 fUv, FfxFloat32x2 fMotionVector, FfxFloat32 fCurrentDepthSample) |
|||
{ |
|||
const FfxInt32x2 iPxReprojectedPos = FfxInt32x2((fUv + fMotionVector) * RenderSize()); |
|||
const FfxFloat32 fReprojectedDepth = LoadDilatedDepth(iPxReprojectedPos); |
|||
const FfxFloat32x2 fReprojectedMotionVector = LoadDilatedMotionVector(iPxReprojectedPos); |
|||
|
|||
const FfxFloat32 fReprojectedVelocity = Get4KVelocity(fReprojectedMotionVector); |
|||
const FfxFloat32 f4KVelocity = Get4KVelocity(fMotionVector); |
|||
|
|||
const FfxFloat32 fMaxLen = max(length(fMotionVector), length(fReprojectedMotionVector)); |
|||
|
|||
const FfxFloat32 fNucleusDepthInMeters = GetViewSpaceDepthInMeters(fReprojectedDepth); |
|||
const FfxFloat32 fCurrentDepthInMeters = GetViewSpaceDepthInMeters(fCurrentDepthSample); |
|||
|
|||
const FfxFloat32 fDistanceFactor = MinDividedByMax(fNucleusDepthInMeters, fCurrentDepthInMeters); |
|||
const FfxFloat32 fVelocityFactor = ffxSaturate(f4KVelocity / 10.0f); |
|||
const FfxFloat32 fMotionVectorFieldConfidence = (1.0f - ffxSaturate(fReprojectedVelocity / f4KVelocity)) * fDistanceFactor * fVelocityFactor; |
|||
|
|||
return fMotionVectorFieldConfidence; |
|||
} |
|||
|
|||
FfxFloat32 DilateReactiveMasks(FfxInt32x2 iPxPos, FfxFloat32x2 fUv) |
|||
{ |
|||
FfxFloat32 fDilatedReactiveMasks = 0.0f; |
|||
|
|||
FFX_UNROLL |
|||
for (FfxInt32 y = -1; y <=1; y++) |
|||
{ |
|||
FFX_UNROLL |
|||
for (FfxInt32 x = -1; x <= 1; x++) |
|||
{ |
|||
const FfxInt32x2 sampleCoord = ClampLoad(iPxPos, FfxInt32x2(x, y), FfxInt32x2(RenderSize())); |
|||
fDilatedReactiveMasks = ffxMax(fDilatedReactiveMasks, LoadReactiveMask(sampleCoord)); |
|||
} |
|||
} |
|||
|
|||
return fDilatedReactiveMasks; |
|||
} |
|||
|
|||
FfxFloat32 DilateTransparencyAndCompositionMasks(FfxInt32x2 iPxPos, FfxFloat32x2 fUv) |
|||
{ |
|||
const FfxFloat32x2 fUvTransparencyAndCompositionMask = ClampUv(fUv, RenderSize(), GetTransparencyAndCompositionMaskResourceDimensions()); |
|||
return SampleTransparencyAndCompositionMask(fUvTransparencyAndCompositionMask); |
|||
} |
|||
|
|||
FfxFloat32 ComputeThinFeatureConfidence(FfxInt32x2 iPxPos) |
|||
{ |
|||
/* |
|||
1 2 3 |
|||
4 0 5 |
|||
6 7 8 |
|||
*/ |
|||
|
|||
const FfxInt32 iNucleusIndex = 0; |
|||
const FfxInt32 iSampleCount = 9; |
|||
const FfxInt32x2 iSampleOffsets[iSampleCount] = { |
|||
FfxInt32x2(+0, +0), |
|||
FfxInt32x2(-1, -1), |
|||
FfxInt32x2(+0, -1), |
|||
FfxInt32x2(+1, -1), |
|||
FfxInt32x2(-1, +0), |
|||
FfxInt32x2(+1, +0), |
|||
FfxInt32x2(-1, +1), |
|||
FfxInt32x2(+0, +1), |
|||
FfxInt32x2(+1, +1), |
|||
}; |
|||
|
|||
FfxFloat32 fSamples[iSampleCount]; |
|||
|
|||
FfxFloat32 fLumaMin = FSR3UPSCALER_FP32_MAX; |
|||
FfxFloat32 fLumaMax = FSR3UPSCALER_FP32_MIN; |
|||
|
|||
FFX_UNROLL |
|||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < iSampleCount; ++iSampleIndex) { |
|||
const FfxInt32x2 iPxSamplePos = ClampLoad(iPxPos, iSampleOffsets[iSampleIndex], FfxInt32x2(RenderSize())); |
|||
fSamples[iSampleIndex] = LoadCurrentLuma(iPxSamplePos) * Exposure(); |
|||
|
|||
fLumaMin = ffxMin(fLumaMin, fSamples[iSampleIndex]); |
|||
fLumaMax = ffxMax(fLumaMax, fSamples[iSampleIndex]); |
|||
} |
|||
|
|||
const FfxFloat32 fThreshold = 0.9f; |
|||
FfxFloat32 fDissimilarLumaMin = FSR3UPSCALER_FP32_MAX; |
|||
FfxFloat32 fDissimilarLumaMax = 0; |
|||
|
|||
#define SETBIT(x) (1U << x) |
|||
|
|||
FfxUInt32 uPatternMask = SETBIT(iNucleusIndex); // Flag nucleus as similar |
|||
|
|||
const FfxUInt32 uNumRejectionMasks = 4; |
|||
const FfxUInt32 uRejectionMasks[uNumRejectionMasks] = { |
|||
SETBIT(1) | SETBIT(2) | SETBIT(4) | SETBIT(iNucleusIndex), // Upper left |
|||
SETBIT(2) | SETBIT(3) | SETBIT(5) | SETBIT(iNucleusIndex), // Upper right |
|||
SETBIT(4) | SETBIT(6) | SETBIT(7) | SETBIT(iNucleusIndex), // Lower left |
|||
SETBIT(5) | SETBIT(7) | SETBIT(8) | SETBIT(iNucleusIndex) // Lower right |
|||
}; |
|||
|
|||
FfxInt32 iBitIndex = 1; |
|||
FFX_UNROLL |
|||
for (FfxInt32 iSampleIndex = 1; iSampleIndex < iSampleCount; ++iSampleIndex, ++iBitIndex) { |
|||
|
|||
const FfxFloat32 fDifference = abs(fSamples[iSampleIndex] - fSamples[iNucleusIndex]) / (fLumaMax - fLumaMin); |
|||
|
|||
if (fDifference < fThreshold) |
|||
{ |
|||
uPatternMask |= SETBIT(iBitIndex); |
|||
} |
|||
else |
|||
{ |
|||
fDissimilarLumaMin = ffxMin(fDissimilarLumaMin, fSamples[iSampleIndex]); |
|||
fDissimilarLumaMax = ffxMax(fDissimilarLumaMax, fSamples[iSampleIndex]); |
|||
} |
|||
} |
|||
|
|||
const FfxBoolean bIsRidge = fSamples[iNucleusIndex] > fDissimilarLumaMax || fSamples[iNucleusIndex] < fDissimilarLumaMin; |
|||
|
|||
if (FFX_FALSE == bIsRidge) |
|||
{ |
|||
return 0.0f; |
|||
} |
|||
|
|||
FFX_UNROLL |
|||
for (FfxInt32 i = 0; i < uNumRejectionMasks; i++) |
|||
{ |
|||
if ((uPatternMask & uRejectionMasks[i]) == uRejectionMasks[i]) |
|||
{ |
|||
return 0.0f; |
|||
} |
|||
} |
|||
|
|||
return 1.0f - fLumaMin / fLumaMax; |
|||
} |
|||
|
|||
FfxFloat32 UpdateAccumulation(FfxInt32x2 iPxPos, FfxFloat32x2 fUv, FfxFloat32x2 fMotionVector, FfxFloat32 fDisocclusion, FfxFloat32 fShadingChange) |
|||
{ |
|||
const FfxFloat32x2 fReprojectedUv = fUv + fMotionVector; |
|||
FfxFloat32 fAccumulation = 0.0f; |
|||
|
|||
if (IsUvInside(fReprojectedUv)) { |
|||
const FfxFloat32x2 fReprojectedUv_HW = ClampUv(fReprojectedUv, PreviousFrameRenderSize(), MaxRenderSize()); |
|||
fAccumulation = ffxSaturate(SampleAccumulation(fReprojectedUv_HW)); |
|||
} |
|||
|
|||
fAccumulation = ffxLerp(fAccumulation, 0.0f, fShadingChange); |
|||
fAccumulation = ffxLerp(fAccumulation, ffxMin(fAccumulation, 0.25f), fDisocclusion); |
|||
|
|||
fAccumulation *= FfxFloat32(round(fAccumulation * 100.0f) > 1.0f); |
|||
|
|||
// Update for next frame, normalize to store in unorm |
|||
const FfxFloat32 fAccumulatedFramesMax = 3.0f; |
|||
const FfxFloat32 fAccumulatedFramesToStore = ffxSaturate(fAccumulation + (1.0f / fAccumulatedFramesMax)); |
|||
StoreAccumulation(iPxPos, fAccumulatedFramesToStore); |
|||
|
|||
return fAccumulation; |
|||
} |
|||
|
|||
FfxFloat32 ComputeShadingChange(FfxFloat32x2 fUv) |
|||
{ |
|||
// NOTE: Here we re-apply jitter, will be reverted again when sampled in accumulation pass |
|||
const FfxFloat32x2 fShadingChangeUv = ClampUv(fUv - Jitter() / RenderSize(), ShadingChangeRenderSize(), ShadingChangeMaxRenderSize()); |
|||
const FfxFloat32 fShadingChange = ffxSaturate(SampleShadingChange(fShadingChangeUv)); |
|||
|
|||
return fShadingChange; |
|||
} |
|||
|
|||
void PrepareReactivity(FfxInt32x2 iPxPos) |
|||
{ |
|||
const FfxFloat32x2 fUv = (iPxPos + 0.5f) / RenderSize(); |
|||
const FfxFloat32x2 fMotionVector = LoadDilatedMotionVector(iPxPos); |
|||
|
|||
// Discard small mvs |
|||
const FfxFloat32 f4KVelocity = Get4KVelocity(fMotionVector); |
|||
|
|||
const FfxFloat32x2 fDilatedUv = fUv + fMotionVector; |
|||
const FfxFloat32 fDilatedDepth = LoadDilatedDepth(iPxPos); |
|||
const FfxFloat32 fDepthInMeters = GetViewSpaceDepthInMeters(fDilatedDepth); |
|||
|
|||
const FfxFloat32 fDisocclusion = ComputeDisocclusions(fUv, fMotionVector, GetViewSpaceDepth(fDilatedDepth)); |
|||
const FfxFloat32 fShadingChange = ffxMax(DilateReactiveMasks(iPxPos, fUv), ComputeShadingChange(fUv)); |
|||
|
|||
const FfxFloat32 fMotionDivergence = ComputeMotionDivergence(fUv, fMotionVector, fDilatedDepth); |
|||
const FfxFloat32 fDilatedTransparencyAndComposition = DilateTransparencyAndCompositionMasks(iPxPos, fUv); |
|||
const FfxFloat32 fFinalReactiveness = ffxMax(fMotionDivergence, fDilatedTransparencyAndComposition); |
|||
|
|||
const FfxFloat32 fAccumulation = UpdateAccumulation(iPxPos, fUv, fMotionVector, fDisocclusion, fShadingChange); |
|||
|
|||
FfxFloat32x4 fOutput; |
|||
fOutput[REACTIVE] = fFinalReactiveness; |
|||
fOutput[DISOCCLUSION] = fDisocclusion; |
|||
fOutput[SHADING_CHANGE] = fShadingChange; |
|||
fOutput[ACCUMULAION] = fAccumulation; |
|||
|
|||
StoreDilatedReactiveMasks(iPxPos, fOutput); |
|||
|
|||
const FfxFloat32 fLockStrength = ComputeThinFeatureConfidence(iPxPos); |
|||
if (fLockStrength > (1.0f / 100.0f)) |
|||
{ |
|||
StoreNewLocks(ComputeHrPosFromLrPos(FfxInt32x2(iPxPos)), fLockStrength); |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: d3e61797324ec384b96b9c14d17b34d1 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -1,146 +0,0 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files (the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions: |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
|
|||
#ifndef FFX_FSR3UPSCALER_RECONSTRUCT_DILATED_VELOCITY_AND_PREVIOUS_DEPTH_H |
|||
#define FFX_FSR3UPSCALER_RECONSTRUCT_DILATED_VELOCITY_AND_PREVIOUS_DEPTH_H |
|||
|
|||
void ReconstructPrevDepth(FfxInt32x2 iPxPos, FfxFloat32 fDepth, FfxFloat32x2 fMotionVector, FfxInt32x2 iPxDepthSize) |
|||
{ |
|||
fMotionVector *= FfxFloat32(length(fMotionVector * DisplaySize()) > 0.1f); |
|||
|
|||
FfxFloat32x2 fUv = (iPxPos + FfxFloat32(0.5)) / iPxDepthSize; |
|||
FfxFloat32x2 fReprojectedUv = fUv + fMotionVector; |
|||
|
|||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fReprojectedUv, RenderSize()); |
|||
|
|||
// Project current depth into previous frame locations. |
|||
// Push to all pixels having some contribution if reprojection is using bilinear logic. |
|||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++) { |
|||
|
|||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex]; |
|||
FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex]; |
|||
|
|||
if (fWeight > fReconstructedDepthBilinearWeightThreshold) { |
|||
|
|||
FfxInt32x2 iStorePos = bilinearInfo.iBasePos + iOffset; |
|||
if (IsOnScreen(iStorePos, iPxDepthSize)) { |
|||
StoreReconstructedDepth(iStorePos, fDepth); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
void FindNearestDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxInt32x2 iPxSize, FFX_PARAMETER_OUT FfxFloat32 fNearestDepth, FFX_PARAMETER_OUT FfxInt32x2 fNearestDepthCoord) |
|||
{ |
|||
const FfxInt32 iSampleCount = 9; |
|||
const FfxInt32x2 iSampleOffsets[iSampleCount] = { |
|||
FfxInt32x2(+0, +0), |
|||
FfxInt32x2(+1, +0), |
|||
FfxInt32x2(+0, +1), |
|||
FfxInt32x2(+0, -1), |
|||
FfxInt32x2(-1, +0), |
|||
FfxInt32x2(-1, +1), |
|||
FfxInt32x2(+1, +1), |
|||
FfxInt32x2(-1, -1), |
|||
FfxInt32x2(+1, -1), |
|||
}; |
|||
|
|||
// pull out the depth loads to allow SC to batch them |
|||
FfxFloat32 depth[9]; |
|||
FfxInt32 iSampleIndex = 0; |
|||
FFX_UNROLL |
|||
for (iSampleIndex = 0; iSampleIndex < iSampleCount; ++iSampleIndex) { |
|||
|
|||
FfxInt32x2 iPos = iPxPos + iSampleOffsets[iSampleIndex]; |
|||
depth[iSampleIndex] = LoadInputDepth(iPos); |
|||
} |
|||
|
|||
// find closest depth |
|||
fNearestDepthCoord = iPxPos; |
|||
fNearestDepth = depth[0]; |
|||
FFX_UNROLL |
|||
for (iSampleIndex = 1; iSampleIndex < iSampleCount; ++iSampleIndex) { |
|||
|
|||
FfxInt32x2 iPos = iPxPos + iSampleOffsets[iSampleIndex]; |
|||
if (IsOnScreen(iPos, iPxSize)) { |
|||
|
|||
FfxFloat32 fNdDepth = depth[iSampleIndex]; |
|||
#if FFX_FSR3UPSCALER_OPTION_INVERTED_DEPTH |
|||
if (fNdDepth > fNearestDepth) { |
|||
#else |
|||
if (fNdDepth < fNearestDepth) { |
|||
#endif |
|||
fNearestDepthCoord = iPos; |
|||
fNearestDepth = fNdDepth; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
FfxFloat32 ComputeLockInputLuma(FfxInt32x2 iPxLrPos) |
|||
{ |
|||
//We assume linear data. if non-linear input (sRGB, ...), |
|||
//then we should convert to linear first and back to sRGB on output. |
|||
FfxFloat32x3 fRgb = ffxMax(FfxFloat32x3(0, 0, 0), LoadInputColor(iPxLrPos)); |
|||
|
|||
// Use internal auto exposure for locking logic |
|||
fRgb /= PreExposure(); |
|||
fRgb *= Exposure(); |
|||
|
|||
#if FFX_FSR3UPSCALER_OPTION_HDR_COLOR_INPUT |
|||
fRgb = Tonemap(fRgb); |
|||
#endif |
|||
|
|||
//compute luma used to lock pixels, if used elsewhere the ffxPow must be moved! |
|||
const FfxFloat32 fLockInputLuma = ffxPow(RGBToPerceivedLuma(fRgb), FfxFloat32(1.0 / 6.0)); |
|||
|
|||
return fLockInputLuma; |
|||
} |
|||
|
|||
void ReconstructAndDilate(FfxInt32x2 iPxLrPos) |
|||
{ |
|||
FfxFloat32 fDilatedDepth; |
|||
FfxInt32x2 iNearestDepthCoord; |
|||
|
|||
FindNearestDepth(iPxLrPos, RenderSize(), fDilatedDepth, iNearestDepthCoord); |
|||
|
|||
#if FFX_FSR3UPSCALER_OPTION_LOW_RESOLUTION_MOTION_VECTORS |
|||
FfxInt32x2 iSamplePos = iPxLrPos; |
|||
FfxInt32x2 iMotionVectorPos = iNearestDepthCoord; |
|||
#else |
|||
FfxInt32x2 iSamplePos = ComputeHrPosFromLrPos(iPxLrPos); |
|||
FfxInt32x2 iMotionVectorPos = ComputeHrPosFromLrPos(iNearestDepthCoord); |
|||
#endif |
|||
|
|||
FfxFloat32x2 fDilatedMotionVector = LoadInputMotionVector(iMotionVectorPos); |
|||
|
|||
StoreDilatedDepth(iPxLrPos, fDilatedDepth); |
|||
StoreDilatedMotionVector(iPxLrPos, fDilatedMotionVector); |
|||
|
|||
ReconstructPrevDepth(iPxLrPos, fDilatedDepth, fDilatedMotionVector, RenderSize()); |
|||
|
|||
FfxFloat32 fLockInputLuma = ComputeLockInputLuma(iPxLrPos); |
|||
StoreLockInputLuma(iPxLrPos, fLockInputLuma); |
|||
} |
|||
|
|||
|
|||
#endif //!defined( FFX_FSR3UPSCALER_RECONSTRUCT_DILATED_VELOCITY_AND_PREVIOUS_DEPTH_H ) |
|||
@ -1,65 +0,0 @@ |
|||
fileFormatVersion: 2 |
|||
guid: c8b3854bad30a8b40babc5a9805f294e |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
: Any |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
Exclude Editor: 1 |
|||
Exclude GameCoreScarlett: 1 |
|||
Exclude GameCoreXboxOne: 1 |
|||
Exclude Linux64: 1 |
|||
Exclude OSXUniversal: 1 |
|||
Exclude PS4: 1 |
|||
Exclude PS5: 1 |
|||
Exclude Win: 1 |
|||
Exclude Win64: 1 |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 0 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
- first: |
|||
Standalone: Linux64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: OSXUniversal |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
- first: |
|||
Standalone: Win64 |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
CPU: None |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,68 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
FFX_STATIC const FfxInt32 s_MipLevelsToUse = 3; |
|||
|
|||
struct ShadingChangeLumaInfo |
|||
{ |
|||
FfxFloat32 fSamples[s_MipLevelsToUse]; |
|||
}; |
|||
|
|||
ShadingChangeLumaInfo ComputeShadingChangeLuma(FfxInt32x2 iPxPos, FfxFloat32x2 fUv, const FfxInt32x2 iCurrentSize) |
|||
{ |
|||
ShadingChangeLumaInfo info; |
|||
|
|||
const FfxFloat32x2 fMipUv = ClampUv(fUv, ShadingChangeRenderSize(), GetSPDMipDimensions(0)); |
|||
|
|||
FFX_UNROLL |
|||
for (FfxInt32 iMipLevel = iShadingChangeMipStart; iMipLevel < s_MipLevelsToUse; iMipLevel++) { |
|||
|
|||
const FfxFloat32x2 fSample = SampleSPDMipLevel(fMipUv, iMipLevel); |
|||
|
|||
info.fSamples[iMipLevel] = abs(fSample.x * fSample.y); |
|||
} |
|||
|
|||
return info; |
|||
} |
|||
|
|||
void ShadingChange(FfxInt32x2 iPxPos) |
|||
{ |
|||
if (IsOnScreen(FfxInt32x2(iPxPos), ShadingChangeRenderSize())) { |
|||
|
|||
const FfxFloat32x2 fUv = (iPxPos + 0.5f) / ShadingChangeRenderSize(); |
|||
const FfxFloat32x2 fUvJittered = fUv + Jitter() / RenderSize(); |
|||
|
|||
const ShadingChangeLumaInfo info = ComputeShadingChangeLuma(iPxPos, fUvJittered, ShadingChangeRenderSize()); |
|||
|
|||
const FfxFloat32 fScale = 1.0f + iShadingChangeMipStart / s_MipLevelsToUse; |
|||
FfxFloat32 fShadingChange = 0.0f; |
|||
FFX_UNROLL |
|||
for (int iMipLevel = iShadingChangeMipStart; iMipLevel < s_MipLevelsToUse; iMipLevel++) |
|||
{ |
|||
if (info.fSamples[iMipLevel] > 0) { |
|||
fShadingChange = ffxMax(fShadingChange, info.fSamples[iMipLevel]) * fScale; |
|||
} |
|||
} |
|||
|
|||
StoreShadingChange(iPxPos, ffxSaturate(fShadingChange)); |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: c473fdf032dbf5142a97d6c5c40ebb12 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,297 @@ |
|||
// This file is part of the FidelityFX SDK. |
|||
// |
|||
// Copyright (C) 2024 Advanced Micro Devices, Inc. |
|||
// |
|||
// Permission is hereby granted, free of charge, to any person obtaining a copy |
|||
// of this software and associated documentation files(the "Software"), to deal |
|||
// in the Software without restriction, including without limitation the rights |
|||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell |
|||
// copies of the Software, and to permit persons to whom the Software is |
|||
// furnished to do so, subject to the following conditions : |
|||
// |
|||
// The above copyright notice and this permission notice shall be included in |
|||
// all copies or substantial portions of the Software. |
|||
// |
|||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|||
// THE SOFTWARE. |
|||
|
|||
FFX_GROUPSHARED FfxUInt32 spdCounter; |
|||
|
|||
void SpdIncreaseAtomicCounter(FfxUInt32 slice) |
|||
{ |
|||
SPD_IncreaseAtomicCounter(spdCounter); |
|||
} |
|||
|
|||
FfxUInt32 SpdGetAtomicCounter() |
|||
{ |
|||
return spdCounter; |
|||
} |
|||
|
|||
void SpdResetAtomicCounter(FfxUInt32 slice) |
|||
{ |
|||
SPD_ResetAtomicCounter(); |
|||
} |
|||
|
|||
#ifndef SPD_PACKED_ONLY |
|||
FFX_GROUPSHARED FfxFloat32 spdIntermediateR[16][16]; |
|||
FFX_GROUPSHARED FfxFloat32 spdIntermediateG[16][16]; |
|||
FFX_GROUPSHARED FfxFloat32 spdIntermediateB[16][16]; |
|||
FFX_GROUPSHARED FfxFloat32 spdIntermediateA[16][16]; |
|||
|
|||
FFX_STATIC const FfxInt32 DIFFERENCE = 0; |
|||
FFX_STATIC const FfxInt32 SIGN_SUM = 1; |
|||
FFX_STATIC const FfxInt32 MIP0_INDICATOR = 2; |
|||
|
|||
FfxFloat32x2 Sort2(FfxFloat32x2 v) |
|||
{ |
|||
return FfxFloat32x2(ffxMin(v.x, v.y), ffxMax(v.x, v.y)); |
|||
} |
|||
|
|||
struct SampleSet |
|||
{ |
|||
FfxFloat32 fSamples[SHADING_CHANGE_SET_SIZE]; |
|||
}; |
|||
|
|||
#define CompareSwap(i, j) \ |
|||
{ \ |
|||
FfxFloat32 fTmp = ffxMin(fSet.fSamples[i], fSet.fSamples[j]);\ |
|||
fSet.fSamples[j] = ffxMax(fSet.fSamples[i], fSet.fSamples[j]);\ |
|||
fSet.fSamples[i] = fTmp;\ |
|||
} |
|||
|
|||
#if SHADING_CHANGE_SET_SIZE == 5 |
|||
FFX_STATIC const FfxInt32x2 iSampleOffsets[5] = {FfxInt32x2(+0, +0), FfxInt32x2(-1, +0), FfxInt32x2(+1, +0), FfxInt32x2(+0, -1), FfxInt32x2(+0, +1)}; |
|||
|
|||
void SortSet(FFX_PARAMETER_INOUT SampleSet fSet) |
|||
{ |
|||
CompareSwap(0, 3); |
|||
CompareSwap(1, 4); |
|||
CompareSwap(0, 2); |
|||
CompareSwap(1, 3); |
|||
CompareSwap(0, 1); |
|||
CompareSwap(2, 4); |
|||
CompareSwap(1, 2); |
|||
CompareSwap(3, 4); |
|||
CompareSwap(2, 3); |
|||
} |
|||
#endif |
|||
|
|||
FfxFloat32 ComputeMinimumDifference(FfxInt32x2 iPxPos, SampleSet fSet0, SampleSet fSet1) |
|||
{ |
|||
FfxFloat32 fMinDiff = FSR3UPSCALER_FP16_MAX - 1; |
|||
FfxInt32 a = 0; |
|||
FfxInt32 b = 0; |
|||
|
|||
SortSet(fSet0); |
|||
SortSet(fSet1); |
|||
|
|||
const FfxFloat32 fMax = ffxMin(fSet0.fSamples[SHADING_CHANGE_SET_SIZE-1], fSet1.fSamples[SHADING_CHANGE_SET_SIZE-1]); |
|||
|
|||
if (fMax > FSR3UPSCALER_FP32_MIN) { |
|||
|
|||
FFX_UNROLL |
|||
for (FfxInt32 i = 0; i < SHADING_CHANGE_SET_SIZE && (fMinDiff < FSR3UPSCALER_FP16_MAX); i++) { |
|||
|
|||
FfxFloat32 fDiff = fSet0.fSamples[a] - fSet1.fSamples[b]; |
|||
|
|||
if (abs(fDiff) > FSR3UPSCALER_FP16_MIN) { |
|||
|
|||
fDiff = sign(fDiff) * (1.0f - MinDividedByMax(fSet0.fSamples[a], fSet1.fSamples[b])); |
|||
|
|||
fMinDiff = (abs(fDiff) < abs(fMinDiff)) ? fDiff : fMinDiff; |
|||
|
|||
a += FfxInt32(fSet0.fSamples[a] < fSet1.fSamples[b]); |
|||
b += FfxInt32(fSet0.fSamples[a] >= fSet1.fSamples[b]); |
|||
} |
|||
else |
|||
{ |
|||
fMinDiff = FSR3UPSCALER_FP16_MAX; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return fMinDiff * FfxFloat32(fMinDiff < (FSR3UPSCALER_FP16_MAX - 1)); |
|||
} |
|||
|
|||
SampleSet GetCurrentLumaBilinearSamples(FfxFloat32x2 fUv) |
|||
{ |
|||
const FfxFloat32x2 fUvJittered = fUv + Jitter() / RenderSize(); |
|||
const FfxInt32x2 iBasePos = FfxInt32x2(floor(fUvJittered * RenderSize())); |
|||
|
|||
SampleSet fSet; |
|||
|
|||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < SHADING_CHANGE_SET_SIZE; iSampleIndex++) { |
|||
const FfxInt32x2 iSamplePos = ClampLoad(iBasePos, iSampleOffsets[iSampleIndex], RenderSize()); |
|||
fSet.fSamples[iSampleIndex] = LoadCurrentLuma(iSamplePos) * Exposure(); |
|||
fSet.fSamples[iSampleIndex] = ffxPow(fSet.fSamples[iSampleIndex], fShadingChangeSamplePow); |
|||
fSet.fSamples[iSampleIndex] = ffxMax(fSet.fSamples[iSampleIndex], FSR3UPSCALER_EPSILON); |
|||
} |
|||
|
|||
return fSet; |
|||
} |
|||
|
|||
struct PreviousLumaBilinearSamplesData |
|||
{ |
|||
SampleSet fSet; |
|||
FfxBoolean bIsExistingSample; |
|||
}; |
|||
|
|||
PreviousLumaBilinearSamplesData GetPreviousLumaBilinearSamples(FfxFloat32x2 fUv, FfxFloat32x2 fMotionVector) |
|||
{ |
|||
PreviousLumaBilinearSamplesData data; |
|||
|
|||
const FfxFloat32x2 fUvJittered = fUv + PreviousFrameJitter() / PreviousFrameRenderSize(); |
|||
const FfxFloat32x2 fReprojectedUv = fUvJittered + fMotionVector; |
|||
|
|||
data.bIsExistingSample = IsUvInside(fReprojectedUv); |
|||
|
|||
if (data.bIsExistingSample) { |
|||
|
|||
const FfxInt32x2 iBasePos = FfxInt32x2(floor(fReprojectedUv * PreviousFrameRenderSize())); |
|||
|
|||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < SHADING_CHANGE_SET_SIZE; iSampleIndex++) { |
|||
|
|||
const FfxInt32x2 iSamplePos = ClampLoad(iBasePos, iSampleOffsets[iSampleIndex], PreviousFrameRenderSize()); |
|||
data.fSet.fSamples[iSampleIndex] = LoadPreviousLuma(iSamplePos) * DeltaPreExposure() * Exposure(); |
|||
data.fSet.fSamples[iSampleIndex] = ffxPow(data.fSet.fSamples[iSampleIndex], fShadingChangeSamplePow); |
|||
data.fSet.fSamples[iSampleIndex] = ffxMax(data.fSet.fSamples[iSampleIndex], FSR3UPSCALER_EPSILON); |
|||
} |
|||
} |
|||
|
|||
return data; |
|||
} |
|||
|
|||
FfxFloat32 ComputeDiff(FfxInt32x2 iPxPos, FfxFloat32x2 fUv, FfxFloat32x2 fMotionVector) |
|||
{ |
|||
FfxFloat32 fMinDiff = 0.0f; |
|||
|
|||
const SampleSet fCurrentSamples = GetCurrentLumaBilinearSamples(fUv); |
|||
const PreviousLumaBilinearSamplesData previousData = GetPreviousLumaBilinearSamples(fUv, fMotionVector); |
|||
|
|||
if (previousData.bIsExistingSample) { |
|||
fMinDiff = ComputeMinimumDifference(iPxPos, fCurrentSamples, previousData.fSet); |
|||
} |
|||
|
|||
return fMinDiff; |
|||
} |
|||
|
|||
FfxFloat32x4 SpdLoadSourceImage(FfxFloat32x2 iPxPos, FfxUInt32 slice) |
|||
{ |
|||
const FfxInt32x2 iPxSamplePos = ClampLoad(FfxInt32x2(iPxPos), FfxInt32x2(0, 0), FfxInt32x2(RenderSize())); |
|||
const FfxFloat32x2 fDilatedMotionVector = LoadDilatedMotionVector(iPxSamplePos); |
|||
const FfxFloat32x2 fUv = (iPxSamplePos + 0.5f) / RenderSize(); |
|||
|
|||
const FfxFloat32 fScaledAndSignedLumaDiff = ComputeDiff(iPxSamplePos, fUv, fDilatedMotionVector); |
|||
|
|||
FfxFloat32x4 fOutput = FfxFloat32x4(0.0f, 0.0f, 0.0f, 0.0f); |
|||
fOutput[DIFFERENCE] = fScaledAndSignedLumaDiff; |
|||
fOutput[SIGN_SUM] = (fScaledAndSignedLumaDiff != 0.0f) ? sign(fScaledAndSignedLumaDiff) : 0.0f; |
|||
fOutput[MIP0_INDICATOR] = 1.0f; |
|||
|
|||
return fOutput; |
|||
} |
|||
|
|||
FfxFloat32x4 SpdLoad(FfxInt32x2 tex, FfxUInt32 slice) |
|||
{ |
|||
return FfxFloat32x4(RWLoadPyramid(tex, 5), 0, 0); |
|||
} |
|||
|
|||
FfxFloat32x4 SpdReduce4(FfxFloat32x4 v0, FfxFloat32x4 v1, FfxFloat32x4 v2, FfxFloat32x4 v3) |
|||
{ |
|||
return (v0 + v1 + v2 + v3) * 0.25f; |
|||
} |
|||
|
|||
void SpdStore(FfxInt32x2 pix, FfxFloat32x4 outValue, FfxUInt32 index, FfxUInt32 slice) |
|||
{ |
|||
if (index >= iShadingChangeMipStart) |
|||
{ |
|||
StorePyramid(pix, outValue.xy, index); |
|||
} |
|||
} |
|||
|
|||
FfxFloat32x4 SpdLoadIntermediate(FfxUInt32 x, FfxUInt32 y) |
|||
{ |
|||
return FfxFloat32x4( |
|||
spdIntermediateR[x][y], |
|||
spdIntermediateG[x][y], |
|||
spdIntermediateB[x][y], |
|||
spdIntermediateA[x][y]); |
|||
} |
|||
void SpdStoreIntermediate(FfxUInt32 x, FfxUInt32 y, FfxFloat32x4 value) |
|||
{ |
|||
spdIntermediateR[x][y] = value.x; |
|||
spdIntermediateG[x][y] = value.y; |
|||
spdIntermediateB[x][y] = value.z; |
|||
spdIntermediateA[x][y] = value.w; |
|||
} |
|||
|
|||
#endif |
|||
|
|||
// define fetch and store functions Packed |
|||
#if FFX_HALF |
|||
|
|||
FFX_GROUPSHARED FfxFloat16x2 spdIntermediateRG[16][16]; |
|||
FFX_GROUPSHARED FfxFloat16x2 spdIntermediateBA[16][16]; |
|||
|
|||
FfxFloat16x4 SpdLoadSourceImageH(FfxFloat32x2 tex, FfxUInt32 slice) |
|||
{ |
|||
return FfxFloat16x4(0, 0, 0, 0); |
|||
} |
|||
|
|||
FfxFloat16x4 SpdLoadH(FfxInt32x2 p, FfxUInt32 slice) |
|||
{ |
|||
return FfxFloat16x4(0, 0, 0, 0); |
|||
} |
|||
|
|||
void SpdStoreH(FfxInt32x2 p, FfxFloat16x4 value, FfxUInt32 mip, FfxUInt32 slice) |
|||
{ |
|||
} |
|||
|
|||
FfxFloat16x4 SpdLoadIntermediateH(FfxUInt32 x, FfxUInt32 y) |
|||
{ |
|||
return FfxFloat16x4( |
|||
spdIntermediateRG[x][y].x, |
|||
spdIntermediateRG[x][y].y, |
|||
spdIntermediateBA[x][y].x, |
|||
spdIntermediateBA[x][y].y); |
|||
} |
|||
|
|||
void SpdStoreIntermediateH(FfxUInt32 x, FfxUInt32 y, FfxFloat16x4 value) |
|||
{ |
|||
spdIntermediateRG[x][y] = value.xy; |
|||
spdIntermediateBA[x][y] = value.zw; |
|||
} |
|||
|
|||
FfxFloat16x4 SpdReduce4H(FfxFloat16x4 v0, FfxFloat16x4 v1, FfxFloat16x4 v2, FfxFloat16x4 v3) |
|||
{ |
|||
return (v0 + v1 + v2 + v3) * FfxFloat16(0.25); |
|||
} |
|||
#endif |
|||
|
|||
#include "spd/ffx_spd.h" |
|||
|
|||
void ComputeShadingChangePyramid(FfxUInt32x3 WorkGroupId, FfxUInt32 LocalThreadIndex) |
|||
{ |
|||
#if FFX_HALF |
|||
SpdDownsampleH( |
|||
FfxUInt32x2(WorkGroupId.xy), |
|||
FfxUInt32(LocalThreadIndex), |
|||
FfxUInt32(MipCount()), |
|||
FfxUInt32(NumWorkGroups()), |
|||
FfxUInt32(WorkGroupId.z), |
|||
FfxUInt32x2(WorkGroupOffset())); |
|||
#else |
|||
SpdDownsample( |
|||
FfxUInt32x2(WorkGroupId.xy), |
|||
FfxUInt32(LocalThreadIndex), |
|||
FfxUInt32(MipCount()), |
|||
FfxUInt32(NumWorkGroups()), |
|||
FfxUInt32(WorkGroupId.z), |
|||
FfxUInt32x2(WorkGroupOffset())); |
|||
#endif |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 26c560eb3a1c18645ab5a44c238e39f8 |
|||
PluginImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
iconMap: {} |
|||
executionOrder: {} |
|||
defineConstraints: [] |
|||
isPreloaded: 0 |
|||
isOverridable: 0 |
|||
isExplicitlyReferenced: 0 |
|||
validateReferences: 1 |
|||
platformData: |
|||
- first: |
|||
Any: |
|||
second: |
|||
enabled: 1 |
|||
settings: {} |
|||
- first: |
|||
Editor: Editor |
|||
second: |
|||
enabled: 0 |
|||
settings: |
|||
DefaultValueInitialized: true |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue