@ -1,7 +1,5 @@
using System ;
using System.Collections ;
using System.Collections.Generic ;
using System.Linq ;
using FidelityFX ;
using UnityEngine ;
using UnityEngine.Experimental.Rendering ;
@ -24,10 +22,7 @@ public class Fsr2Controller : MonoBehaviour // TODO: rename this to Fsr2Disp
private bool reset ;
[HideInInspector]
public Camera gameCamera ;
[HideInInspector]
public Camera outputCamera ;
public Camera renderCamera ;
[HideInInspector]
public float renderScale ;
@ -39,25 +34,7 @@ public class Fsr2Controller : MonoBehaviour // TODO: rename this to Fsr2Disp
private Fsr2Context _context ;
private readonly Fsr2 . DispatchDescription _dispatchDescription = new Fsr2 . DispatchDescription ( ) ;
public Fsr2Context Context = > _context ;
private RenderTexture _upscaledOutput ;
private Material _copyMotionMat ;
private Material CopyMotionVectorsMaterial
{
get
{
if ( _copyMotionMat = = null )
{
var copyMotionShader = Fsr2 . GlobalCallbacks . LoadShader ( "Shaders/FSR2_CopyMotionVectors" ) ;
_copyMotionMat = new Material ( copyMotionShader ) ;
}
return _copyMotionMat ;
}
}
private CommandBuffer _commandBuffer ;
private void Start ( )
{
@ -72,19 +49,15 @@ public class Fsr2Controller : MonoBehaviour // TODO: rename this to Fsr2Disp
return ;
_context = Fsr2 . CreateContext ( DisplaySize , RenderSize , Fsr2 . InitializationFlags . EnableMotionVectorsJitterCancellation ) ;
// TODO: do we need a depth buffer for the output? We will need depth & motion vectors for subsequent post-FX. How should FSR2 output these?
// TODO: can probably be a temporary RT
_upscaledOutput = new RenderTexture ( DisplaySize . x , DisplaySize . y , 0 , RenderTextureFormat . ARGBHalf ) { name = "FSR2 Upscaled Output" , enableRandomWrite = true } ;
_upscaledOutput . Create ( ) ;
_commandBuffer = new CommandBuffer { name = "FSR2 Dispatch" } ;
}
private void OnDisable ( )
{
if ( _upscaledOutput ! = null )
if ( _commandBuffer ! = null )
{
_upscaledOutput . Release ( ) ;
_upscaledOutput = null ;
_commandBuffer . Release ( ) ;
_commandBuffer = null ;
}
if ( _context ! = null )
@ -102,28 +75,18 @@ public class Fsr2Controller : MonoBehaviour // TODO: rename this to Fsr2Disp
// For legacy built-in render pipeline
private void OnRenderImage ( RenderTexture src , RenderTexture dest )
{
var renderBuffer = gameCamera . targetTexture ;
var commandBuffer = new CommandBuffer { name = "FSR2 Main" } ;
// int motionVectorsId = Shader.PropertyToID("r_input_motion_vectors");
int upscaledOutputId = Shader . PropertyToID ( "rw_upscaled_output" ) ;
// I hate having to allocate extra RTs just to duplicate already existing Unity render buffers, but AFAIK there is no way to directly address motion vectors from code
// TODO: or can we? Look at RenderTargetIdentifier.MotionVectors with SetGlobalTexture!! (Possibly in gameCamera OnRenderImage)
// commandBuffer.GetTemporaryRT(motionVectorsId, renderBuffer.width, renderBuffer.height, 0, default, RenderTextureFormat.RGHalf);
// commandBuffer.Blit(renderBuffer, motionVectorsId, CopyMotionVectorsMaterial);
_commandBuffer . Clear ( ) ;
if ( dest ! = null )
{
// We have more image effects lined up after this, so FSR2 can output straight to the intermediate render texture
// TODO: we should probably use a shader to include depth & motion vectors into the output
commandBuffer . SetGlobalTexture ( upscaledOutputId , dest ) ;
_commandBuffer . SetGlobalTexture ( Fsr2Pipeline . UavUpscaledOutput , dest ) ;
}
else
{
// We are rendering to the backbuffer, so we need a temporary render texture for FSR2 to output to
commandBuffer . GetTemporaryRT ( upscaledOutputId , DisplaySize . x , DisplaySize . y , 0 , default , GraphicsFormat . R16G16B16A16_SFloat , 1 , true ) ;
_ commandBuffer. GetTemporaryRT ( Fsr2Pipeline . UavUpscaledOutput , DisplaySize . x , DisplaySize . y , 0 , default , GraphicsFormat . R16G16B16A16_SFloat , 1 , true ) ;
}
_dispatchDescription . Color = null ;
@ -135,31 +98,28 @@ public class Fsr2Controller : MonoBehaviour // TODO: rename this to Fsr2Disp
_dispatchDescription . PreExposure = 0 ;
_dispatchDescription . EnableSharpening = performSharpenPass ;
_dispatchDescription . Sharpness = sharpness ;
_dispatchDescription . MotionVectorScale . x = - game Camera. pixelWidth ;
_dispatchDescription . MotionVectorScale . y = - game Camera. pixelHeight ;
_dispatchDescription . MotionVectorScale . x = - render Camera. pixelWidth ;
_dispatchDescription . MotionVectorScale . y = - render Camera. pixelHeight ;
_dispatchDescription . RenderSize = RenderSize ;
_dispatchDescription . FrameTimeDelta = Time . unscaledDeltaTime ;
_dispatchDescription . CameraNear = game Camera. nearClipPlane ;
_dispatchDescription . CameraFar = game Camera. farClipPlane ;
_dispatchDescription . CameraFovAngleVertical = game Camera. fieldOfView * Mathf . Deg2Rad ;
_dispatchDescription . CameraNear = render Camera. nearClipPlane ;
_dispatchDescription . CameraFar = render Camera. farClipPlane ;
_dispatchDescription . CameraFovAngleVertical = render Camera. fieldOfView * Mathf . Deg2Rad ;
_dispatchDescription . ViewSpaceToMetersFactor = 1.0f ; // 1 unit is 1 meter in Unity
_dispatchDescription . Reset = reset ;
reset = false ;
_context . Dispatch ( _dispatchDescription , commandBuffer ) ;
_context . Dispatch ( _dispatchDescription , _ commandBuffer) ;
// Output upscaled image to screen
// TODO: if `dest` is null, we likely don't care about the depth & motion vectors anymore
if ( dest = = null )
{
commandBuffer . Blit ( upscaledOutputId , dest ) ;
commandBuffer . ReleaseTemporaryRT ( upscaledOutputId ) ;
_ commandBuffer. Blit ( Fsr2Pipeline . UavUpscaledOutput , dest ) ;
_ commandBuffer. ReleaseTemporaryRT ( Fsr2Pipeline . UavUpscaledOutput ) ;
}
// commandBuffer.ReleaseTemporaryRT(motionVectorsId);
Graphics . ExecuteCommandBuffer ( commandBuffer ) ;
commandBuffer . Release ( ) ;
Graphics . ExecuteCommandBuffer ( _commandBuffer ) ;
// Shut up the Unity warning about not writing to the destination texture
Graphics . SetRenderTarget ( dest ) ;