@ -2,6 +2,7 @@
using System.Collections.Generic ;
using System.Runtime.InteropServices ;
using UnityEngine ;
using UnityEngine.Experimental.Rendering ;
using UnityEngine.Rendering ;
namespace FidelityFX
@ -23,6 +24,9 @@ namespace FidelityFX
private Fsr2Pipeline _generateReactivePipeline ;
private Fsr2Pipeline _tcrAutogeneratePipeline ;
private Texture2D _lanczosLutResource ;
private RenderTexture _autoExposureResource ;
private ComputeBuffer _fsr2ConstantsBuffer ;
private readonly Fsr2 . Fsr2Constants [ ] _fsr2ConstantsArray = { new Fsr2 . Fsr2Constants ( ) } ;
private ref Fsr2 . Fsr2Constants Constants = > ref _fsr2ConstantsArray [ 0 ] ;
@ -58,10 +62,16 @@ namespace FidelityFX
Constants . displaySize = _contextDescription . DisplaySize ;
CreateResources ( ) ;
CreatePipelines ( ) ;
}
private void CreateResources ( )
{
// Generate the data for the LUT
const uint lanczos2LutWidth = 1 2 8 ;
const int lanczos2LutWidth = 1 2 8 ;
short [ ] lanczos2Weights = new short [ lanczos2LutWidth ] ;
for ( uint currentLanczosWidthIndex = 0 ; currentLanczosWidthIndex < lanczos2LutWidth ; + + currentLanczosWidthIndex )
for ( int currentLanczosWidthIndex = 0 ; currentLanczosWidthIndex < lanczos2LutWidth ; + + currentLanczosWidthIndex )
{
float x = 2.0f * currentLanczosWidthIndex / ( lanczos2LutWidth - 1 ) ;
float y = Fsr2 . Lanczos2 ( x ) ;
@ -73,10 +83,18 @@ namespace FidelityFX
// UAVs *may* be an issue with the PS4 not handling simultaneous reading and writing to an RT properly
// Unity does have Graphics.SetRandomWriteTarget for enabling UAV on ComputeBuffers or RTs
// Unity doesn't do 1D textures so just default to Texture2D
CreatePipelines ( ) ;
}
// Resource FSR2_LanczosLutData: FFX_RESOURCE_USAGE_READ_ONLY, FFX_SURFACE_FORMAT_R16_SNORM, FFX_RESOURCE_FLAGS_NONE
// TODO FIXME: R16_SNorm not supported? That's weird... This really ought to be a ComputeBuffer, not a Texture2D. Or just use R16_SFloat and upload pre-normalized floats, I guess...
// _lanczosLutResource = new Texture2D(lanczos2LutWidth, 1, GraphicsFormat.R16_SNorm, TextureCreationFlags.None) { name = "FSR2_LanczosLutData" };
// _lanczosLutResource.SetPixelData(lanczos2Weights, 0);
// _lanczosLutResource.Apply();
// Resource FSR2_AutoExposure: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE
_autoExposureResource = new RenderTexture ( 1 , 1 , 1 , GraphicsFormat . R32G32_SFloat ) { name = "FSR2_AutoExposure" , enableRandomWrite = true } ;
_autoExposureResource . Create ( ) ;
}
// private void InitShaders()
// {
// LoadComputeShader("FSR2/ffx_fsr2_compute_luminance_pyramid_pass", ref _computeLuminancePyramidShader, out _computeLuminancePyramidKernel);
@ -92,7 +110,8 @@ namespace FidelityFX
private void CreatePipelines ( )
{
_computeLuminancePyramidPipeline = new Fsr2ComputeLuminancePyramidPipeline ( _contextDescription . Callbacks , _contextDescription . Flags , _fsr2ConstantsBuffer , _spdConstantsBuffer ) ;
_computeLuminancePyramidPipeline =
new Fsr2ComputeLuminancePyramidPipeline ( _contextDescription . Callbacks , _contextDescription . Flags , _fsr2ConstantsBuffer , _spdConstantsBuffer , _autoExposureResource ) ;
_accumulatePipeline = new Fsr2AccumulatePipeline ( _contextDescription . Callbacks , _contextDescription . Flags , _fsr2ConstantsBuffer ) ;
_accumulateSharpenPipeline = new Fsr2AccumulateSharpenPipeline ( _contextDescription . Callbacks , _contextDescription . Flags , _fsr2ConstantsBuffer ) ;
_rcasPipeline = new Fsr2RcasPipeline ( _contextDescription . Callbacks , _contextDescription . Flags , _fsr2ConstantsBuffer , _rcasConstantsBuffer ) ;
@ -110,6 +129,9 @@ namespace FidelityFX
DestroyPipeline ( ref _reconstructPreviousDepthPipeline ) ;
DestroyPipeline ( ref _depthClipPipeline ) ;
DestroyResource ( ref _autoExposureResource ) ;
DestroyResource ( ref _lanczosLutResource ) ;
DestroyConstantBuffer ( ref _rcasConstantsBuffer ) ;
DestroyConstantBuffer ( ref _spdConstantsBuffer ) ;
DestroyConstantBuffer ( ref _fsr2ConstantsBuffer ) ;
@ -214,32 +236,24 @@ namespace FidelityFX
dispatchParams . RenderSize . x > 0 ? dispatchParams . RenderSize . x : dispatchParams . Input . width ,
dispatchParams . RenderSize . y > 0 ? dispatchParams . RenderSize . y : dispatchParams . Input . height ) ;
constants . maxRenderSize = _contextDescription . MaxRenderSize ;
constants . inputColorResourceDimensions =
new Vector2Int ( dispatchParams . Input . width , dispatchParams . Input . height ) ;
constants . inputColorResourceDimensions = new Vector2Int ( dispatchParams . Input . width , dispatchParams . Input . height ) ;
// Compute the horizontal FOV for the shader from the vertical one
float aspectRatio = ( float ) dispatchParams . RenderSize . x / dispatchParams . RenderSize . y ;
float cameraAngleHorizontal = Mathf . Atan ( Mathf . Tan ( dispatchParams . CameraFovAngleVertical / 2.0f ) * aspectRatio ) * 2.0f ;
constants . tanHalfFOV = Mathf . Tan ( cameraAngleHorizontal * 0.5f ) ;
constants . viewSpaceToMetersFactor =
( dispatchParams . ViewSpaceToMetersFactor > 0.0f ) ? dispatchParams . ViewSpaceToMetersFactor : 1.0f ;
constants . viewSpaceToMetersFactor = ( dispatchParams . ViewSpaceToMetersFactor > 0.0f ) ? dispatchParams . ViewSpaceToMetersFactor : 1.0f ;
// Compute params to enable device depth to view space depth computation in shader
constants . deviceToViewDepth = SetupDeviceDepthToViewSpaceDepthParams ( dispatchParams ) ;
// To be updated if resource is larger than the actual image size
constants . downscaleFactor = new Vector2 (
( float ) constants . renderSize . x / _contextDescription . DisplaySize . x ,
( float ) constants . renderSize . y / _contextDescription . DisplaySize . y ) ;
constants . downscaleFactor = new Vector2 ( ( float ) constants . renderSize . x / _contextDescription . DisplaySize . x , ( float ) constants . renderSize . y / _contextDescription . DisplaySize . y ) ;
constants . previousFramePreExposure = constants . preExposure ;
constants . preExposure = ( dispatchParams . PreExposure ! = 0 ) ? dispatchParams . PreExposure : 1.0f ;
// Motion vector data
Vector2Int motionVectorsTargetSize =
( _contextDescription . Flags & Fsr2 . InitializationFlags . EnableDisplayResolutionMotionVectors ) ! = 0
? constants . displaySize
: constants . renderSize ;
Vector2Int motionVectorsTargetSize = ( _contextDescription . Flags & Fsr2 . InitializationFlags . EnableDisplayResolutionMotionVectors ) ! = 0 ? constants . displaySize : constants . renderSize ;
constants . motionVectorScale = dispatchParams . MotionVectorScale / motionVectorsTargetSize ;
// Compute jitter cancellation
@ -302,8 +316,7 @@ namespace FidelityFX
// Revert x and y coords
float aspect = ( float ) dispatchParams . RenderSize . x / dispatchParams . RenderSize . y ;
float cotHalfFovY = Mathf . Cos ( 0.5f * dispatchParams . CameraFovAngleVertical ) /
Mathf . Sin ( 0.5f * dispatchParams . CameraFovAngleVertical ) ;
float cotHalfFovY = Mathf . Cos ( 0.5f * dispatchParams . CameraFovAngleVertical ) / Mathf . Sin ( 0.5f * dispatchParams . CameraFovAngleVertical ) ;
int matrixIndex = ( inverted ? 2 : 0 ) + ( infinite ? 1 : 0 ) ;
return new Vector4 (
@ -395,6 +408,33 @@ namespace FidelityFX
bufferRef = null ;
}
private static void DestroyResource ( ref ComputeBuffer resource )
{
if ( resource = = null )
return ;
resource . Release ( ) ;
resource = null ;
}
private static void DestroyResource ( ref Texture2D resource )
{
if ( resource = = null )
return ;
UnityEngine . Object . Destroy ( resource ) ;
resource = null ;
}
private static void DestroyResource ( ref RenderTexture resource )
{
if ( resource = = null )
return ;
resource . Release ( ) ;
resource = null ;
}
private static void DestroyPipeline ( ref Fsr2Pipeline pipeline )
{
if ( pipeline = = null )