├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── Config └── FilterPlugin.ini ├── FSR.uplugin ├── LICENSE ├── README.md ├── Resources └── Icon128.png ├── Shaders └── Private │ ├── PostProcessChromaticAberration.usf │ ├── PostProcessFFX_Common.ush │ ├── PostProcessFFX_FSR.usf │ ├── PostProcessFFX_HDRColorConversion.usf │ ├── PostProcessFFX_RCAS.usf │ ├── ffx_a.ush │ └── ffx_fsr1.ush └── Source ├── FSR ├── FSR.Build.cs ├── Private │ └── FSR.cpp └── Public │ └── FSR.h └── FSRSpatialUpscaling ├── FSRSpatialUpscaling.Build.cs ├── Private ├── FSRSpatialUpscaler.cpp ├── FSRSpatialUpscaler.h ├── FSRSpatialUpscaling.cpp ├── FSRViewExtension.cpp ├── LogFSR.h └── Subpasses │ ├── FSRData.h │ ├── FSRSubpass.h │ ├── FSRSubpassChromaticAberration.cpp │ ├── FSRSubpassChromaticAberration.h │ ├── FSRSubpassEASU.cpp │ ├── FSRSubpassEASU.h │ ├── FSRSubpassFilmGrain.cpp │ ├── FSRSubpassFilmGrain.h │ ├── FSRSubpassFirst.cpp │ ├── FSRSubpassFirst.h │ ├── FSRSubpassHDR.cpp │ ├── FSRSubpassHDR.h │ ├── FSRSubpassLast.cpp │ ├── FSRSubpassLast.h │ ├── FSRSubpassRCAS.cpp │ ├── FSRSubpassRCAS.h │ └── FSRSubpassSharedTypes.h └── Public ├── FSRSpatialUpscaling.h └── FSRViewExtension.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [lucoiso] 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Binaries 2 | DerivedDataCache 3 | Intermediate 4 | Saved 5 | enc_temp_folder 6 | .vscode 7 | .vs 8 | .idea 9 | *.VC.db 10 | *.opensdf 11 | *.opendb 12 | *.sdf 13 | *.sln 14 | *.suo 15 | *.xcodeproj 16 | *.xcworkspace 17 | *.ipch 18 | *.TMP 19 | Shaders/Private/Version.ush -------------------------------------------------------------------------------- /Config/FilterPlugin.ini: -------------------------------------------------------------------------------- 1 | [FilterPlugin] -------------------------------------------------------------------------------- /FSR.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 1, 4 | "VersionName": "1.0", 5 | "FriendlyName": "FSR 1.0", 6 | "Description": "FidelityFX Super Resolution 1.0", 7 | "Category": "Rendering", 8 | "CreatedBy": "AMD", 9 | "CreatedByURL": "https://gpuopen.com/unreal-engine/", 10 | "DocsURL": "", 11 | "MarketplaceURL": "", 12 | "SupportURL": "", 13 | "CanContainContent": false, 14 | "Installed": true, 15 | "Modules": [ 16 | { 17 | "Name": "FSR", 18 | "Type": "Runtime", 19 | "LoadingPhase": "PostEngineInit" 20 | }, 21 | { 22 | "Name": "FSRSpatialUpscaling", 23 | "Type": "Runtime", 24 | "LoadingPhase": "PostConfigInit" 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Lucas Vilas-Bôas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AMD FidelityFX Super Resolution 1.0 for Unreal Engine 5 2 | ![image](https://user-images.githubusercontent.com/77353979/165979900-9dfd1cb9-7f49-4c5e-8624-79af4d9a5104.png) 3 | 4 | ## About 5 | 6 | This plugin was built as a adapted version of the original AMD FSR 1.0 plugin for UE4 to properly work in Unreal Engine 5. 7 | 8 | **Supports:** 9 | 10 | * DirectX 12. 11 | * DirectX 11. 12 | * Vulkan. 13 | 14 | **Links:** 15 | 16 | * AMD GPU Open Documentation: https://gpuopen.com/learn/ue4-fsr/ 17 | 18 | ----------------------- 19 | 20 | # AMD FidelityFX Super Resolution 2.0 21 | AMD has released the new FSR version which supports: 22 | * DirectX 12. 23 | * Vulkan. 24 | * Unreal Engine 4.26/4.27 and Unreal Engine 5 as a plugin from the Unreal Marketplace. 25 | 26 | Check it out at [GPU Open](https://gpuopen.com/fidelityfx-superresolution-2/) and/or [Unreal Engine Marketplace](https://marketplace-website-node-launcher-prod.ol.epicgames.com/ue/marketplace/en-US/product/fidelityfx-super-resolution-2)! 27 | -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucoiso/UEFSR/002ed5e8b7e36689e6ba25500f76f50391a01dd8/Resources/Icon128.png -------------------------------------------------------------------------------- /Shaders/Private/PostProcessChromaticAberration.usf: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | 22 | // FidelityFX Super Resolution 23 | 24 | #include "/Engine/Private/Common.ush" 25 | #include "/Engine/Private/ScreenPass.ush" 26 | 27 | 28 | // ===================================================================================== 29 | // 30 | // SHADER RESOURCES 31 | // 32 | // ===================================================================================== 33 | // UE4 Color Fringe Parameters 34 | float4 ChromaticAberrationParams; 35 | float4 LensPrincipalPointOffsetScale; 36 | float4 LensPrincipalPointOffsetScaleInverse; 37 | SCREEN_PASS_TEXTURE_VIEWPORT(Color) 38 | 39 | Texture2D ColorTexture; 40 | SamplerState ColorSampler; 41 | 42 | 43 | // UE4 GrainIntensity 44 | float4 GrainRandomFull; // zw:unused 45 | float4 GrainScaleBiasJitter; // x:Scale y:Bias z:Jitter 46 | 47 | // ===================================================================================== 48 | // 49 | // FIDELITYFX SETUP 50 | // 51 | // ===================================================================================== 52 | #define A_HLSL 1 53 | #define A_GPU 1 54 | #include "ffx_a.ush" 55 | #include "ffx_fsr1.ush" 56 | #include "PostProcessFFX_Common.ush" 57 | 58 | 59 | // ===================================================================================== 60 | // 61 | // UE4 Chromatic Aberration 62 | // 63 | // ===================================================================================== 64 | float2 UVToScreenPos(float2 UV, float2 Extent) 65 | { 66 | #if NEEDTOSWITCHVERTICLEAXIS 67 | UV.y = 1.0 - UV.y; 68 | #endif 69 | 70 | return (UV * Extent - Color_ScreenPosToViewportBias) / Color_ScreenPosToViewportScale; 71 | } 72 | float2 ScreenPosToUV(float2 ScreenPos, float2 ExtentInverse) 73 | { 74 | float2 UV = (ScreenPos * Color_ScreenPosToViewportScale + Color_ScreenPosToViewportBias) * ExtentInverse; 75 | 76 | #if NEEDTOSWITCHVERTICLEAXIS 77 | UV.y = 1.0 - UV.y; 78 | #endif 79 | 80 | return UV; 81 | } 82 | 83 | #define RED 0 84 | #define GREEN 1 85 | #define BLUE 2 86 | #define ALPHA 3 87 | 88 | float SampleSceneColorSingleChannel(float2 SceneUV, uint channel) 89 | { 90 | float2 SampleCoord = SceneUV * Color_Extent + 0.5; 91 | int2 GatherCoord = int2(SampleCoord); 92 | float2 Fract = SampleCoord - GatherCoord; 93 | float2 GatherUV = GatherCoord * (1 / Color_Extent); 94 | 95 | // At this point in the pipeline, the color is not stored as linear anymore so we can't sample. 96 | // We load each channel here, convert to linear, then run the 'sampling' logic. 97 | // Gather() pixel order: 98 | // w z 99 | // x y 100 | float4 SingleChannel; 101 | if (channel == RED) { SingleChannel = ColorTexture.GatherRed(ColorSampler, GatherUV, 0); } 102 | else if (channel == GREEN) { SingleChannel = ColorTexture.GatherGreen(ColorSampler, GatherUV, 0); } 103 | else if (channel == BLUE) { SingleChannel = ColorTexture.GatherBlue(ColorSampler, GatherUV, 0); } 104 | else if (channel == ALPHA) { SingleChannel = ColorTexture.GatherAlpha(ColorSampler, GatherUV, 0); } 105 | 106 | // FSR input/output is encoded in Gamma2 107 | SingleChannel = Gamma2ToLinear(SingleChannel); 108 | #if FSR_OUTPUTDEVICE == FSR_ST2084 // PQ ----------------- 109 | SingleChannel *= HDR_MAX_NITS; 110 | #endif 111 | 112 | float TopRow = lerp(SingleChannel.w, SingleChannel.z, Fract.x); 113 | float BottomRow = lerp(SingleChannel.x, SingleChannel.y, Fract.x); 114 | float SampledLinearColor = lerp(TopRow, BottomRow, Fract.y); 115 | return SampledLinearColor; 116 | } 117 | 118 | 119 | // converts from screen [-1,1] space to the lens [-1,1] viewport space 120 | float2 ConvertScreenViewportSpaceToLensViewportSpace(float2 UV) 121 | { 122 | return LensPrincipalPointOffsetScale.xy + UV * LensPrincipalPointOffsetScale.zw; 123 | } 124 | float2 ConvertLensViewportSpaceToScreenViewportSpace(float2 UV) 125 | { 126 | // reference version 127 | //return (UV - LensPrincipalPointOffsetScale.xy)/LensPrincipalPointOffsetScale.zw; 128 | 129 | // optimized version 130 | return LensPrincipalPointOffsetScaleInverse.xy + UV * LensPrincipalPointOffsetScaleInverse.zw; 131 | } 132 | AF4 ApplyChromaticAberration(AF2 ScreenPos, AF2 UV, AU2 gxy) 133 | { 134 | float2 SceneUV = UV.xy; 135 | #if USE_GRAIN_JITTER 136 | SceneUV = lerp(UV.xy, GrainUV.xy, (1.0 - Grain * Grain) * GrainScaleBiasJitter.z); 137 | #endif 138 | 139 | float2 SceneUVJitter = float2(0.0, 0.0); 140 | #if USE_GRAIN_JITTER 141 | SceneUVJitter = SceneUV.xy - UV.xy; 142 | #endif 143 | 144 | float2 CAScale = ChromaticAberrationParams.rg; 145 | float StartOffset = ChromaticAberrationParams.z; 146 | 147 | float2 LensUV = ConvertScreenViewportSpaceToLensViewportSpace(ScreenPos); 148 | 149 | float4 CAUV; 150 | CAUV = LensUV.xyxy - sign(LensUV).xyxy * saturate(abs(LensUV) - StartOffset).xyxy * CAScale.rrgg; 151 | 152 | CAUV.xy = ConvertLensViewportSpaceToScreenViewportSpace(CAUV.xy); 153 | CAUV.zw = ConvertLensViewportSpaceToScreenViewportSpace(CAUV.zw); 154 | 155 | CAUV.xy = ScreenPosToUV(CAUV.xy, Color_ExtentInverse); 156 | CAUV.zw = ScreenPosToUV(CAUV.zw, Color_ExtentInverse); 157 | 158 | float3 LinearColor; 159 | LinearColor.r = SampleSceneColorSingleChannel(CAUV.xy + SceneUVJitter.xy, RED); 160 | LinearColor.g = SampleSceneColorSingleChannel(CAUV.zw + SceneUVJitter.xy, GREEN); 161 | LinearColor.b = SampleSceneColorSingleChannel(SceneUV, BLUE); 162 | 163 | // 164 | // UE4Grain() is post ChromAb() 165 | // 166 | #if USE_GRAIN_INTENSITY 167 | ApplyUE4Grain(LinearColor, gxy, Color_ExtentInverse); 168 | #endif 169 | 170 | 171 | // 172 | // Color Conversion 173 | // 174 | // ChromAb is the last pass in the chain so convert back to output device color space. 175 | #if FSR_OUTPUTDEVICE == FSR_scRGB // ----------------------- 176 | 177 | float3 OutColor = LinearToScRGB(LinearColor); 178 | 179 | #elif FSR_OUTPUTDEVICE == FSR_ST2084 // PQ ----------------- 180 | 181 | // LinearColor is already multiplied by HDR_MAX_NITS, no need to do it here for the conversion 182 | float3 OutColor = LinearToST2084(LinearColor); 183 | 184 | #elif FSR_OUTPUTDEVICE == FSR_LINEAR // ------------------- 185 | 186 | // FidelityFX SuperResolution / SRTM: Simple Reversible Tonemapper 187 | FsrSrtmInvF(LinearColor); // [0-1] -> [0, FP16_MAX) 188 | float3 OutColor = LinearColor; 189 | 190 | #elif FSR_OUTPUTDEVICE == FSR_SRGB // ---------------------- 191 | 192 | float3 OutColor = LinearToGamma2(LinearColor); 193 | 194 | #endif 195 | 196 | return AF4(OutColor, 1); 197 | } 198 | 199 | 200 | // ===================================================================================== 201 | // 202 | // ENTRY POINTS 203 | // 204 | // ===================================================================================== 205 | #if COMPUTE_SHADER 206 | RWTexture2D OutputTexture; 207 | [numthreads(THREADGROUP_SIZEX, THREADGROUP_SIZEY, THREADGROUP_SIZEZ)] 208 | void MainCS(uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID, uint3 Dtid : SV_DispatchThreadID) 209 | { 210 | // Do remapping of local xy in workgroup for a more PS-like swizzle pattern. 211 | AU2 gxy = ARmp8x8(LocalThreadId.x) + AU2(WorkGroupId.x << 4u, WorkGroupId.y << 4u); 212 | 213 | AF2 UV = gxy * Color_ExtentInverse; 214 | AF2 NormalizedScreenPosition = UVToScreenPos(UV, Color_Extent); 215 | OutputTexture[gxy] = ApplyChromaticAberration(NormalizedScreenPosition, UV, gxy); 216 | 217 | gxy.x += 8u; 218 | UV = gxy * Color_ExtentInverse; 219 | NormalizedScreenPosition = UVToScreenPos(UV, Color_Extent); 220 | OutputTexture[gxy] = ApplyChromaticAberration(NormalizedScreenPosition, UV, gxy); 221 | 222 | 223 | gxy.y += 8u; 224 | UV = gxy * Color_ExtentInverse; 225 | NormalizedScreenPosition = UVToScreenPos(UV, Color_Extent); 226 | OutputTexture[gxy] = ApplyChromaticAberration(NormalizedScreenPosition, UV, gxy); 227 | 228 | 229 | gxy.x -= 8u; 230 | UV = gxy * Color_ExtentInverse; 231 | NormalizedScreenPosition = UVToScreenPos(UV, Color_Extent); 232 | OutputTexture[gxy] = ApplyChromaticAberration(NormalizedScreenPosition, UV, gxy); 233 | } 234 | #else 235 | 236 | void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out float4 OutColor : SV_Target0) 237 | { 238 | AU2 gxy = AU2(SvPosition.xy); 239 | AF2 UV = UVAndScreenPos.xy; 240 | AF2 NormalizedScreenPosition = UVToScreenPos(UV, Color_Extent); 241 | OutColor = ApplyChromaticAberration(NormalizedScreenPosition, UV, gxy); 242 | } 243 | #endif // COMPUTE_SHADER -------------------------------------------------------------------------------- /Shaders/Private/PostProcessFFX_Common.ush: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | 22 | // !!! 23 | // FidelityFX Super Resolution - Common 24 | // This header should be included after ffx_a.ush 25 | // !!! 26 | 27 | // ===================================================================================== 28 | // 29 | // EOTF Conversions 30 | // 31 | // ===================================================================================== 32 | // FSR output device definitions : matching EFSR_OutputDevice enum in PostProcessFSR.cpp 33 | #define FSR_SRGB 0 34 | #define FSR_LINEAR 1 35 | #define FSR_ST2084 2 36 | #define FSR_scRGB 3 37 | 38 | #include "/Engine/Private/ACES.ush" 39 | #include "/Engine/Private/GammaCorrectionCommon.ush" 40 | 41 | float4 LinearToGamma2(float4 Color) { return sqrt(Color); } 42 | float3 LinearToGamma2(float3 Color) { return sqrt(Color); } 43 | float2 LinearToGamma2(float2 Color) { return sqrt(Color); } 44 | float LinearToGamma2(float Color) { return sqrt(Color); } 45 | 46 | float4 Gamma2ToLinear(float4 Color) { return Color * Color; } 47 | float3 Gamma2ToLinear(float3 Color) { return Color * Color; } 48 | float2 Gamma2ToLinear(float2 Color) { return Color * Color; } 49 | float Gamma2ToLinear(float Color) { return Color * Color; } 50 | 51 | #if ENABLE_FP16 52 | AH4 LinearToGamma2(AH4 Color) { return sqrt(Color); } 53 | AH3 LinearToGamma2(AH3 Color) { return sqrt(Color); } 54 | AH2 LinearToGamma2(AH2 Color) { return sqrt(Color); } 55 | AH1 LinearToGamma2(AH1 Color) { return sqrt(Color); } 56 | 57 | AH4 Gamma2ToLinear(AH4 Color) { return Color * Color; } 58 | AH3 Gamma2ToLinear(AH3 Color) { return Color * Color; } 59 | AH2 Gamma2ToLinear(AH2 Color) { return Color * Color; } 60 | AH1 Gamma2ToLinear(AH1 Color) { return Color * Color; } 61 | #endif 62 | 63 | //----------------------------------------------------------------- 64 | 65 | // only float3 ST2084ToLinear() is defined in GammaCorrectionCommon.ush 66 | float ST2084ToLinear_F(float pq) 67 | { 68 | const float m1 = 0.1593017578125; // = 2610. / 4096. * .25; 69 | const float m2 = 78.84375; // = 2523. / 4096. * 128; 70 | const float c1 = 0.8359375; // = 2392. / 4096. * 32 - 2413./4096.*32 + 1; 71 | const float c2 = 18.8515625; // = 2413. / 4096. * 32; 72 | const float c3 = 18.6875; // = 2392. / 4096. * 32; 73 | const float C = 10000.; 74 | 75 | float Np = pow(pq, 1. / m2); 76 | float L = Np - c1; 77 | L = max(0., L); 78 | L = L / (c2 - c3 * Np); 79 | L = pow(L, 1. / m1); 80 | float P = L * C; 81 | 82 | return P; 83 | } 84 | float ST2084ToGamma2(float pq) { return LinearToGamma2(ST2084ToLinear_F(pq)); } 85 | float2 ST2084ToGamma2(float2 pq) { return LinearToGamma2(float2(ST2084ToLinear_F(pq.r), ST2084ToLinear_F(pq.g))); } 86 | float3 ST2084ToGamma2(float3 pq) { return LinearToGamma2(ST2084ToLinear(pq)); } 87 | float4 ST2084ToGamma2(float4 pq) { return LinearToGamma2(float4(ST2084ToLinear(pq.rgb), ST2084ToLinear_F(pq.a))); } 88 | 89 | //----------------------------------------------------------------- 90 | 91 | // Either 1000 or 2000 depending on UE4 Tonemapper enum, 92 | // should be provided by the engine 93 | #if MAX_ODT_NITS_ENUM == 1 94 | #define HDR_MAX_ODT_NITS 2000 95 | #else 96 | #define HDR_MAX_ODT_NITS 1000 97 | #endif 98 | 99 | #define HDR_MAX_NITS 10000 100 | #define HDR_MAX_NITS_INV 0.0001f 101 | 102 | // matches white point in ST2084ToScRGB() 103 | #define HDR_WHITE_POINT 80.0f 104 | 105 | float3 Gamma2ToScRGB(float3 Color) 106 | { 107 | const float3x3 Rec2020_2_sRGB = mul(XYZ_2_sRGB_MAT, Rec2020_2_XYZ_MAT); 108 | const float MaxODTNits = HDR_MAX_ODT_NITS; 109 | const float scRGBScale = MaxODTNits / HDR_WHITE_POINT; 110 | 111 | // Gamma2 -> Linear encoding 112 | float3 LinearColor_Rec2020 = Gamma2ToLinear(Color); 113 | 114 | // Rec2020 -> sRGB primaries 115 | float3 LinearColor_sRGB = mul(Rec2020_2_sRGB, LinearColor_Rec2020); 116 | 117 | // Linear_sRGB -> scRGB 118 | return LinearColor_sRGB * scRGBScale; 119 | } 120 | 121 | float3 scRGBToGamma2(float3 Color_scRGB) 122 | { 123 | const float3x3 sRGB_2_Rec2020 = mul(XYZ_2_Rec2020_MAT, sRGB_2_XYZ_MAT); 124 | const float MaxODTNits = HDR_MAX_ODT_NITS; 125 | const float scRGBScale = MaxODTNits / HDR_WHITE_POINT; 126 | const float scRGBScaleInv = HDR_WHITE_POINT / MaxODTNits; 127 | 128 | // normalize to [0-1] 129 | Color_scRGB *= scRGBScaleInv; 130 | 131 | // convert primaries sRGB -> Rec2020 132 | float3 Color_Rec2020 = mul(sRGB_2_Rec2020, Color_scRGB); 133 | 134 | // clamp negatives 135 | Color_Rec2020 = max(Color_Rec2020, 0); 136 | 137 | // Gamma2-encode 138 | return LinearToGamma2(Color_Rec2020); 139 | } 140 | 141 | float3 LinearToScRGB(float3 LinearColor_Rec2020) 142 | { 143 | const float3x3 Rec2020_2_sRGB = mul(XYZ_2_sRGB_MAT, Rec2020_2_XYZ_MAT); 144 | const float MaxODTNits = HDR_MAX_ODT_NITS; 145 | const float scRGBScale = MaxODTNits / HDR_WHITE_POINT; 146 | 147 | // Rec2020 -> sRGB primaries 148 | float3 LinearColor_sRGB = mul(Rec2020_2_sRGB, LinearColor_Rec2020); 149 | 150 | // Linear_sRGB -> scRGB 151 | return LinearColor_sRGB * scRGBScale; 152 | } 153 | 154 | // ===================================================================================== 155 | // 156 | // UE4 Film Grain (GrainIntensity) 157 | // 158 | // ===================================================================================== 159 | // applied inline in FSR/RCAS 160 | #if USE_GRAIN_INTENSITY 161 | half GrainFromUV(float2 GrainUV) 162 | { 163 | half Grain = frac(sin(GrainUV.x + GrainUV.y * 543.31) * 493013.0); 164 | return Grain; 165 | } 166 | void ApplyUE4Grain(inout AF3 LinearColor, AU2 gxy, AF2 VPColor_ExtentInverse) 167 | { 168 | const float2 TexCoord = gxy * VPColor_ExtentInverse;; 169 | float4 GrainUV; 170 | 171 | // VS 172 | GrainUV.xy = TexCoord + VPColor_ExtentInverse * float2(-0.5, 0.5); 173 | GrainUV.zw = TexCoord + GrainRandomFull.xy; 174 | 175 | // PS 176 | half Grain = GrainFromUV(GrainUV.zw); 177 | half GrainMul = Grain * GrainScaleBiasJitter.x + GrainScaleBiasJitter.y; 178 | LinearColor *= GrainMul; 179 | } 180 | #endif // USE_GRAIN_INTENSITY -------------------------------------------------------------------------------- /Shaders/Private/PostProcessFFX_FSR.usf: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | 22 | #include "/Engine/Private/Common.ush" 23 | #include "/Engine/Private/ScreenPass.ush" 24 | 25 | 26 | // ===================================================================================== 27 | // 28 | // SHADER RESOURCES 29 | // 30 | // ===================================================================================== 31 | uint4 Const0; 32 | uint4 Const1; 33 | uint4 Const2; 34 | uint4 Const3; 35 | 36 | SamplerState samLinearClamp; 37 | 38 | 39 | // UE4 GrainIntensity 40 | float4 GrainRandomFull; // zw:unused 41 | float4 GrainScaleBiasJitter; // x:Scale y:Bias z:Jitter 42 | 43 | float2 VPColor_ExtentInverse; 44 | float2 VPColor_ViewportMin; 45 | 46 | 47 | // ===================================================================================== 48 | // 49 | // FIDELITYFX SETUP 50 | // 51 | // ===================================================================================== 52 | #define A_GPU 1 53 | #define A_HLSL 1 54 | 55 | // Note: Input is expected to be in Gamma2-encoding. 56 | // LDR: This is already the case. 57 | // HDR: A ColorConversionCS runs before FSR to provide Gamma2 input to FSR passes 58 | #if ENABLE_FP16 59 | #define A_HALF 60 | #include "ffx_a.ush" 61 | Texture2D InputTexture; 62 | RWTexture2D OutputTexture; 63 | #define FSR_EASU_H 1 64 | AH4 FsrEasuRH(AF2 p) { AH4 res = InputTexture.GatherRed (samLinearClamp, p, ASU2(0, 0)); return res; } 65 | AH4 FsrEasuGH(AF2 p) { AH4 res = InputTexture.GatherGreen(samLinearClamp, p, ASU2(0, 0)); return res; } 66 | AH4 FsrEasuBH(AF2 p) { AH4 res = InputTexture.GatherBlue (samLinearClamp, p, ASU2(0, 0)); return res; } 67 | #else 68 | #include "ffx_a.ush" 69 | Texture2D InputTexture; 70 | RWTexture2D OutputTexture; 71 | #define FSR_EASU_F 1 72 | AF4 FsrEasuRF(AF2 p) { AF4 res = InputTexture.GatherRed (samLinearClamp, p, ASU2(0, 0)); return res; } 73 | AF4 FsrEasuGF(AF2 p) { AF4 res = InputTexture.GatherGreen(samLinearClamp, p, ASU2(0, 0)); return res; } 74 | AF4 FsrEasuBF(AF2 p) { AF4 res = InputTexture.GatherBlue (samLinearClamp, p, ASU2(0, 0)); return res; } 75 | #endif 76 | 77 | // should be included after ffx_a.ush, defines FSR_OUTPUTDEVICE 78 | #include "PostProcessFFX_Common.ush" 79 | 80 | #include "ffx_fsr1.ush" 81 | 82 | // ===================================================================================== 83 | // 84 | // FIDELITYFX SUPER RESOLUTION 85 | // 86 | // ===================================================================================== 87 | #if ENABLE_FP16 88 | AH4 FidelityFXSuperResolution(AU2 gxy) 89 | #else 90 | AF4 FidelityFXSuperResolution(AU2 gxy) 91 | #endif 92 | { 93 | 94 | // 95 | // FSR / EASU() 96 | // 97 | #if ENABLE_FP16 98 | AH3 Gamma2Color = AH3(0,0,0); 99 | FsrEasuH(Gamma2Color, gxy, Const0, Const1, Const2, Const3); 100 | #else 101 | AF3 Gamma2Color = AF3(0,0,0); 102 | FsrEasuF(Gamma2Color, gxy, Const0, Const1, Const2, Const3); 103 | #endif // ENABLE_FP16 104 | 105 | AF3 OutColor = AF3(Gamma2Color); 106 | 107 | // 108 | // Grain() 109 | // 110 | // if RCAS & ChromAb are not running, we will apply Grain Intensity post-upscale here. 111 | // App should disable this path based on pass inputs on the CPU-side; 112 | #if USE_GRAIN_INTENSITY 113 | AF3 LinearColor = Gamma2ToLinear(AF3(Gamma2Color)); 114 | ApplyUE4Grain(LinearColor, gxy, VPColor_ExtentInverse); 115 | #endif // USE_GRAIN_INTENSITY 116 | 117 | 118 | // 119 | // Color Conversions 120 | // 121 | // For the HDR path, a CS converts the FSR input into Gamma2-encoding w/ Rec2020 primaries. 122 | // If this is the last pass of the FSR pass chain (RCAS=off, ChromAb=off), then convert 123 | // back to output device space. 124 | #if CONVERT_TO_OUTPUT_DEVICE 125 | #if FSR_OUTPUTDEVICE == FSR_scRGB // scRGB ------------------------------------ 126 | #if USE_GRAIN_INTENSITY 127 | OutColor = LinearToScRGB(LinearColor); 128 | #else 129 | OutColor = Gamma2ToScRGB(Gamma2Color); 130 | #endif 131 | 132 | #elif FSR_OUTPUTDEVICE == FSR_ST2084 // PQ ------------------------------------ 133 | 134 | #if USE_GRAIN_INTENSITY 135 | OutColor = LinearToST2084(LinearColor * HDR_MAX_NITS); 136 | #else 137 | AF3 LinearColor = Gamma2ToLinear(Gamma2Color); 138 | OutColor = LinearToST2084(LinearColor * HDR_MAX_NITS); 139 | #endif 140 | 141 | 142 | #elif FSR_OUTPUTDEVICE == FSR_LINEAR // Linear -------------------------------- 143 | 144 | #if USE_GRAIN_INTENSITY 145 | // FidelityFX SuperResolution / SRTM: Simple Reversible Tonemapper 146 | FsrSrtmInvF(LinearColor); // [0-1] -> [0, FP16_MAX) 147 | OutColor = LinearColor; 148 | #else 149 | AF3 LinearColor = Gamma2ToLinear(Gamma2Color); 150 | // FidelityFX SuperResolution / SRTM: Simple Reversible Tonemapper 151 | FsrSrtmInvF(LinearColor); // [0-1] -> [0, FP16_MAX) 152 | OutColor = LinearColor; 153 | #endif 154 | #endif // FSR_OUTPUTDEVICE == FSR_scRGB 155 | 156 | #else // == 'FSR_OUTPUTDEVICE == FSR_SRGB' --------------------------------------- 157 | 158 | // No HDR conversions, but we still need to convert from 159 | // Linear back to Gamma2 if we've used GrainIntensity() 160 | #if USE_GRAIN_INTENSITY 161 | OutColor = LinearToGamma2(LinearColor); 162 | #endif 163 | 164 | #endif // CONVERT_TO_OUTPUT_DEVICE 165 | 166 | 167 | #if ENABLE_FP16 168 | return AH4(OutColor, 1); 169 | #else 170 | return AF4(OutColor, 1); 171 | #endif 172 | } 173 | 174 | 175 | 176 | // ===================================================================================== 177 | // 178 | // ENTRY POINTS 179 | // 180 | // ===================================================================================== 181 | #if COMPUTE_SHADER 182 | [numthreads(THREADGROUP_SIZEX, THREADGROUP_SIZEY, THREADGROUP_SIZEZ)] 183 | void MainCS(uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID, uint3 Dtid : SV_DispatchThreadID) 184 | { 185 | // Do remapping of local xy in workgroup for a more PS-like swizzle pattern. 186 | // Threadgroup of 64 threads, each working on a cache-friendly 2x2 region (= 16x16 workgroup if 1px/thread assumed) 187 | AU2 gxy = ARmp8x8(LocalThreadId.x) + AU2(WorkGroupId.x << 4u, WorkGroupId.y << 4u); 188 | 189 | OutputTexture[gxy + VPColor_ViewportMin] = FidelityFXSuperResolution(gxy); 190 | 191 | gxy.x += 8u; 192 | OutputTexture[gxy + VPColor_ViewportMin] = FidelityFXSuperResolution(gxy); 193 | 194 | gxy.y += 8u; 195 | OutputTexture[gxy + VPColor_ViewportMin] = FidelityFXSuperResolution(gxy); 196 | 197 | gxy.x -= 8u; 198 | OutputTexture[gxy + VPColor_ViewportMin] = FidelityFXSuperResolution(gxy); 199 | } 200 | #endif // COMPUTE SHADER 201 | 202 | #if ENABLE_FP16 203 | void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out AH4 OutColor : SV_Target0) 204 | { 205 | AU2 gxy = AU2(SvPosition.xy - VPColor_ViewportMin); 206 | OutColor = FidelityFXSuperResolution(gxy); 207 | } 208 | #else 209 | void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out float4 OutColor : SV_Target0) 210 | { 211 | AU2 gxy = AU2(SvPosition.xy - VPColor_ViewportMin); 212 | OutColor = FidelityFXSuperResolution(gxy); 213 | } 214 | #endif 215 | -------------------------------------------------------------------------------- /Shaders/Private/PostProcessFFX_HDRColorConversion.usf: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | 22 | #include "Version.ush" 23 | 24 | #include "/Engine/Private/Common.ush" 25 | #include "/Engine/Private/ScreenPass.ush" 26 | 27 | // ===================================================================================== 28 | // 29 | // FIDELITYFX SETUP 30 | // 31 | // ===================================================================================== 32 | #define A_HLSL 1 33 | #define A_GPU 1 34 | #include "ffx_a.ush" 35 | #include "ffx_fsr1.ush" 36 | #include "PostProcessFFX_Common.ush" 37 | #include "/Engine/Private/BlueNoise.ush" 38 | 39 | #if COMPUTE_SHADER 40 | #ifndef FSR_OUTPUTDEVICE 41 | #error FSR_OUTPUTDEVICE must be defined 42 | #endif 43 | 44 | Texture2D InputTexture; 45 | RWTexture2D OutputTexture; 46 | 47 | AF1 DitherAmount; // Amount of dither (0 to 1} ranged. 48 | 49 | // ===================================================================================== 50 | // 51 | // COLOR CONVERSION CS 52 | // 53 | // ===================================================================================== 54 | AF4 ConvertHDRColorToGamma2(AU2 gxy) 55 | { 56 | AF4 Input = InputTexture.Load(ASU3(gxy, 0)); 57 | AF3 Color = Input.rgb; 58 | 59 | // encode in Gamma2 perceptual space for EASU/RCAS consumption 60 | 61 | #if FSR_OUTPUTDEVICE == FSR_scRGB 62 | 63 | AF3 Gamma2Color = scRGBToGamma2(Color); 64 | 65 | #elif FSR_OUTPUTDEVICE == FSR_ST2084 // PQ 66 | 67 | AF3 LinearColor = ST2084ToLinear(Color); // [0-10000] 68 | AF3 NormalizedLinearColor = LinearColor * HDR_MAX_NITS_INV; // [0-1] 69 | 70 | #if ENABLE_PQ_DITHER 71 | 72 | AU2 BlueNoiseTileCoord = gxy % BlueNoise.Dimensions.xy; // 256x256 73 | AU1 BlueNoiseSlice = 0; 74 | 75 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1 76 | AF3 PerPixelGrainTex = BlueNoiseScalar(BlueNoiseTileCoord, BlueNoiseSlice); 77 | #else 78 | AF3 PerPixelGrainTex = EvalBlueNoise(BlueNoiseTileCoord, BlueNoiseSlice); 79 | #endif 80 | 81 | // Temporally Energy Preserving Dither for 10:10:10:2_UNORM / Gamma2 storage 82 | FsrTepdC10F(NormalizedLinearColor, PerPixelGrainTex.r * DitherAmount); 83 | AF3 Gamma2Color = NormalizedLinearColor; // Tepd() already converts to Gamma2 84 | 85 | #else 86 | AF3 Gamma2Color = LinearToGamma2(NormalizedLinearColor); 87 | #endif // ENABLE_PQ_DITHER 88 | 89 | 90 | #elif FSR_OUTPUTDEVICE == FSR_LINEAR 91 | 92 | // FidelityFX SuperResolution / SRTM: Simple Reversible Tonemapper 93 | FsrSrtmF(Color); // [0, FP16_MAX) -> [0, 1] 94 | AF3 Gamma2Color = LinearToGamma2(Color); 95 | 96 | #endif // FSR_OUTPUTDEVICE 97 | 98 | return AF4(Gamma2Color, Input.a); 99 | } 100 | 101 | // ===================================================================================== 102 | // 103 | // ENTRY POINT 104 | // 105 | // ===================================================================================== 106 | [numthreads(THREADGROUP_SIZEX, THREADGROUP_SIZEY, 1)] 107 | void MainCS(uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID, uint3 Dtid : SV_DispatchThreadID) 108 | { 109 | // Do remapping of local xy in workgroup for a more PS-like swizzle pattern. 110 | AU2 gxy = ARmp8x8(LocalThreadId.x) + AU2(WorkGroupId.x << 4u, WorkGroupId.y << 4u); 111 | 112 | // process 8x8 region TopLeft (1/4) 113 | OutputTexture[gxy] = ConvertHDRColorToGamma2(gxy); 114 | 115 | // process 8x8 region TopRight (2/4) 116 | gxy.x += 8u; 117 | OutputTexture[gxy] = ConvertHDRColorToGamma2(gxy); 118 | 119 | // process 8x8 region BottomRight (3/4) 120 | gxy.y += 8u; 121 | OutputTexture[gxy] = ConvertHDRColorToGamma2(gxy); 122 | 123 | // process 8x8 region BottomLeft (4/4) 124 | gxy.x -= 8u; 125 | OutputTexture[gxy] = ConvertHDRColorToGamma2(gxy); 126 | } 127 | #endif // COMPUTE_SHADER -------------------------------------------------------------------------------- /Shaders/Private/PostProcessFFX_RCAS.usf: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | 22 | // FidelityFX Super Resolution - Robust Contrast Adaptive Sharpening 23 | 24 | #include "/Engine/Private/Common.ush" 25 | #include "/Engine/Private/ScreenPass.ush" 26 | 27 | 28 | // ===================================================================================== 29 | // 30 | // SHADER RESOURCES 31 | // 32 | // ===================================================================================== 33 | 34 | // RCAS params 35 | uint4 Const0; 36 | 37 | // UE4 GrainIntensity 38 | float4 GrainRandomFull; // zw:unused 39 | float4 GrainScaleBiasJitter; // x:Scale y:Bias z:Jitter 40 | float2 VPColor_ExtentInverse; 41 | 42 | 43 | // ===================================================================================== 44 | // 45 | // FIDELITYFX SETUP 46 | // 47 | // ===================================================================================== 48 | #define A_HLSL 1 49 | #define A_GPU 1 50 | 51 | #if USE_RCAS_DENOISE 52 | #define FSR_RCAS_DENOISE 1 53 | #endif 54 | 55 | #if ENABLE_FP16 56 | #define FSR_RCAS_H 1 57 | #define FSR_RCAS_HX2 1 58 | #define A_HALF 1 59 | #include "ffx_a.ush" 60 | 61 | Texture2D InputTexture; 62 | RWTexture2D OutputTexture; 63 | AH4 FsrRcasLoadH(ASW2 p) {return InputTexture.Load(int3(p, 0));} 64 | AH4 FsrRcasLoadHx2(ASW2 p){return InputTexture.Load(int3(p, 0));} 65 | #else 66 | #define FSR_RCAS_F 1 67 | #include "ffx_a.ush" 68 | 69 | Texture2D InputTexture; 70 | RWTexture2D OutputTexture; 71 | AF4 FsrRcasLoadF(ASU2 p){return InputTexture.Load(int3(p, 0));} 72 | #endif 73 | 74 | // should be included after ffx_a.ush, defines FSR_OUTPUTDEVICE 75 | #include "PostProcessFFX_Common.ush" 76 | 77 | 78 | // Note: Input is expected to be in Gamma2-encoding. 79 | // LDR: This is already the case. 80 | // HDR: A ColorConversionCS runs before FSR to provide Gamma2 input to FSR passes 81 | #if ENABLE_FP16 82 | void FsrRcasInputH (inout AH1 r,inout AH1 g,inout AH1 b){} // RCAS is done in perceptual space (sRGB~Gamma2) 83 | void FsrRcasInputHx2(inout AH2 r,inout AH2 g,inout AH2 b){} // Hence, no need to modify r/g/b 84 | #else 85 | void FsrRcasInputF(inout AF1 r, inout AF1 g, inout AF1 b){} 86 | #endif 87 | 88 | 89 | #include "ffx_fsr1.ush" 90 | 91 | 92 | // ===================================================================================== 93 | // 94 | // RCAS IMPLEMENTATION 95 | // 96 | // ===================================================================================== 97 | AF3 RCASPassCommon(AU2 gxy) 98 | { 99 | // 100 | // RCAS() 101 | // 102 | #if ENABLE_FP16 // half precision floating point 103 | 104 | AH3 Gamma2Color = AH3(0, 0, 0); 105 | FsrRcasH(Gamma2Color.r, Gamma2Color.g, Gamma2Color.b, gxy, Const0); 106 | 107 | #else // FP32 - full precision floating point 108 | 109 | AF3 Gamma2Color = AF3(0, 0, 0); 110 | FsrRcasF(Gamma2Color.r, Gamma2Color.g, Gamma2Color.b, gxy, Const0); 111 | 112 | #endif // ENABLE_FP16 113 | 114 | AF3 OutColor = AF3(Gamma2Color); 115 | 116 | 117 | // 118 | // Grain() 119 | // 120 | // if ChromAb is not running, we'll handle Grain here 121 | #if USE_GRAIN_INTENSITY 122 | AF3 LinearColor = Gamma2ToLinear(AF3(Gamma2Color)); 123 | ApplyUE4Grain(LinearColor, gxy, VPColor_ExtentInverse); 124 | #endif 125 | 126 | // 127 | // Color Conversions 128 | // 129 | // For the HDR path, a CS converts the FSR input into Gamma2-encoding w/ Rec2020 primaries. 130 | // If this is the last pass of the FSR pass chain (ChromAb=off), then convert 131 | // back to output device space. 132 | #if CONVERT_TO_OUTPUT_DEVICE 133 | #if FSR_OUTPUTDEVICE == FSR_scRGB // scRGB ------------------------------------ 134 | #if USE_GRAIN_INTENSITY 135 | OutColor = LinearToScRGB(LinearColor); 136 | #else 137 | OutColor = Gamma2ToScRGB(Gamma2Color); 138 | #endif 139 | 140 | #elif FSR_OUTPUTDEVICE == FSR_ST2084 // PQ ------------------------------------ 141 | 142 | #if USE_GRAIN_INTENSITY 143 | OutColor = LinearToST2084(LinearColor * HDR_MAX_NITS); 144 | #else 145 | AF3 LinearColor = Gamma2ToLinear(Gamma2Color); 146 | OutColor = LinearToST2084(LinearColor * HDR_MAX_NITS); 147 | #endif 148 | 149 | #elif FSR_OUTPUTDEVICE == FSR_LINEAR // Linear -------------------------------- 150 | 151 | #if USE_GRAIN_INTENSITY 152 | // FidelityFX SuperResolution / SRTM: Simple Reversible Tonemapper 153 | FsrSrtmInvF(LinearColor); // [0-1] -> [0, FP16_MAX) 154 | OutColor = LinearColor; 155 | #else 156 | AF3 LinearColor = Gamma2ToLinear(Gamma2Color); 157 | // FidelityFX SuperResolution / SRTM: Simple Reversible Tonemapper 158 | FsrSrtmInvF(LinearColor); // [0-1] -> [0, FP16_MAX) 159 | OutColor = LinearColor; 160 | #endif 161 | 162 | #endif // FSR_OUTPUTDEVICE == FSR_scRGB 163 | 164 | #else // == 'FSR_OUTPUTDEVICE == FSR_sRGB' --------------------------------------- 165 | 166 | // No HDR conversions, but we still need to convert from 167 | // Linear back to Gamma2 if we've used GrainIntensity() 168 | #if USE_GRAIN_INTENSITY 169 | OutColor = LinearToGamma2(LinearColor); 170 | #endif 171 | 172 | #endif // CONVERT_TO_OUTPUT_DEVICE 173 | 174 | return OutColor; 175 | } 176 | 177 | 178 | 179 | // ===================================================================================== 180 | // 181 | // ENTRY POINTS 182 | // 183 | // ===================================================================================== 184 | #if COMPUTE_SHADER 185 | [numthreads(THREADGROUP_SIZEX, THREADGROUP_SIZEY, THREADGROUP_SIZEZ)] 186 | void MainCS(uint3 LocalThreadId : SV_GroupThreadID, uint3 WorkGroupId : SV_GroupID, uint3 Dtid : SV_DispatchThreadID) 187 | { 188 | // Do remapping of local xy in workgroup for a more PS-like swizzle pattern. 189 | AU2 gxy = ARmp8x8(LocalThreadId.x) + AU2(WorkGroupId.x << 4u, WorkGroupId.y << 4u); 190 | 191 | #if ENABLE_FP16 192 | OutputTexture[gxy] = AH4(RCASPassCommon(gxy), 1); 193 | 194 | gxy.x += 8u; 195 | OutputTexture[gxy] = AH4(RCASPassCommon(gxy), 1); 196 | 197 | gxy.y += 8u; 198 | OutputTexture[gxy] = AH4(RCASPassCommon(gxy), 1); 199 | 200 | gxy.x -= 8u; 201 | OutputTexture[gxy] = AH4(RCASPassCommon(gxy), 1); 202 | #else 203 | OutputTexture[gxy] = AF4(RCASPassCommon(gxy), 1); 204 | 205 | gxy.x += 8u; 206 | OutputTexture[gxy] = AF4(RCASPassCommon(gxy), 1); 207 | 208 | gxy.y += 8u; 209 | OutputTexture[gxy] = AF4(RCASPassCommon(gxy), 1); 210 | 211 | gxy.x -= 8u; 212 | OutputTexture[gxy] = AF4(RCASPassCommon(gxy), 1); 213 | #endif 214 | } 215 | #endif // COMPUTE_SHADER 216 | 217 | #if ENABLE_FP16 218 | void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out AH4 OutColor : SV_Target0) 219 | { 220 | AU2 gxy = AU2(SvPosition.xy); 221 | OutColor = AH4(RCASPassCommon(gxy), 1); 222 | } 223 | #else 224 | void MainPS(noperspective float4 UVAndScreenPos : TEXCOORD0, float4 SvPosition : SV_POSITION, out float4 OutColor : SV_Target0) 225 | { 226 | AU2 gxy = AU2(SvPosition.xy); 227 | OutColor = AF4(RCASPassCommon(gxy), 1); 228 | } 229 | #endif -------------------------------------------------------------------------------- /Source/FSR/FSR.Build.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | 22 | using System; 23 | using System.IO; 24 | using System.Text; 25 | 26 | using UnrealBuildTool; 27 | 28 | public class FSR : ModuleRules 29 | { 30 | public FSR(ReadOnlyTargetRules Target) : base(Target) 31 | { 32 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 33 | 34 | PublicIncludePaths.AddRange( 35 | new string[] { 36 | // ... add public include paths required here ... 37 | } 38 | ); 39 | 40 | 41 | PrivateIncludePaths.AddRange( 42 | new string[] { 43 | // ... add other private include paths required here ... 44 | } 45 | ); 46 | 47 | PublicDependencyModuleNames.AddRange( 48 | new string[] 49 | { 50 | 51 | // ... add other public dependencies that you statically link with here ... 52 | } 53 | ); 54 | 55 | 56 | PrivateDependencyModuleNames.AddRange( 57 | new string[] 58 | { 59 | "Core", 60 | "CoreUObject", 61 | "Engine", 62 | "Renderer", 63 | 64 | "FSRSpatialUpscaling", 65 | // ... add private dependencies that you statically link with here ... 66 | } 67 | ); 68 | 69 | DynamicallyLoadedModuleNames.AddRange( 70 | new string[] 71 | { 72 | // ... add any modules that your module loads dynamically here ... 73 | } 74 | ); 75 | 76 | PrecompileForTargets = PrecompileTargetsType.Any; 77 | 78 | /* ------------------------------------------ CUSTOM ------------------------------------------ */ 79 | 80 | // Some things changed from 4.27 to 5+, so we r copying the version macros to a new .ush file 81 | // To allow adjust the logic of the shaders based on the unreal engine version and this copy will occur when build the plugin 82 | string VersionHeaderPath = Path.Combine(EngineDirectory, "Source", "Runtime", "Launch", "Resources", "Version.h"); 83 | string DestinationVersionFile = Path.Combine(ModuleDirectory, "..", "..", "Shaders", "Private", "Version.ush"); 84 | 85 | string[] FileLines = File.ReadAllLines(VersionHeaderPath); 86 | 87 | StringBuilder StringBuilder = new StringBuilder(); 88 | 89 | StringBuilder.AppendLine("#pragma once"); 90 | StringBuilder.AppendLine(); 91 | 92 | foreach (string Iterator in FileLines) 93 | { 94 | if (Iterator.StartsWith("#define ENGINE_")) 95 | { 96 | StringBuilder.AppendLine(Iterator); 97 | } 98 | 99 | if (Iterator.Contains("ENGINE_PATCH_VERSION")) 100 | { 101 | break; 102 | } 103 | } 104 | 105 | File.WriteAllText(DestinationVersionFile, StringBuilder.ToString()); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Source/FSR/Private/FSR.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSR.h" 22 | #include "FSRViewExtension.h" 23 | 24 | #include "CoreMinimal.h" 25 | 26 | #include "Runtime/Launch/Resources/Version.h" 27 | #include "Engine/Engine.h" 28 | #include "Engine/Texture2D.h" 29 | 30 | static_assert((ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION == 27 && ENGINE_PATCH_VERSION >= 1) 31 | || (ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 27) 32 | || ENGINE_MAJOR_VERSION >= 5, "FSR plugin requires UE4.27.1 or greater."); 33 | 34 | IMPLEMENT_MODULE(FFSRModule, FSR) 35 | 36 | // DUPLICATED FROM UNREALENGINE.CPP 37 | /** Special function that loads an engine texture and adds it to root set in cooked builds. 38 | * This is to prevent the textures from being added to GC clusters (root set objects are not clustered) 39 | * because otherwise since they're always going to be referenced by UUnrealEngine object which will 40 | * prevent the clusters from being GC'd. */ 41 | template 42 | static void LoadEngineTexture(TextureType*& InOutTexture, const TCHAR* InName) 43 | { 44 | if (!InOutTexture) 45 | { 46 | InOutTexture = LoadObject(nullptr, InName, nullptr, LOAD_None, nullptr); 47 | } 48 | if (FPlatformProperties::RequiresCookedData() && InOutTexture) 49 | { 50 | InOutTexture->AddToRoot(); 51 | } 52 | } 53 | // END OF DUPLICATED FROM UNREALENGINE.CPP 54 | 55 | void FFSRModule::StartupModule() 56 | { 57 | FSRViewExtension = FSceneViewExtensions::NewExtension(); 58 | 59 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1 60 | if (GEngine->BlueNoiseScalarTexture == nullptr) 61 | #else 62 | if (GEngine->BlueNoiseTexture == nullptr) 63 | #endif 64 | { 65 | #if ENGINE_MAJOR_VERSION >= 5 66 | GEngine->LoadBlueNoiseTexture(); 67 | #else 68 | LoadEngineTexture(GEngine->BlueNoiseTexture, *GEngine->BlueNoiseTextureName.ToString()); 69 | #endif 70 | } 71 | } 72 | 73 | void FFSRModule::ShutdownModule() 74 | { 75 | // this is a smart pointer. setting it to null is the correct way to release its memory. 76 | FSRViewExtension = nullptr; 77 | } -------------------------------------------------------------------------------- /Source/FSR/Public/FSR.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "Modules/ModuleManager.h" 24 | 25 | class FFSRViewExtension; 26 | 27 | class FFSRModule final : public IModuleInterface 28 | { 29 | public: 30 | // IModuleInterface implementation 31 | void StartupModule() override; 32 | void ShutdownModule() override; 33 | 34 | private: 35 | TSharedPtr FSRViewExtension; 36 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/FSRSpatialUpscaling.Build.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | using UnrealBuildTool; 22 | 23 | public class FSRSpatialUpscaling : ModuleRules 24 | { 25 | public FSRSpatialUpscaling(ReadOnlyTargetRules Target) : base(Target) 26 | { 27 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 28 | 29 | PublicIncludePaths.AddRange( 30 | new string[] { 31 | // ... add public include paths required here ... 32 | } 33 | ); 34 | 35 | 36 | PrivateIncludePaths.AddRange( 37 | new string[] { 38 | // ... add other private include paths required here ... 39 | EngineDirectory + "/Source/Runtime/Renderer/Private", 40 | } 41 | ); 42 | 43 | PublicDependencyModuleNames.AddRange( 44 | new string[] 45 | { 46 | 47 | // ... add other public dependencies that you statically link with here ... 48 | } 49 | ); 50 | 51 | 52 | PrivateDependencyModuleNames.AddRange( 53 | new string[] 54 | { 55 | "Core", 56 | "Engine", 57 | "Projects", 58 | "RenderCore", 59 | "Renderer", 60 | "RHI", 61 | "CoreUObject" 62 | // ... add private dependencies that you statically link with here ... 63 | } 64 | ); 65 | 66 | DynamicallyLoadedModuleNames.AddRange( 67 | new string[] 68 | { 69 | // ... add any modules that your module loads dynamically here ... 70 | } 71 | ); 72 | 73 | PrecompileForTargets = PrecompileTargetsType.Any; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/FSRSpatialUpscaler.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSpatialUpscaler.h" 22 | 23 | #include "Subpasses/FSRSubpassFirst.h" 24 | #include "Subpasses/FSRSubpassEASU.h" 25 | #include "Subpasses/FSRSubpassRCAS.h" 26 | #include "Subpasses/FSRSubpassFilmGrain.h" 27 | #include "Subpasses/FSRSubpassHDR.h" 28 | #include "Subpasses/FSRSubpassChromaticAberration.h" 29 | #include "Subpasses/FSRSubpassLast.h" 30 | 31 | #if ENGINE_MAJOR_VERSION > 5 || (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 3) 32 | #include 33 | #endif 34 | 35 | #define EXECUTE_STEP(step) \ 36 | for (FFSRSubpass* Subpass : FSRSubpasses) \ 37 | { \ 38 | Subpass->step(GraphBuilder, View, PassInputs); \ 39 | } 40 | 41 | DECLARE_GPU_STAT(FidelityFXSuperResolutionPass) 42 | 43 | FFSRSpatialUpscaler::FFSRSpatialUpscaler(EFSRMode InMode, TArray> InViewData) 44 | : Mode(InMode) 45 | , ViewData(InViewData) 46 | { 47 | if (Mode != EFSRMode::None) 48 | { 49 | // subpasses will run in the order in which they are registered 50 | 51 | // ensure this subpass always runs first 52 | RegisterSubpass(); 53 | 54 | RegisterSubpass(); 55 | RegisterSubpass(); 56 | RegisterSubpass(); 57 | RegisterSubpass(); 58 | RegisterSubpass(); 59 | 60 | // ensure this subpass always runs last. 61 | RegisterSubpass(); 62 | } 63 | } 64 | 65 | ISpatialUpscaler* FFSRSpatialUpscaler::Fork_GameThread(const class FSceneViewFamily& ViewFamily) const 66 | { 67 | // the object we return here will get deleted by UE4 when the scene view tears down, so we need to instantiate a new one every frame. 68 | return new FFSRSpatialUpscaler(Mode, ViewData); 69 | } 70 | 71 | FScreenPassTexture FFSRSpatialUpscaler::AddPasses(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) const 72 | { 73 | RDG_GPU_STAT_SCOPE(GraphBuilder, FidelityFXSuperResolutionPass); 74 | check(PassInputs.SceneColor.IsValid()); 75 | 76 | TSharedPtr Data = GetDataForView(View); 77 | for (FFSRSubpass* Subpass : FSRSubpasses) 78 | { 79 | Subpass->SetData(Data.Get()); 80 | } 81 | 82 | if (!Data->bInitialized) 83 | { 84 | EXECUTE_STEP(ParseEnvironment); 85 | EXECUTE_STEP(CreateResources); 86 | } 87 | 88 | if (Mode == EFSRMode::UpscalingOnly || Mode == EFSRMode::Combined) 89 | { 90 | EXECUTE_STEP(Upscale); 91 | } 92 | 93 | if (Mode == EFSRMode::PostProcessingOnly || Mode == EFSRMode::Combined) 94 | { 95 | EXECUTE_STEP(PostProcess); 96 | } 97 | 98 | FScreenPassTexture FinalOutput = Data->FinalOutput; 99 | return MoveTemp(FinalOutput); 100 | } 101 | 102 | TSharedPtr FFSRSpatialUpscaler::GetDataForView(const FViewInfo& View) const 103 | { 104 | for (int i = 0; i < View.Family->Views.Num(); i++) 105 | { 106 | if (View.Family->Views[i] == &View) 107 | { 108 | return ViewData[i]; 109 | } 110 | } 111 | return nullptr; 112 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/FSRSpatialUpscaler.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "Subpasses/FSRData.h" 24 | 25 | #include "PostProcess/PostProcessUpscale.h" 26 | 27 | class FFSRSubpass; 28 | 29 | enum class EFSRMode 30 | { 31 | None, 32 | UpscalingOnly, 33 | PostProcessingOnly, 34 | Combined 35 | }; 36 | 37 | class FFSRSpatialUpscaler final : public ISpatialUpscaler 38 | { 39 | public: 40 | FFSRSpatialUpscaler(EFSRMode InMode, TArray> InViewData); 41 | 42 | // ISpatialUpscaler interface 43 | const TCHAR* GetDebugName() const override { return TEXT("FFSRSpatialUpscaler"); } 44 | 45 | ISpatialUpscaler* Fork_GameThread(const class FSceneViewFamily& ViewFamily) const override; 46 | FScreenPassTexture AddPasses(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) const override; 47 | 48 | private: 49 | template 50 | T* RegisterSubpass() 51 | { 52 | T* Subpass = new T(); 53 | FSRSubpasses.Add(Subpass); 54 | return Subpass; 55 | } 56 | 57 | TSharedPtr GetDataForView(const FViewInfo& View) const; 58 | 59 | EFSRMode Mode; 60 | TArray> ViewData; 61 | TArray FSRSubpasses; 62 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/FSRSpatialUpscaling.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSpatialUpscaling.h" 22 | #include "LogFSR.h" 23 | 24 | #include "CoreMinimal.h" 25 | #include "Interfaces/IPluginManager.h" 26 | 27 | IMPLEMENT_MODULE(FFSRSpatialUpscalingModule, FSRSpatialUpscaling) 28 | 29 | #define LOCTEXT_NAMESPACE "FSR" 30 | 31 | DEFINE_LOG_CATEGORY(LogFSR); 32 | 33 | void FFSRSpatialUpscalingModule::StartupModule() 34 | { 35 | FString PluginShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin(TEXT("FSR"))->GetBaseDir(), TEXT("Shaders")); 36 | AddShaderSourceDirectoryMapping(TEXT("/Plugin/FSR"), PluginShaderDir); 37 | 38 | UE_LOG(LogFSR, Log, TEXT("FSR Spatial Upscaling Module Started")); 39 | } 40 | 41 | void FFSRSpatialUpscalingModule::ShutdownModule() 42 | { 43 | UE_LOG(LogFSR, Log, TEXT("FSR Spatial Upscaling Module Shutdown")); 44 | } 45 | 46 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/FSRViewExtension.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRViewExtension.h" 22 | #include "FSRSpatialUpscaler.h" 23 | 24 | static TAutoConsoleVariable CVarEnableFSR( 25 | TEXT("r.FidelityFX.FSR.Enabled"), 26 | 1, 27 | TEXT("Enable FidelityFX Super Resolution for Primary Upscale"), 28 | ECVF_RenderThreadSafe); 29 | 30 | inline static bool IsChromaticAberrationPassEnabled() 31 | { 32 | static TConsoleVariableData* CVarPostFSRColorFringe = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FidelityFX.FSR.Post.ExperimentalChromaticAberration")); 33 | return (CVarPostFSRColorFringe->GetValueOnAnyThread() > 0); 34 | } 35 | 36 | inline static bool IsFilmGrainPassEnabled() 37 | { 38 | static TConsoleVariableData* CVarFSRPostFSRFilmGrain = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FidelityFX.FSR.Post.FilmGrain")); 39 | return (CVarFSRPostFSRFilmGrain->GetValueOnAnyThread() > 0); 40 | } 41 | 42 | static bool IsEASUTheLastPass() 43 | { 44 | static IConsoleVariable* CVarFSRRCASEnabled = IConsoleManager::Get().FindConsoleVariable(TEXT("r.FidelityFX.FSR.RCAS.Enabled")); 45 | const bool IsRCasEnabled = (CVarFSRRCASEnabled->GetInt() > 0); 46 | return !(IsRCasEnabled || IsChromaticAberrationPassEnabled()); 47 | } 48 | 49 | void FFSRViewExtension::BeginRenderViewFamily(FSceneViewFamily& InViewFamily) 50 | { 51 | // the object(s) we assign here will get deleted by UE4 when the scene view tears down, so we need to instantiate a new one every frame. 52 | if (InViewFamily.GetFeatureLevel() >= ERHIFeatureLevel::SM5 && CVarEnableFSR.GetValueOnAnyThread() > 0) 53 | { 54 | #if WITH_EDITOR 55 | if (GIsEditor) 56 | { 57 | // if we are in the full Editor, don't let the DPI-upscaler interfere with FSR 58 | static auto CVarEnableEditorScreenPercentageOverride = IConsoleManager::Get().FindConsoleVariable(TEXT("Editor.OverrideDPIBasedEditorViewportScaling")); 59 | 60 | if (CVarEnableEditorScreenPercentageOverride != nullptr) 61 | { 62 | CVarEnableEditorScreenPercentageOverride->Set(1); 63 | } 64 | } 65 | #endif 66 | 67 | TArray> ViewData; 68 | 69 | bool IsTemporalUpscalingRequested = false; 70 | for (int i = 0; i < InViewFamily.Views.Num(); i++) 71 | { 72 | const FSceneView* InView = InViewFamily.Views[i]; 73 | if (ensure(InView)) 74 | { 75 | // if any view is using temporal upscaling, use the Combined upscaling mode. 76 | IsTemporalUpscalingRequested |= (InView->PrimaryScreenPercentageMethod == EPrimaryScreenPercentageMethod::TemporalUpscale); 77 | 78 | // TSharedPtr will clean up this allocation 79 | FFSRData* Data = new FFSRData(); 80 | 81 | #if ENGINE_MAJOR_VERSION >= 5 82 | Data->PostProcess_GrainIntensity = InView->FinalPostProcessSettings.GrainIntensity_DEPRECATED; 83 | Data->PostProcess_GrainJitter = InView->FinalPostProcessSettings.GrainJitter_DEPRECATED; 84 | #else 85 | Data->PostProcess_GrainIntensity = InView->FinalPostProcessSettings.GrainIntensity; 86 | Data->PostProcess_GrainJitter = InView->FinalPostProcessSettings.GrainJitter; 87 | #endif 88 | Data->PostProcess_SceneFringeIntensity = InView->FinalPostProcessSettings.SceneFringeIntensity; 89 | Data->PostProcess_ChromaticAberrationStartOffset = InView->FinalPostProcessSettings.ChromaticAberrationStartOffset; 90 | ViewData.Add(TSharedPtr(Data)); 91 | } 92 | } 93 | 94 | if (!IsTemporalUpscalingRequested) 95 | { 96 | InViewFamily.SetPrimarySpatialUpscalerInterface(new FFSRSpatialUpscaler(EFSRMode::UpscalingOnly, ViewData)); 97 | if (!IsEASUTheLastPass()) 98 | { 99 | InViewFamily.SetSecondarySpatialUpscalerInterface(new FFSRSpatialUpscaler(EFSRMode::PostProcessingOnly, ViewData)); 100 | } 101 | } 102 | else 103 | { 104 | InViewFamily.SetSecondarySpatialUpscalerInterface(new FFSRSpatialUpscaler(EFSRMode::Combined, ViewData)); 105 | } 106 | } 107 | } 108 | 109 | void FFSRViewExtension::PreRenderView_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneView& InView) 110 | { 111 | if (CVarEnableFSR.GetValueOnAnyThread() > 0) 112 | { 113 | if (IsFilmGrainPassEnabled()) 114 | { 115 | // setting these values to 0 completely disables the shader permutations in PostProcessTonemap. it doesn't just run it with no visible result. 116 | #if ENGINE_MAJOR_VERSION >= 5 117 | InView.FinalPostProcessSettings.GrainIntensity_DEPRECATED = 0; 118 | InView.FinalPostProcessSettings.GrainJitter_DEPRECATED = 0; 119 | #else 120 | InView.FinalPostProcessSettings.GrainIntensity = 0; 121 | InView.FinalPostProcessSettings.GrainJitter = 0; 122 | #endif 123 | } 124 | 125 | if (IsChromaticAberrationPassEnabled()) 126 | { 127 | // setting these values to 0 completely disables the shader permutations in PostProcessTonemap. it doesn't just run it with no visible result. 128 | InView.FinalPostProcessSettings.SceneFringeIntensity = 0; 129 | InView.FinalPostProcessSettings.ChromaticAberrationStartOffset = 0; 130 | } 131 | } 132 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/LogFSR.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "CoreMinimal.h" 24 | 25 | DECLARE_LOG_CATEGORY_EXTERN(LogFSR, Verbose, All); -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRData.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRSubpassSharedTypes.h" 24 | 25 | #include "PostProcess/PostProcessTonemap.h" 26 | 27 | struct FFSRData 28 | { 29 | bool bInitialized = false; 30 | 31 | bool bUSE_FP16; 32 | bool bFORCE_VSPS; 33 | bool bUSE_RCAS_DENOISE; 34 | bool bUSE_GRAIN_INTENSITY; 35 | 36 | float PostProcess_GrainIntensity; 37 | float PostProcess_GrainJitter; 38 | float PostProcess_SceneFringeIntensity; 39 | float PostProcess_ChromaticAberrationStartOffset; 40 | 41 | EFSR_OutputDevice eOUTPUT_DEVICE; 42 | EFSR_OutputDeviceMaxNits eMAX_NITS; 43 | 44 | bool bEASUEnabled; 45 | bool bRCASEnabled; 46 | bool bChromaticAberrationPassEnabled; 47 | bool bHDRColorConversionPassEnabled; 48 | bool bHDRColorConversionPassRan; 49 | 50 | bool bEASUIsTheLastPass; 51 | bool bRCASIsTheLastPass; 52 | bool bChromAbIsTheLastPass; 53 | 54 | FTonemapperOutputDeviceParameters TonemapperOutputDeviceParameters; 55 | FFSRPassParameters_Grain FilmGrainParams; 56 | 57 | FRDGTextureDesc FSROutputTextureDesc; 58 | FScreenPassTexture ColorConvertedTexture; 59 | FScreenPassTexture UpscaleTexture; 60 | FScreenPassTexture SharpenedTexture; 61 | FScreenPassTexture ColorFringeOutputTexture; 62 | 63 | FPostProcessSettings ChromaticAberrationPostProcessSettings; 64 | 65 | FScreenPassTextureViewportParameters PassOutputViewportParams; 66 | FScreenPassTextureViewport InputViewport; 67 | FScreenPassTextureViewport OutputViewport; 68 | 69 | FRDGTextureRef CurrentInputTexture; 70 | FScreenPassTexture FinalOutput; 71 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpass.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRData.h" 24 | 25 | #include "PostProcess/PostProcessUpscale.h" 26 | 27 | class FFSRSubpass 28 | { 29 | public: 30 | typedef ISpatialUpscaler::FInputs FInputs; 31 | 32 | inline void SetData(FFSRData* InData) 33 | { 34 | Data = InData; 35 | }; 36 | 37 | virtual void ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) {} 38 | virtual void CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) {} 39 | virtual void Upscale(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) {} 40 | virtual void PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) {} 41 | 42 | protected: 43 | FFSRData* Data; 44 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassChromaticAberration.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSubpassChromaticAberration.h" 22 | 23 | #if ENGINE_MAJOR_VERSION > 5 || (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2) 24 | #include 25 | #include 26 | #endif 27 | 28 | static TAutoConsoleVariable CVarFSRPostFSRChromaticAberration( 29 | TEXT("r.FidelityFX.FSR.Post.ExperimentalChromaticAberration"), 30 | #if WITH_EDITOR 31 | // Editor widgets also show chromatic aberration if chromatic aberration is applied after FSR. 32 | // So we keep it 0 for editor builds by default. 33 | 0, 34 | #else 35 | // Note: We've noticed some image issues such as jagged edges when FSR.Post.ExperimentalChromaticAberration is 1 36 | // from the earlier integrations. Even though we addressed a number of issues with this release, 37 | // we still need additional time to make sure all of the outstanding issues are properly addressed. 38 | // Until the next release, we set the default for this option as 0 to keep the feature as an experimental one. 39 | 0, 40 | #endif 41 | TEXT("[Experimental] Applies ChromaticAberration after FidelityFX Super Resolution instead of during tonemapping for sharper images: It may produce slightly different fringes than the original.") 42 | TEXT("Note: widgets will show fringes if used in editor."), 43 | ECVF_RenderThreadSafe); 44 | 45 | static FVector4 GetChromaticAberrationParameters(const FPostProcessSettings& PostProcessSettings) 46 | { 47 | // this section copy-pasted from PostProcessTonemap.cpp to re-generate Color Fringe parameters ---------------- 48 | FVector4 ChromaticAberrationParams; 49 | { 50 | // for scene color fringe 51 | // from percent to fraction 52 | float Offset = 0.0f; 53 | float StartOffset = 0.0f; 54 | float Multiplier = 1.0f; 55 | 56 | if (PostProcessSettings.ChromaticAberrationStartOffset < 1.0f - KINDA_SMALL_NUMBER) 57 | { 58 | Offset = PostProcessSettings.SceneFringeIntensity * 0.01f; 59 | StartOffset = PostProcessSettings.ChromaticAberrationStartOffset; 60 | Multiplier = 1.0f / (1.0f - StartOffset); 61 | } 62 | 63 | // Wavelength of primaries in nm 64 | const float PrimaryR = 611.3f; 65 | const float PrimaryG = 549.1f; 66 | const float PrimaryB = 464.3f; 67 | 68 | // Simple lens chromatic aberration is roughly linear in wavelength 69 | float ScaleR = 0.007f * (PrimaryR - PrimaryB); 70 | float ScaleG = 0.007f * (PrimaryG - PrimaryB); 71 | ChromaticAberrationParams = FVector4(Offset * ScaleR * Multiplier, Offset * ScaleG * Multiplier, StartOffset, 0.f); 72 | } 73 | // this section copy-pasted from PostProcessTonemap.cpp to re-generate Color Fringe parameters ---------------- 74 | return ChromaticAberrationParams; 75 | } 76 | 77 | #if ENGINE_MAJOR_VERSION >= 5 78 | static void GetLensParameters(FVector4f& LensPrincipalPointOffsetScale, FVector4f& LensPrincipalPointOffsetScaleInverse, const FViewInfo& View) 79 | #else 80 | static void GetLensParameters(FVector4& LensPrincipalPointOffsetScale, FVector4& LensPrincipalPointOffsetScaleInverse, const FViewInfo& View) 81 | #endif 82 | { 83 | // this section copy-pasted from PostProcessTonemap.cpp to re-generate Color Fringe parameters ---------------- 84 | LensPrincipalPointOffsetScale = View.LensPrincipalPointOffsetScale; 85 | 86 | // forward transformation from shader: 87 | //return LensPrincipalPointOffsetScale.xy + UV * LensPrincipalPointOffsetScale.zw; 88 | 89 | // reverse transformation from shader: 90 | //return UV*(1.0f/LensPrincipalPointOffsetScale.zw) - LensPrincipalPointOffsetScale.xy/LensPrincipalPointOffsetScale.zw; 91 | 92 | LensPrincipalPointOffsetScaleInverse.X = -View.LensPrincipalPointOffsetScale.X / View.LensPrincipalPointOffsetScale.Z; 93 | LensPrincipalPointOffsetScaleInverse.Y = -View.LensPrincipalPointOffsetScale.Y / View.LensPrincipalPointOffsetScale.W; 94 | LensPrincipalPointOffsetScaleInverse.Z = 1.0f / View.LensPrincipalPointOffsetScale.Z; 95 | LensPrincipalPointOffsetScaleInverse.W = 1.0f / View.LensPrincipalPointOffsetScale.W; 96 | // this section copy-pasted from PostProcessTonemap.cpp to re-generate Color Fringe parameters ---------------- 97 | } 98 | 99 | // 100 | // STANDALONE CHROMATIC ABERRATION / PIXEL SHADER 101 | // 102 | class FChromaticAberrationPS : public FGlobalShader 103 | { 104 | public: 105 | DECLARE_GLOBAL_SHADER(FChromaticAberrationPS); 106 | SHADER_USE_PARAMETER_STRUCT(FChromaticAberrationPS, FGlobalShader); 107 | 108 | using FPermutationDomain = TShaderPermutationDomain; 109 | 110 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 111 | SHADER_PARAMETER_RDG_TEXTURE(Texture2D, ColorTexture) 112 | SHADER_PARAMETER_SAMPLER(SamplerState, ColorSampler) 113 | 114 | #if ENGINE_MAJOR_VERSION >= 5 115 | SHADER_PARAMETER(FVector4f, ChromaticAberrationParams) 116 | SHADER_PARAMETER(FVector4f, LensPrincipalPointOffsetScale) 117 | SHADER_PARAMETER(FVector4f, LensPrincipalPointOffsetScaleInverse) 118 | #else 119 | SHADER_PARAMETER(FVector4, ChromaticAberrationParams) 120 | SHADER_PARAMETER(FVector4, LensPrincipalPointOffsetScale) 121 | SHADER_PARAMETER(FVector4, LensPrincipalPointOffsetScaleInverse) 122 | #endif 123 | 124 | SHADER_PARAMETER_STRUCT_INCLUDE(FFSRPassParameters_Grain, FilmGrain) 125 | SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Color) 126 | RENDER_TARGET_BINDING_SLOTS() 127 | END_SHADER_PARAMETER_STRUCT() 128 | 129 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 130 | { 131 | FPermutationDomain PermutationVector(Parameters.PermutationId); 132 | const EFSR_OutputDevice eFSROutputDevice = PermutationVector.Get(); 133 | 134 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 135 | } 136 | static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 137 | { 138 | } 139 | }; 140 | 141 | IMPLEMENT_GLOBAL_SHADER(FChromaticAberrationPS, "/Plugin/FSR/Private/PostProcessChromaticAberration.usf", "MainPS", SF_Pixel); 142 | 143 | // 144 | // STANDALONE CHROMATIC ABERRATION / COMPUTE SHADER 145 | // 146 | class FChromaticAberrationCS : public FGlobalShader 147 | { 148 | public: 149 | DECLARE_GLOBAL_SHADER(FChromaticAberrationCS); 150 | SHADER_USE_PARAMETER_STRUCT(FChromaticAberrationCS, FGlobalShader); 151 | 152 | using FPermutationDomain = TShaderPermutationDomain; 153 | 154 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 155 | SHADER_PARAMETER_RDG_TEXTURE(Texture2D, ColorTexture) 156 | SHADER_PARAMETER_SAMPLER(SamplerState, ColorSampler) 157 | 158 | #if ENGINE_MAJOR_VERSION >= 5 159 | SHADER_PARAMETER(FVector4f, ChromaticAberrationParams) 160 | SHADER_PARAMETER(FVector4f, LensPrincipalPointOffsetScale) 161 | SHADER_PARAMETER(FVector4f, LensPrincipalPointOffsetScaleInverse) 162 | #else 163 | SHADER_PARAMETER(FVector4, ChromaticAberrationParams) 164 | SHADER_PARAMETER(FVector4, LensPrincipalPointOffsetScale) 165 | SHADER_PARAMETER(FVector4, LensPrincipalPointOffsetScaleInverse) 166 | #endif 167 | 168 | SHADER_PARAMETER_STRUCT_INCLUDE(FFSRPassParameters_Grain, FilmGrain) 169 | SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Color) 170 | SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, OutputTexture) 171 | END_SHADER_PARAMETER_STRUCT() 172 | 173 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 174 | { 175 | FPermutationDomain PermutationVector(Parameters.PermutationId); 176 | const EFSR_OutputDevice eFSROutputDevice = PermutationVector.Get(); 177 | 178 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 179 | } 180 | static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 181 | { 182 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEX"), 64); 183 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEY"), 1); 184 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEZ"), 1); 185 | OutEnvironment.SetDefine(TEXT("COMPUTE_SHADER"), 1); 186 | } 187 | }; 188 | 189 | IMPLEMENT_GLOBAL_SHADER(FChromaticAberrationCS, "/Plugin/FSR/Private/PostProcessChromaticAberration.usf", "MainCS", SF_Compute); 190 | 191 | void FFSRSubpassChromaticAberration::ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 192 | { 193 | static TConsoleVariableData* CVarPostFSRColorFringe = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.FidelityFX.FSR.Post.ExperimentalChromaticAberration")); 194 | Data->bChromaticAberrationPassEnabled = CVarPostFSRColorFringe->GetValueOnRenderThread() > 0 && Data->PostProcess_SceneFringeIntensity > 0.01f; 195 | } 196 | 197 | void FFSRSubpassChromaticAberration::CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 198 | { 199 | if (Data->bChromaticAberrationPassEnabled) 200 | { 201 | const bool bChromAbPassOutputsToLinearRT = Data->bHDRColorConversionPassEnabled 202 | && (Data->eOUTPUT_DEVICE == EFSR_OutputDevice::scRGB || Data->eOUTPUT_DEVICE == EFSR_OutputDevice::Linear); 203 | 204 | FRDGTextureDesc ChromAbOutputTextureDesc = Data->UpscaleTexture.Texture->Desc; 205 | 206 | // if we have converted scRGB/Linear input to perceptual space before, we need to convert back to scRGB/Linear 207 | // again at the end of ChromAb, hence, override the output format of ChromAb from 10:10:10:2_UNORM to RGBA16F 208 | if (bChromAbPassOutputsToLinearRT) 209 | { 210 | ChromAbOutputTextureDesc.Format = PassInputs.SceneColor.Texture->Desc.Format; /*PF_FloatRGBA*/ 211 | } 212 | Data->ColorFringeOutputTexture = FScreenPassTexture(Data->UpscaleTexture); 213 | Data->ColorFringeOutputTexture.Texture = GraphBuilder.CreateTexture(ChromAbOutputTextureDesc, TEXT("FFX-ChromAb-Output"), ERDGTextureFlags::MultiFrame); 214 | 215 | // setup a valid PostProcessSettings object so we can invoke GetChromaticAberrationParameters and GetLensParameters against it 216 | Data->ChromaticAberrationPostProcessSettings = View.FinalPostProcessSettings; 217 | Data->ChromaticAberrationPostProcessSettings.SceneFringeIntensity = Data->PostProcess_SceneFringeIntensity; 218 | Data->ChromaticAberrationPostProcessSettings.ChromaticAberrationStartOffset = Data->PostProcess_ChromaticAberrationStartOffset; 219 | } 220 | } 221 | 222 | void FFSRSubpassChromaticAberration::PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 223 | { 224 | // 225 | // Post-upscale/sharpen Chromatic Aberration Pass 226 | // 227 | if (Data->bChromaticAberrationPassEnabled) 228 | { 229 | FRHISamplerState* BilinearClampSampler = TStaticSamplerState::GetRHI(); 230 | 231 | FScreenPassRenderTarget Output = PassInputs.OverrideOutput; 232 | if (!Output.IsValid()) 233 | { 234 | Output = FScreenPassRenderTarget(Data->ColorFringeOutputTexture.Texture, ERenderTargetLoadAction::ENoAction); 235 | } 236 | 237 | const bool bOutputSupportsUAV = (Output.Texture->Desc.Flags & TexCreate_UAV) == TexCreate_UAV; 238 | 239 | // VS-PS 240 | if (!bOutputSupportsUAV) 241 | { 242 | FChromaticAberrationPS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 243 | 244 | // set pass inputs 245 | PassParameters->ColorTexture = Data->CurrentInputTexture; 246 | PassParameters->ColorSampler = BilinearClampSampler; 247 | PassParameters->RenderTargets[0] = FRenderTargetBinding(Output.Texture, ERenderTargetLoadAction::ENoAction); 248 | PassParameters->Color = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(PassParameters->ColorTexture)); 249 | 250 | #if ENGINE_MAJOR_VERSION >= 5 251 | PassParameters->ChromaticAberrationParams = FVector4f(GetChromaticAberrationParameters(Data->ChromaticAberrationPostProcessSettings)); 252 | #else 253 | PassParameters->ChromaticAberrationParams = GetChromaticAberrationParameters(Data->ChromaticAberrationPostProcessSettings); 254 | #endif 255 | 256 | PassParameters->FilmGrain = Data->FilmGrainParams; 257 | GetLensParameters(PassParameters->LensPrincipalPointOffsetScale, PassParameters->LensPrincipalPointOffsetScaleInverse, View); 258 | 259 | // grab shaders 260 | FChromaticAberrationPS::FPermutationDomain PSPermutationVector; 261 | PSPermutationVector.Set(Data->bUSE_GRAIN_INTENSITY); 262 | PSPermutationVector.Set(Data->eOUTPUT_DEVICE); 263 | if (Data->bHDRColorConversionPassEnabled) 264 | { 265 | PSPermutationVector.Set(Data->eMAX_NITS); 266 | } 267 | 268 | TShaderMapRef PixelShader(View.ShaderMap, PSPermutationVector); 269 | 270 | AddDrawScreenPass(GraphBuilder, 271 | RDG_EVENT_NAME("Post-FidelityFX ChromaticAberration GrainIntensity=%d OutputDevice=%d (PS)" 272 | , ((Data->bUSE_GRAIN_INTENSITY) ? 1 : 0) 273 | , Data->TonemapperOutputDeviceParameters.OutputDevice 274 | ), View, Data->OutputViewport, Data->OutputViewport, 275 | PixelShader, PassParameters, 276 | EScreenPassDrawFlags::None 277 | ); 278 | } 279 | // CS 280 | else 281 | { 282 | FChromaticAberrationCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 283 | 284 | // set pass inputs 285 | PassParameters->ColorTexture = Data->CurrentInputTexture; 286 | PassParameters->ColorSampler = BilinearClampSampler; 287 | PassParameters->Color = GetScreenPassTextureViewportParameters(FScreenPassTextureViewport(PassParameters->ColorTexture)); 288 | 289 | #if ENGINE_MAJOR_VERSION >= 5 290 | PassParameters->ChromaticAberrationParams = FVector4f(GetChromaticAberrationParameters(Data->ChromaticAberrationPostProcessSettings)); 291 | #else 292 | PassParameters->ChromaticAberrationParams = GetChromaticAberrationParameters(Data->ChromaticAberrationPostProcessSettings); 293 | #endif 294 | 295 | PassParameters->OutputTexture = GraphBuilder.CreateUAV(Output.Texture); 296 | PassParameters->FilmGrain = Data->FilmGrainParams; 297 | 298 | GetLensParameters(PassParameters->LensPrincipalPointOffsetScale, PassParameters->LensPrincipalPointOffsetScaleInverse, View); 299 | 300 | FChromaticAberrationCS::FPermutationDomain CSPermutationVector; 301 | CSPermutationVector.Set(Data->bUSE_GRAIN_INTENSITY); 302 | CSPermutationVector.Set(Data->eOUTPUT_DEVICE); 303 | if (Data->bHDRColorConversionPassEnabled) 304 | { 305 | CSPermutationVector.Set(Data->eMAX_NITS); 306 | } 307 | 308 | TShaderMapRef ComputeShaderRCASPass(View.ShaderMap, CSPermutationVector); 309 | 310 | FComputeShaderUtils::AddPass( 311 | GraphBuilder, 312 | RDG_EVENT_NAME("Post-FidelityFX ChromaticAberration GrainIntensity=%d OutputDevice=%d (CS)" 313 | , ((Data->bUSE_GRAIN_INTENSITY) ? 1 : 0) 314 | , Data->TonemapperOutputDeviceParameters.OutputDevice 315 | ), 316 | ComputeShaderRCASPass, 317 | PassParameters, 318 | FComputeShaderUtils::GetGroupCount(Data->OutputViewport.Rect.Size(), 16)); 319 | } 320 | 321 | Data->FinalOutput = Output; 322 | } 323 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassChromaticAberration.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRSubpass.h" 24 | 25 | class FFSRSubpassChromaticAberration : public FFSRSubpass 26 | { 27 | public: 28 | void ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 29 | void CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 30 | void PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 31 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassEASU.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSubpassEASU.h" 22 | 23 | #if ENGINE_MAJOR_VERSION > 5 || (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2) 24 | #include 25 | #include 26 | #endif 27 | 28 | static int32 GFSR_FP16 = 1; 29 | static FAutoConsoleVariableRef CVarFSRUseFP16( 30 | TEXT("r.FidelityFX.FSR.UseFP16"), 31 | GFSR_FP16, 32 | TEXT("Enables half precision shaders for extra performance (if the device supports) without perceivable visual difference."), 33 | ECVF_RenderThreadSafe); 34 | 35 | // debug cvars ------------------------------------------------------------- 36 | static int32 GFSR_ForcePS = 0; 37 | static FAutoConsoleVariableRef CVarFSRForcePS( 38 | TEXT("r.FidelityFX.FSR.Debug.ForcePS"), 39 | GFSR_ForcePS, 40 | TEXT("Run FSR and RCAS in VS-PS"), 41 | ECVF_RenderThreadSafe); 42 | 43 | //--------------------------------------------------------------------------------------------------- 44 | // ! IMPORTANT NOTE ! 45 | // Some NVidia GPUs show image corruption issues on DX11 when FP16 path is enabled with FSR. 46 | // To ensure the correctness of the FSR pass output, we've added an additional boolean 47 | // check here to determine whether or not to use FP16 for the DX11/NVidia path. 48 | // Once this is no longer an issue, the default value of GFSR_FP16OnNvidiaDX11 can be set to 1 49 | // or this block of code can be entirely removed. 50 | static int32 GFSR_FP16OnNvidiaDX11 = 0; 51 | static FAutoConsoleVariableRef CVarFSREnableFP16OnNvidiaDX11( 52 | TEXT("r.FidelityFX.FSR.EnableFP16OnNvDX11"), 53 | GFSR_FP16OnNvidiaDX11, 54 | TEXT("Enables FP16 path for DX11/NVidia GPUs, requires 'r.FidelityFX.FSR.UseFP16 1'. Default=0 as image corruption is seen on DX11/NVidia with FP16"), 55 | ECVF_RenderThreadSafe); 56 | //--------------------------------------------------------------------------------------------------- 57 | 58 | /// 59 | /// FSR COMPUTE SHADER 60 | /// 61 | class FFSRCS : public FGlobalShader 62 | { 63 | public: 64 | DECLARE_GLOBAL_SHADER(FFSRCS); 65 | SHADER_USE_PARAMETER_STRUCT(FFSRCS, FGlobalShader); 66 | 67 | using FPermutationDomain = TShaderPermutationDomain; 68 | 69 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 70 | SHADER_PARAMETER_STRUCT_INCLUDE(FFSRPassParameters, FSR) 71 | SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, OutputTexture) 72 | END_SHADER_PARAMETER_STRUCT() 73 | 74 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 75 | { 76 | FPermutationDomain PermutationVector(Parameters.PermutationId); 77 | 78 | const EFSR_OutputDevice eFSROutputDevice = PermutationVector.Get(); 79 | if (PermutationVector.Get()) 80 | { 81 | if (Parameters.Platform != SP_PCD3D_SM5) 82 | { 83 | return false; //only compile FP16 shader permutation for Desktop PC. 84 | } 85 | } 86 | 87 | if (!PermutationVector.Get() && eFSROutputDevice != EFSR_OutputDevice::sRGB) 88 | { 89 | return false; // don't compile FSR_OUTPUTDEVICE dimensions when there's no HDR conversions (== sRGB case) 90 | } 91 | 92 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 93 | } 94 | static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 95 | { 96 | FPermutationDomain PermutationVector(Parameters.PermutationId); 97 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEX"), 64); 98 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEY"), 1); 99 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEZ"), 1); 100 | OutEnvironment.SetDefine(TEXT("COMPUTE_SHADER"), 1); 101 | } 102 | }; 103 | 104 | IMPLEMENT_GLOBAL_SHADER(FFSRCS, "/Plugin/FSR/Private/PostProcessFFX_FSR.usf", "MainCS", SF_Compute); 105 | 106 | /// 107 | /// FSR PIXEL SHADER 108 | /// 109 | class FFSRPS : public FGlobalShader 110 | { 111 | public: 112 | DECLARE_GLOBAL_SHADER(FFSRPS); 113 | SHADER_USE_PARAMETER_STRUCT(FFSRPS, FGlobalShader); 114 | 115 | using FPermutationDomain = TShaderPermutationDomain; 116 | 117 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 118 | SHADER_PARAMETER_STRUCT_INCLUDE(FFSRPassParameters, FSR) 119 | RENDER_TARGET_BINDING_SLOTS() 120 | END_SHADER_PARAMETER_STRUCT() 121 | 122 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 123 | { 124 | FPermutationDomain PermutationVector(Parameters.PermutationId); 125 | 126 | const EFSR_OutputDevice eFSROutputDevice = PermutationVector.Get(); 127 | if (PermutationVector.Get()) 128 | { 129 | if (Parameters.Platform != SP_PCD3D_SM5) 130 | { 131 | return false; //only compile FP16 shader permutation for Desktop PC. 132 | } 133 | } 134 | 135 | if (!PermutationVector.Get() && eFSROutputDevice != EFSR_OutputDevice::sRGB) 136 | { 137 | return false; // don't compile FSR_OUTPUTDEVICE dimensions when there's no HDR conversions (== sRGB case) 138 | } 139 | 140 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 141 | } 142 | static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 143 | { 144 | } 145 | }; 146 | 147 | IMPLEMENT_GLOBAL_SHADER(FFSRPS, "/Plugin/FSR/Private/PostProcessFFX_FSR.usf", "MainPS", SF_Pixel); 148 | 149 | void FFSRSubpassEASU::ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 150 | { 151 | const bool bPlatformPC_D3D = View.GetShaderPlatform() == SP_PCD3D_SM5; 152 | Data->bUSE_FP16 = (GFSR_FP16 > 0) && bPlatformPC_D3D; 153 | Data->bFORCE_VSPS = GFSR_ForcePS > 0; 154 | 155 | //--------------------------------------------------------------------------------------------------- 156 | // ! IMPORTANT NOTE ! 157 | // Some NVidia GPUs show image corruption issues on DX11 when FP16 path is enabled with FSR. 158 | // To ensure the correctness of the FSR pass output, we've added an additional boolean 159 | // check here to determine whether or not to use FP16 for the DX11/NVidia path. 160 | // Once this is no longer an issue, the default value of GFSR_FP16OnNvidiaDX11 can be set to 1 161 | // or this block of code can be entirely removed. 162 | #if PLATFORM_WINDOWS 163 | if (IsRHIDeviceNVIDIA()) 164 | { 165 | static const bool bIsDX11 = FCString::Strcmp(GDynamicRHI->GetName(), TEXT("D3D11")) == 0; 166 | if (bIsDX11) 167 | { 168 | Data->bUSE_FP16 = Data->bUSE_FP16 && (GFSR_FP16OnNvidiaDX11 > 0); 169 | } 170 | } 171 | #endif 172 | //--------------------------------------------------------------------------------------------------- 173 | } 174 | 175 | void FFSRSubpassEASU::CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 176 | { 177 | Data->UpscaleTexture = FScreenPassTexture(PassInputs.SceneColor); 178 | 179 | Data->UpscaleTexture.Texture = GraphBuilder.CreateTexture(Data->FSROutputTextureDesc, TEXT("FFX-FSR-Output"), ERDGTextureFlags::MultiFrame); 180 | Data->UpscaleTexture.ViewRect = View.UnscaledViewRect; 181 | 182 | Data->OutputViewport = FScreenPassTextureViewport(Data->UpscaleTexture); 183 | Data->InputViewport = FScreenPassTextureViewport(PassInputs.SceneColor); 184 | Data->bEASUEnabled = (Data->InputViewport.Rect != Data->OutputViewport.Rect); 185 | 186 | Data->PassOutputViewportParams = GetScreenPassTextureViewportParameters(Data->OutputViewport); 187 | } 188 | 189 | void FFSRSubpassEASU::Upscale(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 190 | { 191 | // 192 | // FidelityFX Super Resolution (FSR) Pass 193 | // 194 | if (Data->bEASUEnabled) 195 | { 196 | AU1 const0[4]; 197 | AU1 const1[4]; 198 | AU1 const2[4]; 199 | AU1 const3[4]; // Configure FSR 200 | 201 | FsrEasuConOffset(const0, const1, const2, const3, 202 | static_cast(Data->InputViewport.Rect.Width()) 203 | , static_cast(Data->InputViewport.Rect.Height()) // current frame render resolution 204 | , static_cast(PassInputs.SceneColor.Texture->Desc.Extent.X) 205 | , static_cast(PassInputs.SceneColor.Texture->Desc.Extent.Y) // input container resolution (for DRS) 206 | , static_cast(Data->OutputViewport.Rect.Width()) 207 | , static_cast(Data->OutputViewport.Rect.Height()) // upscaled-to resolution 208 | , static_cast(Data->InputViewport.Rect.Min.X) 209 | , static_cast(Data->InputViewport.Rect.Min.Y) 210 | ); 211 | 212 | const bool bUseIntermediateRT = (Data->bRCASEnabled || Data->bChromaticAberrationPassEnabled) || !PassInputs.OverrideOutput.IsValid(); 213 | 214 | FScreenPassRenderTarget Output = bUseIntermediateRT 215 | ? FScreenPassRenderTarget(Data->UpscaleTexture.Texture, Data->UpscaleTexture.ViewRect, ERenderTargetLoadAction::ENoAction) 216 | : PassInputs.OverrideOutput; 217 | 218 | const bool bOutputSupportsUAV = (Output.Texture->Desc.Flags & TexCreate_UAV) == TexCreate_UAV; 219 | 220 | // VS-PS 221 | if (!bOutputSupportsUAV || Data->bFORCE_VSPS) 222 | { 223 | FFSRPS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 224 | for (int i = 0; i < 4; i++) 225 | { 226 | PassParameters->FSR.Const0[i] = const0[i]; 227 | PassParameters->FSR.Const1[i] = const1[i]; 228 | PassParameters->FSR.Const2[i] = const2[i]; 229 | PassParameters->FSR.Const3[i] = const3[i]; 230 | } 231 | PassParameters->FSR.InputTexture = Data->CurrentInputTexture; 232 | PassParameters->FSR.samLinearClamp = TStaticSamplerState::GetRHI(); 233 | PassParameters->FSR.FilmGrain = Data->FilmGrainParams; 234 | PassParameters->FSR.VPColor_ExtentInverse = Data->PassOutputViewportParams.ExtentInverse; 235 | PassParameters->FSR.VPColor_ViewportMin = Data->PassOutputViewportParams.ViewportMin; 236 | PassParameters->RenderTargets[0] = FRenderTargetBinding(Output.Texture, ERenderTargetLoadAction::ENoAction); 237 | 238 | FFSRPS::FPermutationDomain PSPermutationVector; 239 | PSPermutationVector.Set(Data->bUSE_FP16); 240 | PSPermutationVector.Set(Data->bUSE_GRAIN_INTENSITY && Data->bEASUIsTheLastPass); 241 | PSPermutationVector.Set(Data->bHDRColorConversionPassEnabled && Data->bEASUIsTheLastPass); 242 | if (PSPermutationVector.Get()) 243 | { 244 | PSPermutationVector.Set(Data->eOUTPUT_DEVICE); 245 | PSPermutationVector.Set(Data->eMAX_NITS); 246 | } 247 | 248 | const bool bFSRWithGrain = PSPermutationVector.Get(); 249 | TShaderMapRef PixelShader(View.ShaderMap, PSPermutationVector); 250 | 251 | AddDrawScreenPass(GraphBuilder, 252 | RDG_EVENT_NAME("FidelityFX-FSR/Upscale %dx%d -> %dx%d GrainIntensity=%d (PS)" 253 | , Data->InputViewport.Rect.Width(), Data->InputViewport.Rect.Height() 254 | , Data->OutputViewport.Rect.Width(), Data->OutputViewport.Rect.Height() 255 | , (bFSRWithGrain ? 1 : 0)), 256 | View, Data->OutputViewport, Data->InputViewport, 257 | PixelShader, PassParameters, 258 | EScreenPassDrawFlags::None 259 | ); 260 | } 261 | // CS 262 | else 263 | { 264 | FFSRCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 265 | 266 | for (int i = 0; i < 4; i++) 267 | { 268 | PassParameters->FSR.Const0[i] = const0[i]; 269 | PassParameters->FSR.Const1[i] = const1[i]; 270 | PassParameters->FSR.Const2[i] = const2[i]; 271 | PassParameters->FSR.Const3[i] = const3[i]; 272 | } 273 | PassParameters->FSR.InputTexture = Data->CurrentInputTexture; 274 | PassParameters->FSR.samLinearClamp = TStaticSamplerState::GetRHI(); 275 | PassParameters->FSR.FilmGrain = Data->FilmGrainParams; 276 | PassParameters->FSR.VPColor_ExtentInverse = Data->PassOutputViewportParams.ExtentInverse; 277 | PassParameters->FSR.VPColor_ViewportMin = Data->PassOutputViewportParams.ViewportMin; 278 | PassParameters->OutputTexture = GraphBuilder.CreateUAV(Data->UpscaleTexture.Texture); 279 | 280 | FFSRCS::FPermutationDomain CSPermutationVector; 281 | CSPermutationVector.Set(Data->bUSE_FP16); 282 | CSPermutationVector.Set(Data->bUSE_GRAIN_INTENSITY && Data->bEASUIsTheLastPass); 283 | CSPermutationVector.Set(Data->bHDRColorConversionPassEnabled && Data->bEASUIsTheLastPass); 284 | if (CSPermutationVector.Get()) 285 | { 286 | CSPermutationVector.Set(Data->eOUTPUT_DEVICE); 287 | CSPermutationVector.Set(Data->eMAX_NITS); 288 | } 289 | 290 | const bool bFSRWithGrain = CSPermutationVector.Get(); 291 | 292 | TShaderMapRef ComputeShaderFSR(View.ShaderMap, CSPermutationVector); 293 | FComputeShaderUtils::AddPass( 294 | GraphBuilder, 295 | RDG_EVENT_NAME("FidelityFX-FSR/Upscale %dx%d -> %dx%d GrainIntensity=%d (CS)" 296 | , Data->InputViewport.Rect.Width(), Data->InputViewport.Rect.Height() 297 | , Data->OutputViewport.Rect.Width(), Data->OutputViewport.Rect.Height() 298 | , (bFSRWithGrain ? 1 : 0)), 299 | ComputeShaderFSR, 300 | PassParameters, 301 | FComputeShaderUtils::GetGroupCount(Data->OutputViewport.Rect.Size(), 16)); 302 | 303 | } 304 | Data->FinalOutput = Output; // RCAS will override this if enabled 305 | Data->CurrentInputTexture = Output.Texture; 306 | } 307 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassEASU.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRSubpass.h" 24 | 25 | class FFSRSubpassEASU : public FFSRSubpass 26 | { 27 | public: 28 | void ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 29 | void CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 30 | void Upscale(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 31 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassFilmGrain.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSubpassFilmGrain.h" 22 | 23 | #if ENGINE_MAJOR_VERSION > 5 || (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 3) 24 | #include 25 | #endif 26 | 27 | static TAutoConsoleVariable CVarFSRPostFSRFilmGrain( 28 | TEXT("r.FidelityFX.FSR.Post.FilmGrain"), 29 | 1, 30 | TEXT("Applies FilmGrain after FidelityFX Super Resolution on the upscaled image instead of during tonemapping (in low-res) to avoid upscaled film grain effect for a more realistic look"), 31 | ECVF_RenderThreadSafe); 32 | 33 | static FFSRPassParameters_Grain GetFilmGrainParameters(const FViewInfo& View, const float GrainIntensity, const float GrainJitter) 34 | { 35 | // this section copy-pasted from PostProcessTonemap.cpp (with modifications) to re-generate Grain Intensity parameters ---------------- 36 | #if ENGINE_MAJOR_VERSION >= 5 37 | FVector3f GrainRandomFullValue; 38 | #else 39 | FVector GrainRandomFullValue; 40 | #endif 41 | { 42 | uint8 FrameIndexMod8 = 0; 43 | if (View.Family) 44 | { 45 | FrameIndexMod8 = View.Family->FrameNumber & 0x7; 46 | } 47 | 48 | GrainRandomFromFrame(&GrainRandomFullValue, FrameIndexMod8); 49 | } 50 | 51 | FVector GrainScaleBiasJitter; 52 | auto fnGrainPostSettings = [](FVector* RESTRICT const Constant, const FPostProcessSettings* RESTRICT const Settings, const float GrainIntensity, const float GrainJitter) 53 | { 54 | Constant->X = GrainIntensity; 55 | Constant->Y = 1.0f + (-0.5f * GrainIntensity); 56 | Constant->Z = GrainJitter; 57 | }; 58 | fnGrainPostSettings(&GrainScaleBiasJitter, &View.FinalPostProcessSettings, GrainIntensity, GrainJitter); 59 | // this section copy-pasted from PostProcessTonemap.cpp (with modifications) to re-generate Grain Intensity parameters ---------------- 60 | 61 | FFSRPassParameters_Grain Parameters; 62 | 63 | #if ENGINE_MAJOR_VERSION >= 5 64 | Parameters.GrainRandomFull = FVector4f(GrainRandomFullValue.X, GrainRandomFullValue.Y, 0, 0); 65 | Parameters.GrainScaleBiasJitter = FVector4f(GrainScaleBiasJitter.X, GrainScaleBiasJitter.Y, GrainScaleBiasJitter.Z, 0); 66 | #else 67 | Parameters.GrainRandomFull = FVector4(GrainRandomFullValue.X, GrainRandomFullValue.Y, 0, 0); 68 | Parameters.GrainScaleBiasJitter = FVector4(GrainScaleBiasJitter, 0); 69 | #endif 70 | 71 | return Parameters; 72 | } 73 | 74 | void FFSRSubpassFilmGrain::ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 75 | { 76 | Data->bUSE_GRAIN_INTENSITY = CVarFSRPostFSRFilmGrain->GetInt() > 0 && Data->PostProcess_GrainIntensity > 0.0f; 77 | Data->FilmGrainParams = GetFilmGrainParameters(View, Data->PostProcess_GrainIntensity, Data->PostProcess_GrainJitter); 78 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassFilmGrain.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRSubpass.h" 24 | 25 | class FFSRSubpassFilmGrain : public FFSRSubpass 26 | { 27 | public: 28 | void ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 29 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassFirst.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSubpassFirst.h" 22 | 23 | #if ENGINE_MAJOR_VERSION > 5 || (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2) 24 | #include 25 | #endif 26 | 27 | void FFSRSubpassFirst::CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 28 | { 29 | Data->FSROutputTextureDesc = PassInputs.SceneColor.Texture->Desc; 30 | Data->FSROutputTextureDesc.Reset(); 31 | Data->FSROutputTextureDesc.Extent = View.UnscaledViewRect.Max; 32 | Data->FSROutputTextureDesc.ClearValue = FClearValueBinding::Black; 33 | Data->FSROutputTextureDesc.Flags = TexCreate_ShaderResource | TexCreate_UAV | TexCreate_RenderTargetable; 34 | } 35 | 36 | void FFSRSubpassFirst::Upscale(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 37 | { 38 | Data->FinalOutput = PassInputs.SceneColor; // later subpasses will override this, if enabled 39 | } 40 | 41 | void FFSRSubpassFirst::PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 42 | { 43 | // if we never ran the Upscale pass, make sure we get initialized before running the PostProcess pass 44 | if (!Data->FinalOutput.IsValid()) 45 | { 46 | check(PassInputs.OverrideOutput.IsValid()); 47 | Data->FinalOutput = PassInputs.OverrideOutput; // later subpasses will override this, if enabled 48 | } 49 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassFirst.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRSubpass.h" 24 | 25 | class FFSRSubpassFirst : public FFSRSubpass 26 | { 27 | public: 28 | void CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 29 | void Upscale(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 30 | void PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 31 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassHDR.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSubpassHDR.h" 22 | #include "BlueNoise.h" 23 | 24 | #if ENGINE_MAJOR_VERSION > 5 || (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2) 25 | #include 26 | #include 27 | #endif 28 | 29 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1 30 | #include 31 | #endif 32 | 33 | static float GFSR_HDR_PQDither = 1.0f; 34 | static FAutoConsoleVariableRef CVarFSR_HDR_PQDither( 35 | TEXT("r.FidelityFX.FSR.HDR.PQDitherAmount"), 36 | GFSR_HDR_PQDither, 37 | TEXT("[HDR-Only] DitherAmount to apply for PQ->Gamma2 conversion to eliminate color banding, when the output device is ST2084/PQ."), 38 | ECVF_RenderThreadSafe); 39 | 40 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1 41 | static EFSR_OutputDevice GetFSROutputDevice(EDisplayOutputFormat UE5DisplayOutputFormat) 42 | { 43 | EFSR_OutputDevice ColorSpace = EFSR_OutputDevice::MAX; 44 | 45 | switch (UE5DisplayOutputFormat) 46 | { 47 | case EDisplayOutputFormat::SDR_sRGB: 48 | case EDisplayOutputFormat::SDR_Rec709: 49 | case EDisplayOutputFormat::SDR_ExplicitGammaMapping: 50 | ColorSpace = EFSR_OutputDevice::sRGB; 51 | break; 52 | case EDisplayOutputFormat::HDR_ACES_1000nit_ST2084: 53 | case EDisplayOutputFormat::HDR_ACES_2000nit_ST2084: 54 | ColorSpace = EFSR_OutputDevice::PQ; 55 | break; 56 | case EDisplayOutputFormat::HDR_ACES_1000nit_ScRGB: 57 | case EDisplayOutputFormat::HDR_ACES_2000nit_ScRGB: 58 | ColorSpace = EFSR_OutputDevice::scRGB; 59 | break; 60 | case EDisplayOutputFormat::HDR_LinearEXR: 61 | case EDisplayOutputFormat::HDR_LinearNoToneCurve: 62 | case EDisplayOutputFormat::HDR_LinearWithToneCurve: 63 | ColorSpace = EFSR_OutputDevice::Linear; 64 | break; 65 | } 66 | 67 | return ColorSpace; 68 | } 69 | 70 | static EFSR_OutputDeviceMaxNits GetOutputDeviceMaxNits(EDisplayOutputFormat eFormat) // only needed for HDR color conversions 71 | { 72 | // this will select shader variants so MAX cannot be used. 73 | EFSR_OutputDeviceMaxNits eMaxNits = EFSR_OutputDeviceMaxNits::EFSR_1000Nits; // Assume 1000 for the default case. 74 | 75 | switch (eFormat) 76 | { 77 | case EDisplayOutputFormat::HDR_ACES_1000nit_ST2084: 78 | case EDisplayOutputFormat::HDR_ACES_1000nit_ScRGB: 79 | eMaxNits = EFSR_OutputDeviceMaxNits::EFSR_1000Nits; 80 | break; 81 | case EDisplayOutputFormat::HDR_ACES_2000nit_ST2084: 82 | case EDisplayOutputFormat::HDR_ACES_2000nit_ScRGB: 83 | eMaxNits = EFSR_OutputDeviceMaxNits::EFSR_2000Nits; 84 | break; 85 | 86 | case EDisplayOutputFormat::SDR_sRGB: 87 | case EDisplayOutputFormat::SDR_Rec709: 88 | case EDisplayOutputFormat::SDR_ExplicitGammaMapping: 89 | case EDisplayOutputFormat::HDR_LinearEXR: 90 | case EDisplayOutputFormat::HDR_LinearNoToneCurve: 91 | case EDisplayOutputFormat::HDR_LinearWithToneCurve: 92 | default: 93 | // noop 94 | break; 95 | } 96 | return eMaxNits; 97 | } 98 | #else 99 | static EFSR_OutputDevice GetFSROutputDevice(ETonemapperOutputDevice UE4TonemapperOutputDevice) 100 | { 101 | EFSR_OutputDevice ColorSpace = EFSR_OutputDevice::MAX; 102 | 103 | switch (UE4TonemapperOutputDevice) 104 | { 105 | case ETonemapperOutputDevice::sRGB: 106 | case ETonemapperOutputDevice::Rec709: 107 | case ETonemapperOutputDevice::ExplicitGammaMapping: 108 | ColorSpace = EFSR_OutputDevice::sRGB; 109 | break; 110 | case ETonemapperOutputDevice::ACES1000nitST2084: 111 | case ETonemapperOutputDevice::ACES2000nitST2084: 112 | ColorSpace = EFSR_OutputDevice::PQ; 113 | break; 114 | case ETonemapperOutputDevice::ACES1000nitScRGB: 115 | case ETonemapperOutputDevice::ACES2000nitScRGB: 116 | ColorSpace = EFSR_OutputDevice::scRGB; 117 | break; 118 | case ETonemapperOutputDevice::LinearEXR: 119 | case ETonemapperOutputDevice::LinearNoToneCurve: 120 | case ETonemapperOutputDevice::LinearWithToneCurve: 121 | ColorSpace = EFSR_OutputDevice::Linear; 122 | break; 123 | } 124 | 125 | return ColorSpace; 126 | } 127 | 128 | static EFSR_OutputDeviceMaxNits GetOutputDeviceMaxNits(ETonemapperOutputDevice eDevice) // only needed for HDR color conversions 129 | { 130 | // this will select shader variants so MAX cannot be used. 131 | EFSR_OutputDeviceMaxNits eMaxNits = EFSR_OutputDeviceMaxNits::EFSR_1000Nits; // Assume 1000 for the default case. 132 | 133 | switch (eDevice) 134 | { 135 | case ETonemapperOutputDevice::ACES1000nitST2084: 136 | case ETonemapperOutputDevice::ACES1000nitScRGB: 137 | eMaxNits = EFSR_OutputDeviceMaxNits::EFSR_1000Nits; 138 | break; 139 | case ETonemapperOutputDevice::ACES2000nitST2084: 140 | case ETonemapperOutputDevice::ACES2000nitScRGB: 141 | eMaxNits = EFSR_OutputDeviceMaxNits::EFSR_2000Nits; 142 | break; 143 | 144 | case ETonemapperOutputDevice::sRGB: 145 | case ETonemapperOutputDevice::Rec709: 146 | case ETonemapperOutputDevice::ExplicitGammaMapping: 147 | case ETonemapperOutputDevice::LinearEXR: 148 | case ETonemapperOutputDevice::LinearNoToneCurve: 149 | case ETonemapperOutputDevice::LinearWithToneCurve: 150 | default: 151 | // noop 152 | break; 153 | } 154 | return eMaxNits; 155 | } 156 | #endif 157 | 158 | // 159 | // COLOR CONVERSION COMPUTE SHADER 160 | // 161 | class FColorConversionCS : public FGlobalShader 162 | { 163 | DECLARE_GLOBAL_SHADER(FColorConversionCS); 164 | SHADER_USE_PARAMETER_STRUCT(FColorConversionCS, FGlobalShader); 165 | 166 | using FPermutationDomain = TShaderPermutationDomain; 167 | 168 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 169 | SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture) 170 | SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, OutputTexture) 171 | SHADER_PARAMETER_STRUCT_REF(FBlueNoise, BlueNoise) 172 | SHADER_PARAMETER(float, DitherAmount) 173 | END_SHADER_PARAMETER_STRUCT() 174 | 175 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 176 | { 177 | FPermutationDomain PermutationVector(Parameters.PermutationId); 178 | 179 | if (PermutationVector.Get() == EFSR_OutputDevice::sRGB) 180 | { 181 | return false; // no color conversion is needed for sRGB 182 | } 183 | 184 | if (PermutationVector.Get() != EFSR_OutputDevice::PQ) 185 | { 186 | if (PermutationVector.Get()) 187 | { 188 | return false; // do not compile PQ variants for non-PQ output devices 189 | } 190 | } 191 | 192 | 193 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 194 | } 195 | static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 196 | { 197 | FPermutationDomain PermutationVector(Parameters.PermutationId); 198 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEX"), 64); 199 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEY"), 1); 200 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEZ"), 1); 201 | OutEnvironment.SetDefine(TEXT("COMPUTE_SHADER"), 1); 202 | } 203 | }; 204 | IMPLEMENT_GLOBAL_SHADER(FColorConversionCS, "/Plugin/FSR/Private/PostProcessFFX_HDRColorConversion.usf", "MainCS", SF_Compute); 205 | 206 | void FFSRSubpassHDR::ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 207 | { 208 | Data->TonemapperOutputDeviceParameters = GetTonemapperOutputDeviceParameters(*View.Family); 209 | 210 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1 211 | const EDisplayOutputFormat eTonemapperOutputDevice = (EDisplayOutputFormat)Data->TonemapperOutputDeviceParameters.OutputDevice; 212 | #else 213 | const ETonemapperOutputDevice eTonemapperOutputDevice = (ETonemapperOutputDevice)Data->TonemapperOutputDeviceParameters.OutputDevice; 214 | #endif 215 | 216 | Data->eOUTPUT_DEVICE = GetFSROutputDevice(eTonemapperOutputDevice); 217 | Data->eMAX_NITS = GetOutputDeviceMaxNits(eTonemapperOutputDevice); 218 | 219 | Data->bHDRColorConversionPassEnabled = Data->eOUTPUT_DEVICE != EFSR_OutputDevice::sRGB; 220 | } 221 | 222 | void FFSRSubpassHDR::CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 223 | { 224 | Data->ColorConvertedTexture = FScreenPassTexture(PassInputs.SceneColor); 225 | 226 | if (Data->bHDRColorConversionPassEnabled) 227 | { 228 | // FSR expects to work in a perceptual space, preferrably Gamma2. 229 | // For the HDR outputs, we will need to convert to Gamma2 prior to FSR. 230 | // 231 | // scRGB & Linear 232 | // -------------- 233 | // Since we will convert scRGB into a perceptual space and store in 10:10:10:2_UNORM format 234 | // a Gamma2 encoded color w/ Rec2020 primaries, override the FSR output texture desc format here. 235 | // Although, override it only when FSR upscaling is not the last pass, becase RCAS or ChromAb may still 236 | // utilize the sRGB / 10:10:10:2 input for faster loads, and convert back to scRGB at the end of their invocation. 237 | // Otherwise, FSR pass will load 10:10:10:2 input, and convert back to scRGB before storing out. 238 | // 239 | // PQ 240 | // -------------- 241 | // The RT format will already be 10:10:10:2, we just need to change the encoding during color conversion. 242 | if (!Data->bEASUIsTheLastPass) 243 | { 244 | Data->FSROutputTextureDesc.Format = PF_A2B10G10R10; 245 | } 246 | 247 | // prepare color conversion resources 248 | FRDGTextureDesc ColorConversionTextureDesc = PassInputs.SceneColor.Texture->Desc; 249 | ColorConversionTextureDesc.Format = PF_A2B10G10R10; 250 | ColorConversionTextureDesc.Flags = TexCreate_ShaderResource | TexCreate_UAV | TexCreate_RenderTargetable; 251 | Data->ColorConvertedTexture.Texture = GraphBuilder.CreateTexture(ColorConversionTextureDesc, TEXT("FFX-ColorConversion-Output"), ERDGTextureFlags::MultiFrame); 252 | Data->ColorConvertedTexture.ViewRect = PassInputs.SceneColor.ViewRect; 253 | 254 | Data->bHDRColorConversionPassRan = false; 255 | } 256 | } 257 | 258 | void FFSRSubpassHDR::Upscale(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 259 | { 260 | // 261 | // [HDR-only] Color Conversion Pass 262 | // 263 | if (Data->bHDRColorConversionPassEnabled) 264 | { 265 | // -------------------------------------------------------------------------------------- 266 | // HDR/scRGB 267 | // --------------------------------------------------------------------------------------- 268 | // In scRGB, there could be input ranging between [-0.5, 12.5]. 269 | // scRGB uses sRGB primaries and is a linear color space, however, 270 | // FSR expects perceptual space (preferrably Gamma2/sRGB) and values in [0-1] range. 271 | // 272 | // Here, we will convert the scRGB input into a Gamma2 encoded perceptual space. 273 | // During the conversion, we will change the sRGB primaries into Rec2020 primaries 274 | // and clip the remaining negative values, while also normalizing [0,1] 275 | // 276 | // --------------------------------------------------------------------------------------- 277 | // HDR/PQ 278 | // --------------------------------------------------------------------------------------- 279 | // The render target format won't change, although the signal encoding will be Gamma2. 280 | // UE4 tonemapper will output normalized (depending on 1000 or 2000 nits) PQ space color. 281 | // The conversion shader will do the following and store the value: PQ -> Linear -> Gamma2 282 | // 283 | // --------------------------------------------------------------------------------------- 284 | // HDR/Linear 285 | // --------------------------------------------------------------------------------------- 286 | // Linear can contain values in [0, FP16_MAX) 287 | // we will use FSR/SRTM (Simple Reversible Tonemapper) to normalize the lienar values 288 | // before storing in a 10:10:10:2_UNORM intermediate target at the end of this pass. 289 | // 290 | // ====================================================================================== 291 | // 292 | // The last pass of the FSR chain will convert back to the original device output space. 293 | // 294 | // ====================================================================================== 295 | 296 | // Set parameters 297 | FColorConversionCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 298 | PassParameters->InputTexture = Data->CurrentInputTexture; 299 | PassParameters->OutputTexture = GraphBuilder.CreateUAV(Data->ColorConvertedTexture.Texture); 300 | 301 | #if ENGINE_MAJOR_VERSION >= 5 && ENGINE_MINOR_VERSION >= 1 302 | #if ENGINE_MINOR_VERSION == 1 303 | FBlueNoise BlueNoise = GetBlueNoiseParameters(); 304 | #elif ENGINE_MINOR_VERSION >= 2 305 | FBlueNoise BlueNoise; 306 | BlueNoise.BlueNoise = GetBlueNoiseParameters(); 307 | #endif 308 | #else 309 | FBlueNoise BlueNoise; 310 | InitializeBlueNoise(BlueNoise); 311 | #endif 312 | 313 | PassParameters->BlueNoise = CreateUniformBufferImmediate(BlueNoise, EUniformBufferUsage::UniformBuffer_SingleFrame); 314 | PassParameters->DitherAmount = FMath::Min(1.0f, FMath::Max(0.0f, GFSR_HDR_PQDither)); 315 | 316 | // Set shader variant 317 | FColorConversionCS::FPermutationDomain CSPermutationVector; 318 | CSPermutationVector.Set(Data->eOUTPUT_DEVICE); 319 | CSPermutationVector.Set(Data->eMAX_NITS); 320 | if (Data->eOUTPUT_DEVICE == EFSR_OutputDevice::PQ) 321 | { 322 | CSPermutationVector.Set(PassParameters->DitherAmount > 0); 323 | } 324 | 325 | // Dispatch 326 | TShaderMapRef ComputeShaderFSR(View.ShaderMap, CSPermutationVector); 327 | FComputeShaderUtils::AddPass( 328 | GraphBuilder, 329 | RDG_EVENT_NAME("FidelityFX-FSR/HDRColorConversion (Gamma2) OutputDevice=%d DeviceMaxNits=%d (CS)" 330 | , Data->TonemapperOutputDeviceParameters.OutputDevice 331 | , (Data->eMAX_NITS == EFSR_OutputDeviceMaxNits::EFSR_1000Nits ? 1000 : 2000) 332 | ), 333 | ComputeShaderFSR, 334 | PassParameters, 335 | FComputeShaderUtils::GetGroupCount(Data->InputViewport.Rect.Size(), 16) 336 | ); 337 | 338 | Data->CurrentInputTexture = Data->ColorConvertedTexture.Texture; 339 | 340 | Data->bHDRColorConversionPassRan = true; 341 | } 342 | } 343 | 344 | void FFSRSubpassHDR::PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 345 | { 346 | // it is possible for the Upscale pass to have been skipped (like if DRS has the screen percentage at 100). if that happened but it was needed, run it now. 347 | if (Data->bHDRColorConversionPassEnabled && !Data->bHDRColorConversionPassRan) 348 | { 349 | Upscale(GraphBuilder, View, PassInputs); 350 | } 351 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassHDR.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRSubpass.h" 24 | 25 | class FFSRSubpassHDR : public FFSRSubpass 26 | { 27 | public: 28 | void ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 29 | void CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 30 | void Upscale(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 31 | void PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 32 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassLast.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSubpassLast.h" 22 | 23 | void FFSRSubpassLast::ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 24 | { 25 | Data->bEASUIsTheLastPass = !Data->bRCASEnabled && !Data->bChromaticAberrationPassEnabled; 26 | Data->bRCASIsTheLastPass = Data->bRCASEnabled && !Data->bChromaticAberrationPassEnabled; 27 | Data->bChromAbIsTheLastPass = Data->bChromaticAberrationPassEnabled; 28 | } 29 | 30 | void FFSRSubpassLast::CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 31 | { 32 | Data->CurrentInputTexture = PassInputs.SceneColor.Texture; 33 | 34 | // we're done with the "initialization" steps, so set up to skip them if we run against this object again. 35 | Data->bInitialized = true; 36 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassLast.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRSubpass.h" 24 | 25 | class FFSRSubpassLast : public FFSRSubpass 26 | { 27 | public: 28 | void ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 29 | void CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 30 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassRCAS.cpp: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #include "FSRSubpassRCAS.h" 22 | 23 | #if ENGINE_MAJOR_VERSION > 5 || (ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION >= 2) 24 | #include 25 | #include 26 | #endif 27 | 28 | static int32 GFSR_RCAS = 1; 29 | static FAutoConsoleVariableRef CVarFSRAddRCAS( 30 | TEXT("r.FidelityFX.FSR.RCAS.Enabled"), 31 | GFSR_RCAS, 32 | TEXT("FidelityFX FSR/RCAS : Robust Contrast Adaptive Sharpening Filter. Requires r.FidelityFX.FSR.PrimaryUpscale 1 or r.FidelityFX.FSR.SecondaryUpscale 1"), 33 | ECVF_RenderThreadSafe); 34 | 35 | static float GFSR_Sharpness = 0.2; // 0.2 stops = 1 / (2^N) ~= 0.87 in lienar [0-1] sharpening of CAS 36 | static FAutoConsoleVariableRef CVarFSRRCASSharpness( 37 | TEXT("r.FidelityFX.FSR.RCAS.Sharpness"), 38 | GFSR_Sharpness, 39 | TEXT("FidelityFX RCAS Sharpness in stops (0: sharpest, 1: 1/2 as sharp, 2: 1/4 as sharp, 3: 1/8 as sharp, etc.). A value of 0.2 would correspond to a ~0.87 sharpness in [0-1] linear scale"), 40 | ECVF_RenderThreadSafe); 41 | 42 | static int32 GFSR_RCASDenoise = 0; 43 | static FAutoConsoleVariableRef CVarFSRRCASDenoise( 44 | TEXT("r.FidelityFX.FSR.RCAS.Denoise"), 45 | GFSR_RCASDenoise, 46 | TEXT("FidelityFX RCAS Denoise support for grainy input such as dithered images or input with custom film grain effects applied prior to FSR. 1:On, 0:Off"), 47 | ECVF_RenderThreadSafe); 48 | 49 | /// 50 | /// RCAS COMPUTE SHADER 51 | /// 52 | class FRCASCS : public FGlobalShader 53 | { 54 | public: 55 | DECLARE_GLOBAL_SHADER(FRCASCS); 56 | SHADER_USE_PARAMETER_STRUCT(FRCASCS, FGlobalShader); 57 | 58 | using FPermutationDomain = TShaderPermutationDomain; 59 | 60 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 61 | SHADER_PARAMETER_STRUCT_INCLUDE(FRCASPassParameters, RCAS) 62 | SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, OutputTexture) 63 | END_SHADER_PARAMETER_STRUCT() 64 | 65 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 66 | { 67 | FPermutationDomain PermutationVector(Parameters.PermutationId); 68 | const EFSR_OutputDevice eFSROutputDevice = PermutationVector.Get(); 69 | 70 | if (PermutationVector.Get()) 71 | { 72 | if (Parameters.Platform != SP_PCD3D_SM5) 73 | { 74 | return false; //only compile FP16 shader permutation for Desktop PC. 75 | } 76 | } 77 | 78 | if (!PermutationVector.Get() && eFSROutputDevice != EFSR_OutputDevice::sRGB) 79 | { 80 | return false; // don't compile FSR_OUTPUTDEVICE dimensions when there's no HDR conversions (== sRGB case) 81 | } 82 | 83 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 84 | } 85 | static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 86 | { 87 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEX"), 64); 88 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEY"), 1); 89 | OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZEZ"), 1); 90 | OutEnvironment.SetDefine(TEXT("COMPUTE_SHADER"), 1); 91 | } 92 | }; 93 | 94 | IMPLEMENT_GLOBAL_SHADER(FRCASCS, "/Plugin/FSR/Private/PostProcessFFX_RCAS.usf", "MainCS", SF_Compute); 95 | 96 | /// 97 | /// RCAS PIXEL SHADER 98 | /// 99 | class FRCASPS : public FGlobalShader 100 | { 101 | public: 102 | DECLARE_GLOBAL_SHADER(FRCASPS); 103 | SHADER_USE_PARAMETER_STRUCT(FRCASPS, FGlobalShader); 104 | 105 | using FPermutationDomain = TShaderPermutationDomain; 106 | 107 | BEGIN_SHADER_PARAMETER_STRUCT(FParameters, ) 108 | SHADER_PARAMETER_STRUCT_INCLUDE(FRCASPassParameters, RCAS) 109 | RENDER_TARGET_BINDING_SLOTS() 110 | END_SHADER_PARAMETER_STRUCT() 111 | 112 | static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters) 113 | { 114 | FPermutationDomain PermutationVector(Parameters.PermutationId); 115 | const EFSR_OutputDevice eFSROutputDevice = PermutationVector.Get(); 116 | 117 | if (PermutationVector.Get()) 118 | { 119 | if (Parameters.Platform != SP_PCD3D_SM5) 120 | { 121 | return false; //only compile FP16 shader permutation for Desktop PC. 122 | } 123 | } 124 | 125 | if (!PermutationVector.Get() && eFSROutputDevice != EFSR_OutputDevice::sRGB) 126 | { 127 | return false; // don't compile FSR_OUTPUTDEVICE dimensions when there's no HDR conversions (== sRGB case) 128 | } 129 | 130 | return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5); 131 | } 132 | static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment) 133 | { 134 | } 135 | }; 136 | 137 | IMPLEMENT_GLOBAL_SHADER(FRCASPS, "/Plugin/FSR/Private/PostProcessFFX_RCAS.usf", "MainPS", SF_Pixel); 138 | 139 | void FFSRSubpassRCAS::ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 140 | { 141 | Data->bRCASEnabled = GFSR_RCAS > 0; 142 | Data->bUSE_RCAS_DENOISE = GFSR_RCASDenoise > 0; 143 | } 144 | 145 | void FFSRSubpassRCAS::CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 146 | { 147 | if (Data->bRCASEnabled) 148 | { 149 | const bool bRCASOutputsToLinearRT = Data->bHDRColorConversionPassEnabled && Data->bRCASIsTheLastPass 150 | && (Data->eOUTPUT_DEVICE == EFSR_OutputDevice::scRGB || Data->eOUTPUT_DEVICE == EFSR_OutputDevice::Linear); 151 | 152 | FRDGTextureDesc RCASOutputTextureDesc = Data->UpscaleTexture.Texture->Desc; 153 | 154 | // if we have converted scRGB/Linear input to perceptual space before, we need to convert back to scRGB/Linear 155 | // again at the end of RCAS, hence, override the output format of RCAS from 10:10:10:2_UNORM to RGBA16F 156 | if (bRCASOutputsToLinearRT) 157 | { 158 | RCASOutputTextureDesc.Format = PassInputs.SceneColor.Texture->Desc.Format; /*PF_FloatRGBA*/ 159 | } 160 | Data->SharpenedTexture = FScreenPassTexture(Data->UpscaleTexture); 161 | Data->SharpenedTexture.Texture = GraphBuilder.CreateTexture(RCASOutputTextureDesc, TEXT("FFX-RCAS-Output"), ERDGTextureFlags::MultiFrame); 162 | } 163 | } 164 | 165 | void FFSRSubpassRCAS::PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) 166 | { 167 | // 168 | // FidelityFX Robust Contrast Adaptive Sharpening (RCAS) Pass 169 | // 170 | if (Data->bRCASEnabled) 171 | { 172 | AU1 const0[4]; // Configure FSR 173 | const bool bUSE_RCAS_GRAIN_INTENSITY = !Data->bChromaticAberrationPassEnabled && Data->bUSE_GRAIN_INTENSITY; 174 | 175 | FsrRcasCon(const0, GFSR_Sharpness); 176 | 177 | FScreenPassRenderTarget Output = Data->bChromaticAberrationPassEnabled 178 | ? FScreenPassRenderTarget(Data->SharpenedTexture.Texture, ERenderTargetLoadAction::ENoAction) 179 | : PassInputs.OverrideOutput; // if no ChromAb, RCAS is last pass so override output 180 | if (!Output.IsValid()) 181 | { 182 | Output = FScreenPassRenderTarget(Data->SharpenedTexture.Texture, ERenderTargetLoadAction::ENoAction); 183 | } 184 | const bool bOutputSupportsUAV = (Output.Texture->Desc.Flags & TexCreate_UAV) == TexCreate_UAV; 185 | 186 | // VS-PS 187 | if (!bOutputSupportsUAV || Data->bFORCE_VSPS) 188 | { 189 | FRCASPS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 190 | 191 | // set pass inputs 192 | for (int i = 0; i < 4; i++) { PassParameters->RCAS.Const0[i] = const0[i]; } 193 | PassParameters->RCAS.InputTexture = Data->CurrentInputTexture; 194 | PassParameters->RCAS.FilmGrain = Data->FilmGrainParams; 195 | PassParameters->RCAS.VPColor_ExtentInverse = Data->PassOutputViewportParams.ExtentInverse; 196 | PassParameters->RenderTargets[0] = FRenderTargetBinding(Output.Texture, ERenderTargetLoadAction::ENoAction); 197 | 198 | // grab shaders 199 | FRCASPS::FPermutationDomain PSPermutationVector; 200 | PSPermutationVector.Set(Data->bUSE_FP16); 201 | PSPermutationVector.Set(bUSE_RCAS_GRAIN_INTENSITY); 202 | PSPermutationVector.Set(Data->bUSE_RCAS_DENOISE); 203 | 204 | PSPermutationVector.Set(Data->bHDRColorConversionPassEnabled && Data->bRCASIsTheLastPass); 205 | if (PSPermutationVector.Get()) 206 | { 207 | PSPermutationVector.Set(Data->eOUTPUT_DEVICE); 208 | PSPermutationVector.Set(Data->eMAX_NITS); 209 | } 210 | 211 | TShaderMapRef PixelShader(View.ShaderMap, PSPermutationVector); 212 | 213 | AddDrawScreenPass(GraphBuilder, 214 | RDG_EVENT_NAME("FidelityFX-FSR/RCAS Sharpness=%.2f OutputDevice=%d GrainIntensity=%d (PS)" 215 | , GFSR_Sharpness 216 | , Data->TonemapperOutputDeviceParameters.OutputDevice 217 | , ((bUSE_RCAS_GRAIN_INTENSITY) ? 1 : 0)), 218 | View, Data->OutputViewport, Data->OutputViewport, 219 | PixelShader, PassParameters, 220 | EScreenPassDrawFlags::None 221 | ); 222 | } 223 | // CS 224 | else 225 | { 226 | FRCASCS::FParameters* PassParameters = GraphBuilder.AllocParameters(); 227 | 228 | for (int i = 0; i < 4; i++) 229 | { 230 | PassParameters->RCAS.Const0[i] = const0[i]; 231 | } 232 | PassParameters->RCAS.InputTexture = Data->CurrentInputTexture; 233 | PassParameters->RCAS.FilmGrain = Data->FilmGrainParams; 234 | PassParameters->RCAS.VPColor_ExtentInverse = Data->PassOutputViewportParams.ExtentInverse; 235 | PassParameters->OutputTexture = GraphBuilder.CreateUAV(Data->SharpenedTexture.Texture); 236 | 237 | FRCASCS::FPermutationDomain CSPermutationVector; 238 | CSPermutationVector.Set(Data->bUSE_FP16); 239 | CSPermutationVector.Set(Data->bUSE_RCAS_DENOISE); 240 | CSPermutationVector.Set(bUSE_RCAS_GRAIN_INTENSITY); 241 | CSPermutationVector.Set(Data->bHDRColorConversionPassEnabled && Data->bRCASIsTheLastPass); 242 | if (CSPermutationVector.Get()) 243 | { 244 | CSPermutationVector.Set(Data->eOUTPUT_DEVICE); 245 | CSPermutationVector.Set(Data->eMAX_NITS); 246 | } 247 | 248 | TShaderMapRef ComputeShaderRCASPass(View.ShaderMap, CSPermutationVector); 249 | FComputeShaderUtils::AddPass( 250 | GraphBuilder, 251 | RDG_EVENT_NAME("FidelityFX-FSR/RCAS Sharpness=%.2f OutputDevice=%d GrainIntensity=%d (CS)" 252 | , GFSR_Sharpness 253 | , Data->TonemapperOutputDeviceParameters.OutputDevice 254 | , ((bUSE_RCAS_GRAIN_INTENSITY) ? 1 : 0)), 255 | ComputeShaderRCASPass, 256 | PassParameters, 257 | FComputeShaderUtils::GetGroupCount(Data->OutputViewport.Rect.Size(), 16)); 258 | } 259 | 260 | Data->FinalOutput = Output; 261 | Data->CurrentInputTexture = Output.Texture; 262 | } 263 | } -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassRCAS.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "FSRSubpass.h" 24 | 25 | class FFSRSubpassRCAS : public FFSRSubpass 26 | { 27 | public: 28 | void ParseEnvironment(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 29 | void CreateResources(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 30 | void PostProcess(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FInputs& PassInputs) override; 31 | 32 | private: 33 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Private/Subpasses/FSRSubpassSharedTypes.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "ShaderParameterMacros.h" 24 | #include "Shader.h" 25 | 26 | #include "Runtime/Launch/Resources/Version.h" 27 | 28 | // =============================================================================================================================================== 29 | // 30 | // FIDELITYFX CONFIGURATION 31 | // 32 | // =============================================================================================================================================== 33 | #define A_CPU 1 34 | // colliding ffx_a.ush/UE4Engine definitions 35 | // ffx_a.ush will override these definitions 36 | #ifdef A_STATIC 37 | #undef A_STATIC 38 | #endif 39 | #ifdef A_RESTRICT 40 | #undef A_RESTRICT 41 | #endif 42 | #include "../Shaders/Private/ffx_a.ush" 43 | #include "../Shaders/Private/ffx_fsr1.ush" 44 | 45 | // =============================================================================================================================================== 46 | // 47 | // SHADER DEFINITIONS 48 | // 49 | // =============================================================================================================================================== 50 | 51 | // 52 | // SHADER PASS PARAMETERS 53 | // 54 | enum class EFSR_OutputDevice // should match PostProcessFFX_Common.ush 55 | { 56 | sRGB = 0, 57 | Linear, 58 | PQ, 59 | scRGB, 60 | MAX 61 | }; 62 | enum class EFSR_OutputDeviceMaxNits // matching UE4's scRGB/PQ-1000Nits and scRGB/PQ-2000Nits 63 | { 64 | EFSR_1000Nits, 65 | EFSR_2000Nits, 66 | MAX 67 | }; 68 | 69 | // permutation domains 70 | class FFSR_UseFP16Dim : SHADER_PERMUTATION_BOOL("ENABLE_FP16"); 71 | class FFSR_OutputDeviceDim : SHADER_PERMUTATION_ENUM_CLASS("FSR_OUTPUTDEVICE", EFSR_OutputDevice); 72 | class FFSR_OutputDeviceNitsDim : SHADER_PERMUTATION_ENUM_CLASS("MAX_ODT_NITS_ENUM", EFSR_OutputDeviceMaxNits); 73 | class FFSR_OutputDeviceConversion : SHADER_PERMUTATION_BOOL("CONVERT_TO_OUTPUT_DEVICE"); 74 | class FFSR_PQDitherDim : SHADER_PERMUTATION_BOOL("ENABLE_PQ_DITHER"); 75 | class FFSR_GrainDim : SHADER_PERMUTATION_BOOL("USE_GRAIN_INTENSITY"); 76 | class FRCAS_DenoiseDim : SHADER_PERMUTATION_BOOL("USE_RCAS_DENOISE"); 77 | 78 | // 79 | // SHADER PASS PARAMETERS 80 | // 81 | BEGIN_SHADER_PARAMETER_STRUCT(FFSRPassParameters_Grain, ) 82 | #if ENGINE_MAJOR_VERSION >= 5 83 | SHADER_PARAMETER(FVector4f, GrainRandomFull) 84 | SHADER_PARAMETER(FVector4f, GrainScaleBiasJitter) 85 | #else 86 | SHADER_PARAMETER(FVector4, GrainRandomFull) 87 | SHADER_PARAMETER(FVector4, GrainScaleBiasJitter) 88 | #endif 89 | END_SHADER_PARAMETER_STRUCT() 90 | 91 | BEGIN_SHADER_PARAMETER_STRUCT(FFSRPassParameters, ) 92 | SHADER_PARAMETER(FUintVector4, Const0) 93 | SHADER_PARAMETER(FUintVector4, Const1) 94 | SHADER_PARAMETER(FUintVector4, Const2) 95 | SHADER_PARAMETER(FUintVector4, Const3) 96 | SHADER_PARAMETER_STRUCT_INCLUDE(FFSRPassParameters_Grain, FilmGrain) 97 | 98 | #if ENGINE_MAJOR_VERSION >= 5 99 | SHADER_PARAMETER(FVector2f, VPColor_ExtentInverse) 100 | SHADER_PARAMETER(FVector2f, VPColor_ViewportMin) 101 | #else 102 | SHADER_PARAMETER(FVector2D, VPColor_ExtentInverse) 103 | SHADER_PARAMETER(FVector2D, VPColor_ViewportMin) 104 | #endif 105 | 106 | SHADER_PARAMETER_SAMPLER(SamplerState, samLinearClamp) 107 | SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture) 108 | END_SHADER_PARAMETER_STRUCT() 109 | 110 | BEGIN_SHADER_PARAMETER_STRUCT(FRCASPassParameters, ) 111 | SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture) 112 | SHADER_PARAMETER(FUintVector4, Const0) 113 | SHADER_PARAMETER_STRUCT_INCLUDE(FFSRPassParameters_Grain, FilmGrain) 114 | 115 | #if ENGINE_MAJOR_VERSION >= 5 116 | SHADER_PARAMETER(FVector2f, VPColor_ExtentInverse) 117 | #else 118 | SHADER_PARAMETER(FVector2D, VPColor_ExtentInverse) 119 | #endif 120 | END_SHADER_PARAMETER_STRUCT() -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Public/FSRSpatialUpscaling.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "Modules/ModuleManager.h" 24 | 25 | class FFSRSpatialUpscalingModule final : public IModuleInterface 26 | { 27 | public: 28 | // IModuleInterface implementation 29 | void StartupModule() override; 30 | void ShutdownModule() override; 31 | }; -------------------------------------------------------------------------------- /Source/FSRSpatialUpscaling/Public/FSRViewExtension.h: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // FidelityFX Super Resolution UE4 Plugin 3 | // 4 | // Copyright (c) 2021 Advanced Micro Devices, Inc. All rights reserved. 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files(the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions : 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | //------------------------------------------------------------------------------ 21 | #pragma once 22 | 23 | #include "SceneViewExtension.h" 24 | 25 | class FFSRViewExtension final : public FSceneViewExtensionBase 26 | { 27 | public: 28 | FFSRViewExtension(const FAutoRegister& AutoRegister) : FSceneViewExtensionBase(AutoRegister) {} 29 | 30 | // ISceneViewExtension interface 31 | void SetupViewFamily(FSceneViewFamily& InViewFamily) override {} 32 | void SetupView(FSceneViewFamily& InViewFamily, FSceneView& InView) override {} 33 | void PreRenderViewFamily_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneViewFamily& InViewFamily) override {} 34 | 35 | FSRSPATIALUPSCALING_API void BeginRenderViewFamily(FSceneViewFamily& InViewFamily) override; 36 | FSRSPATIALUPSCALING_API void PreRenderView_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneView& InView) override; 37 | }; --------------------------------------------------------------------------------