@ -103,7 +103,7 @@ namespace FidelityFX
public RenderTexture outputMotionVectors ;
public RenderTexture outputMotionVectors ;
private Fsr2Context _context ;
private Fsr2Context _context ;
private Vector2Int _r enderSize ;
private Vector2Int _maxR enderSize ;
private Vector2Int _displaySize ;
private Vector2Int _displaySize ;
private float _appliedBiasOffset ;
private float _appliedBiasOffset ;
private bool _resetHistory ;
private bool _resetHistory ;
@ -139,8 +139,8 @@ namespace FidelityFX
// Determine the desired rendering and display resolutions
// Determine the desired rendering and display resolutions
_displaySize = GetDisplaySize ( ) ;
_displaySize = GetDisplaySize ( ) ;
Fsr2 . GetRenderResolutionFromQualityMode ( out var r enderWidth, out var r enderHeight, _displaySize . x , _displaySize . y , qualityMode ) ;
_r enderSize = new Vector2Int ( renderWidth , r enderHeight) ;
Fsr2 . GetRenderResolutionFromQualityMode ( out var maxR enderWidth, out var maxR enderHeight, _displaySize . x , _displaySize . y , qualityMode ) ;
_maxR enderSize = new Vector2Int ( maxRenderWidth , maxR enderHeight) ;
if ( ! SystemInfo . supportsComputeShaders )
if ( ! SystemInfo . supportsComputeShaders )
{
{
@ -149,9 +149,9 @@ namespace FidelityFX
return ;
return ;
}
}
if ( _r enderSize . x = = 0 | | _r enderSize . y = = 0 )
if ( _maxR enderSize . x = = 0 | | _maxR enderSize . y = = 0 )
{
{
Debug . LogError ( $"FSR2 render size is invalid: {_renderSize.x}x{_r enderSize.y}. Please check your screen resolution and camera viewport parameters." ) ;
Debug . LogError ( $"FSR2 render size is invalid: {_maxRenderSize.x}x{_maxR enderSize.y}. Please check your screen resolution and camera viewport parameters." ) ;
enabled = false ;
enabled = false ;
return ;
return ;
}
}
@ -186,8 +186,9 @@ namespace FidelityFX
if ( _renderCamera . allowHDR ) flags | = Fsr2 . InitializationFlags . EnableHighDynamicRange ;
if ( _renderCamera . allowHDR ) flags | = Fsr2 . InitializationFlags . EnableHighDynamicRange ;
if ( enableFP16 ) flags | = Fsr2 . InitializationFlags . EnableFP16Usage ;
if ( enableFP16 ) flags | = Fsr2 . InitializationFlags . EnableFP16Usage ;
if ( enableAutoExposure ) flags | = Fsr2 . InitializationFlags . EnableAutoExposure ;
if ( enableAutoExposure ) flags | = Fsr2 . InitializationFlags . EnableAutoExposure ;
if ( UsingDynamicResolution ( ) ) flags | = Fsr2 . InitializationFlags . EnableDynamicResolution ;
_context = Fsr2 . CreateContext ( _displaySize , _r enderSize , Callbacks , flags ) ;
_context = Fsr2 . CreateContext ( _displaySize , _maxR enderSize , Callbacks , flags ) ;
_prevDisplaySize = _displaySize ;
_prevDisplaySize = _displaySize ;
_prevQualityMode = qualityMode ;
_prevQualityMode = qualityMode ;
@ -233,7 +234,7 @@ namespace FidelityFX
private void ApplyMipmapBias ( )
private void ApplyMipmapBias ( )
{
{
// Apply a mipmap bias so that textures retain their sharpness
// Apply a mipmap bias so that textures retain their sharpness
float biasOffset = Fsr2 . GetMipmapBiasOffset ( _r enderSize . x , _displaySize . x ) ;
float biasOffset = Fsr2 . GetMipmapBiasOffset ( _maxR enderSize . x , _displaySize . x ) ;
if ( ! float . IsNaN ( biasOffset ) & & ! float . IsInfinity ( biasOffset ) )
if ( ! float . IsNaN ( biasOffset ) & & ! float . IsInfinity ( biasOffset ) )
{
{
Callbacks . ApplyMipmapBias ( biasOffset ) ;
Callbacks . ApplyMipmapBias ( biasOffset ) ;
@ -285,14 +286,15 @@ namespace FidelityFX
{
{
// Render to a smaller portion of the screen by manipulating the camera's viewport rect
// Render to a smaller portion of the screen by manipulating the camera's viewport rect
_renderCamera . aspect = ( _displaySize . x * _originalRect . width ) / ( _displaySize . y * _originalRect . height ) ;
_renderCamera . aspect = ( _displaySize . x * _originalRect . width ) / ( _displaySize . y * _originalRect . height ) ;
_renderCamera . rect = new Rect ( 0 , 0 , _originalRect . width * _r enderSize . x / _renderCamera . pixelWidth , _originalRect . height * _r enderSize . y / _renderCamera . pixelHeight ) ;
_renderCamera . rect = new Rect ( 0 , 0 , _originalRect . width * _maxR enderSize . x / _renderCamera . pixelWidth , _originalRect . height * _maxR enderSize . y / _renderCamera . pixelHeight ) ;
}
}
// Set up the opaque-only command buffer to make a copy of the camera color buffer right before transparent drawing starts
// Set up the opaque-only command buffer to make a copy of the camera color buffer right before transparent drawing starts
_opaqueInputCommandBuffer . Clear ( ) ;
_opaqueInputCommandBuffer . Clear ( ) ;
if ( autoGenerateReactiveMask | | autoGenerateTransparencyAndComposition )
if ( autoGenerateReactiveMask | | autoGenerateTransparencyAndComposition )
{
{
_colorOpaqueOnly = RenderTexture . GetTemporary ( _renderSize . x , _renderSize . y , 0 , GetDefaultFormat ( ) ) ;
var scaledRenderSize = GetScaledRenderSize ( ) ;
_colorOpaqueOnly = RenderTexture . GetTemporary ( scaledRenderSize . x , scaledRenderSize . y , 0 , GetDefaultFormat ( ) ) ;
_opaqueInputCommandBuffer . Blit ( BuiltinRenderTextureType . CameraTarget , _colorOpaqueOnly ) ;
_opaqueInputCommandBuffer . Blit ( BuiltinRenderTextureType . CameraTarget , _colorOpaqueOnly ) ;
}
}
@ -320,14 +322,16 @@ namespace FidelityFX
if ( ! enableAutoExposure & & exposure ! = null ) _dispatchDescription . Exposure = exposure ;
if ( ! enableAutoExposure & & exposure ! = null ) _dispatchDescription . Exposure = exposure ;
if ( reactiveMask ! = null ) _dispatchDescription . Reactive = reactiveMask ;
if ( reactiveMask ! = null ) _dispatchDescription . Reactive = reactiveMask ;
if ( transparencyAndCompositionMask ! = null ) _dispatchDescription . TransparencyAndComposition = transparencyAndCompositionMask ;
if ( transparencyAndCompositionMask ! = null ) _dispatchDescription . TransparencyAndComposition = transparencyAndCompositionMask ;
var scaledRenderSize = GetScaledRenderSize ( ) ;
_dispatchDescription . Output = null ;
_dispatchDescription . Output = null ;
_dispatchDescription . PreExposure = preExposure ;
_dispatchDescription . PreExposure = preExposure ;
_dispatchDescription . EnableSharpening = performSharpenPass ;
_dispatchDescription . EnableSharpening = performSharpenPass ;
_dispatchDescription . Sharpness = sharpness ;
_dispatchDescription . Sharpness = sharpness ;
_dispatchDescription . MotionVectorScale . x = - _r enderSize. x ;
_dispatchDescription . MotionVectorScale . y = - _r enderSize. y ;
_dispatchDescription . RenderSize = _r enderSize;
_dispatchDescription . MotionVectorScale . x = - scaledR enderSize. x ;
_dispatchDescription . MotionVectorScale . y = - scaledR enderSize. y ;
_dispatchDescription . RenderSize = scaledR enderSize;
_dispatchDescription . FrameTimeDelta = Time . unscaledDeltaTime ;
_dispatchDescription . FrameTimeDelta = Time . unscaledDeltaTime ;
_dispatchDescription . CameraNear = _renderCamera . nearClipPlane ;
_dispatchDescription . CameraNear = _renderCamera . nearClipPlane ;
_dispatchDescription . CameraFar = _renderCamera . farClipPlane ;
_dispatchDescription . CameraFar = _renderCamera . farClipPlane ;
@ -360,7 +364,7 @@ namespace FidelityFX
_genReactiveDescription . ColorOpaqueOnly = _colorOpaqueOnly ;
_genReactiveDescription . ColorOpaqueOnly = _colorOpaqueOnly ;
_genReactiveDescription . ColorPreUpscale = null ;
_genReactiveDescription . ColorPreUpscale = null ;
_genReactiveDescription . OutReactive = null ;
_genReactiveDescription . OutReactive = null ;
_genReactiveDescription . RenderSize = _renderSize ;
_genReactiveDescription . RenderSize = GetScaledRenderSize ( ) ;
_genReactiveDescription . Scale = generateReactiveParameters . scale ;
_genReactiveDescription . Scale = generateReactiveParameters . scale ;
_genReactiveDescription . CutoffThreshold = generateReactiveParameters . cutoffThreshold ;
_genReactiveDescription . CutoffThreshold = generateReactiveParameters . cutoffThreshold ;
_genReactiveDescription . BinaryValue = generateReactiveParameters . binaryValue ;
_genReactiveDescription . BinaryValue = generateReactiveParameters . binaryValue ;
@ -369,14 +373,16 @@ namespace FidelityFX
private void ApplyJitter ( )
private void ApplyJitter ( )
{
{
var scaledRenderSize = GetScaledRenderSize ( ) ;
// Perform custom jittering of the camera's projection matrix according to FSR2's recipe
// Perform custom jittering of the camera's projection matrix according to FSR2's recipe
int jitterPhaseCount = Fsr2 . GetJitterPhaseCount ( _renderSize . x , _displaySize . x ) ;
int jitterPhaseCount = Fsr2 . GetJitterPhaseCount ( scaledR enderSize. x , _displaySize . x ) ;
Fsr2 . GetJitterOffset ( out float jitterX , out float jitterY , Time . frameCount , jitterPhaseCount ) ;
Fsr2 . GetJitterOffset ( out float jitterX , out float jitterY , Time . frameCount , jitterPhaseCount ) ;
_dispatchDescription . JitterOffset = new Vector2 ( jitterX , jitterY ) ;
_dispatchDescription . JitterOffset = new Vector2 ( jitterX , jitterY ) ;
jitterX = 2.0f * jitterX / _r enderSize. x ;
jitterY = 2.0f * jitterY / _r enderSize. y ;
jitterX = 2.0f * jitterX / scaledR enderSize. x ;
jitterY = 2.0f * jitterY / scaledR enderSize. y ;
var jitterTranslationMatrix = Matrix4x4 . Translate ( new Vector3 ( jitterX , jitterY , 0 ) ) ;
var jitterTranslationMatrix = Matrix4x4 . Translate ( new Vector3 ( jitterX , jitterY , 0 ) ) ;
_renderCamera . nonJitteredProjectionMatrix = _renderCamera . projectionMatrix ;
_renderCamera . nonJitteredProjectionMatrix = _renderCamera . projectionMatrix ;
@ -401,7 +407,8 @@ namespace FidelityFX
if ( autoGenerateReactiveMask )
if ( autoGenerateReactiveMask )
{
{
// The auto-reactive mask pass is executed separately from the main FSR2 passes
// The auto-reactive mask pass is executed separately from the main FSR2 passes
_dispatchCommandBuffer . GetTemporaryRT ( Fsr2ShaderIDs . UavAutoReactive , _renderSize . x , _renderSize . y , 0 , default , GraphicsFormat . R8_UNorm , 1 , true ) ;
var scaledRenderSize = GetScaledRenderSize ( ) ;
_dispatchCommandBuffer . GetTemporaryRT ( Fsr2ShaderIDs . UavAutoReactive , scaledRenderSize . x , scaledRenderSize . y , 0 , default , GraphicsFormat . R8_UNorm , 1 , true ) ;
_context . GenerateReactiveMask ( _genReactiveDescription , _dispatchCommandBuffer ) ;
_context . GenerateReactiveMask ( _genReactiveDescription , _dispatchCommandBuffer ) ;
_dispatchDescription . Reactive = Fsr2ShaderIDs . UavAutoReactive ;
_dispatchDescription . Reactive = Fsr2ShaderIDs . UavAutoReactive ;
}
}
@ -456,5 +463,18 @@ namespace FidelityFX
return new Vector2Int ( _renderCamera . pixelWidth , _renderCamera . pixelHeight ) ;
return new Vector2Int ( _renderCamera . pixelWidth , _renderCamera . pixelHeight ) ;
}
}
private bool UsingDynamicResolution ( )
{
return _renderCamera . allowDynamicResolution | | ( _originalRenderTarget ! = null & & _originalRenderTarget . useDynamicScale ) ;
}
private Vector2Int GetScaledRenderSize ( )
{
if ( UsingDynamicResolution ( ) )
return new Vector2Int ( Mathf . CeilToInt ( _maxRenderSize . x * ScalableBufferManager . widthScaleFactor ) , Mathf . CeilToInt ( _maxRenderSize . y * ScalableBufferManager . heightScaleFactor ) ) ;
return _maxRenderSize ;
}
}
}
}
}