diff --git a/Assets/Scripts/Fsr2.cs b/Assets/Scripts/Fsr2.cs index 399391f..d10e047 100644 --- a/Assets/Scripts/Fsr2.cs +++ b/Assets/Scripts/Fsr2.cs @@ -29,7 +29,7 @@ namespace FidelityFX EnableTexture1DUsage = 1 << 7, } - public class ContextDescription + public struct ContextDescription { public InitializationFlags Flags; public Vector2Int MaxRenderSize; @@ -130,5 +130,11 @@ namespace FidelityFX return result; } + + public static float Lanczos2(float value) + { + return Mathf.Abs(value) < Mathf.Epsilon ? 1.0f : + Mathf.Sin(Mathf.PI * value) / (Mathf.PI * value) * (Mathf.Sin(0.5f * Mathf.PI * value) / (0.5f * Mathf.PI * value)); + } } } diff --git a/Assets/Scripts/Fsr2Context.cs b/Assets/Scripts/Fsr2Context.cs index 7746636..f6f4880 100644 --- a/Assets/Scripts/Fsr2Context.cs +++ b/Assets/Scripts/Fsr2Context.cs @@ -8,8 +8,15 @@ namespace FidelityFX public class Fsr2Context { private Fsr2.ContextDescription _contextDescription; - - private ComputeShader _rcasComputeShader; + + private ComputeShader _prepareInputColorShader; + private ComputeShader _depthClipShader; + private ComputeShader _reconstructPreviousDepthShader; + private ComputeShader _lockShader; + private ComputeShader _accumulateShader; + private ComputeShader _generateReactiveShader; + private ComputeShader _rcasShader; + private ComputeShader _computeLuminancePyramidShader; private ComputeBuffer _fsr2ConstantsBuffer; private readonly Fsr2Constants[] _fsr2ConstantsArray = { new Fsr2Constants() }; @@ -24,12 +31,45 @@ namespace FidelityFX { _contextDescription = contextDescription; - if (_rcasComputeShader == null) - _rcasComputeShader = _contextDescription.Callbacks.LoadComputeShader("FSR2/ffx_fsr2_rcas_pass"); - _fsr2ConstantsBuffer = new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant); _spdConstantsBuffer = new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant); _rcasConstantsBuffer = new ComputeBuffer(1, Marshal.SizeOf(), ComputeBufferType.Constant); + + // Set defaults + _fsr2ConstantsArray[0].displaySize = _contextDescription.DisplaySize; + _fsr2ConstantsArray[0].displaySizeRcp = new Vector2( + 1.0f / _contextDescription.DisplaySize.x, + 1.0f / _contextDescription.DisplaySize.y); + + // Generate the data for the LUT + const uint lanczos2LutWidth = 128; + short[] lanczos2Weights = new short[lanczos2LutWidth]; + for (uint currentLanczosWidthIndex = 0; currentLanczosWidthIndex < lanczos2LutWidth; ++currentLanczosWidthIndex) + { + float x = 2.0f * currentLanczosWidthIndex / (lanczos2LutWidth - 1); + float y = Fsr2.Lanczos2(x); + lanczos2Weights[currentLanczosWidthIndex] = (short)Mathf.Round(y * 32767.0f); + } + + InitShaders(); + } + + private void InitShaders() + { + LoadComputeShader("FSR2/ffx_fsr2_compute_luminance_pyramid_pass", ref _computeLuminancePyramidShader); + LoadComputeShader("FSR2/ffx_fsr2_rcas_pass", ref _rcasShader); + LoadComputeShader("FSR2/ffx_fsr2_prepare_input_color_pass", ref _prepareInputColorShader); + LoadComputeShader("FSR2/ffx_fsr2_depth_clip_pass", ref _depthClipShader); + LoadComputeShader("FSR2/ffx_fsr2_reconstruct_previous_depth_pass", ref _reconstructPreviousDepthShader); + LoadComputeShader("FSR2/ffx_fsr2_lock_pass", ref _lockShader); + LoadComputeShader("FSR2/ffx_fsr2_accumulate_pass", ref _accumulateShader); + LoadComputeShader("FSR2/ffx_fsr2_autogen_reactive_pass", ref _generateReactiveShader); + } + + private void LoadComputeShader(string name, ref ComputeShader shaderRef) + { + if (shaderRef == null) + shaderRef = _contextDescription.Callbacks.LoadComputeShader(name); } public void Dispatch(Fsr2.DispatchDescription dispatchDescription) @@ -44,18 +84,18 @@ namespace FidelityFX _rcasConstantsBuffer.SetData(_rcasConstantsArray); // Run the RCAS sharpening filter on the upscaled image - int rcasKernel = _rcasComputeShader.FindKernel("CS"); - _rcasComputeShader.SetTexture(rcasKernel, "r_exposure", dispatchDescription.Exposure); - _rcasComputeShader.SetTexture(rcasKernel, "r_rcas_input", dispatchDescription.Input); - _rcasComputeShader.SetTexture(rcasKernel, "rw_upscaled_output", dispatchDescription.Output); - _rcasComputeShader.SetConstantBuffer("cbFSR2", _fsr2ConstantsBuffer, 0, Marshal.SizeOf()); - _rcasComputeShader.SetConstantBuffer("cbRCAS", _rcasConstantsBuffer, 0, Marshal.SizeOf()); + int rcasKernel = _rcasShader.FindKernel("CS"); + _rcasShader.SetTexture(rcasKernel, "r_exposure", dispatchDescription.Exposure); + _rcasShader.SetTexture(rcasKernel, "r_rcas_input", dispatchDescription.Input); + _rcasShader.SetTexture(rcasKernel, "rw_upscaled_output", dispatchDescription.Output); + _rcasShader.SetConstantBuffer("cbFSR2", _fsr2ConstantsBuffer, 0, Marshal.SizeOf()); + _rcasShader.SetConstantBuffer("cbRCAS", _rcasConstantsBuffer, 0, Marshal.SizeOf()); const int threadGroupWorkRegionDimRcas = 16; int threadGroupsX = (Screen.width + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; int threadGroupsY = (Screen.height + threadGroupWorkRegionDimRcas - 1) / threadGroupWorkRegionDimRcas; - _rcasComputeShader.Dispatch(rcasKernel, threadGroupsX, threadGroupsY, 1); + _rcasShader.Dispatch(rcasKernel, threadGroupsX, threadGroupsY, 1); } else {