FSR2 tests in Unity based on built-in render pipeline
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

127 lines
4.7 KiB

using System.Collections;
using System.Collections.Generic;
using FidelityFX;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
/// <summary>
/// This class is responsible for hooking into various Unity events and translating them to the FSR2 subsystem.
/// This includes creation and destruction of the FSR2 context, as well as dispatching commands at the right time.
/// This class also exposes various FSR2 parameters to the Unity inspector.
/// </summary>
public class Fsr2Controller : MonoBehaviour // TODO: rename this to Fsr2Dispatcher and move most of the functionality to Fsr2Controller (now SubsampleTest)
{
[SerializeField]
private bool performSharpenPass = true;
[SerializeField, Range(0, 1)]
private float sharpness = 0.8f;
[SerializeField]
private bool reset;
[HideInInspector]
public Camera renderCamera;
[HideInInspector]
public float renderScale;
private bool _started;
private Vector2Int DisplaySize => new Vector2Int(Screen.width, Screen.height);
private Vector2Int RenderSize => new Vector2Int(Mathf.FloorToInt(Screen.width * renderScale), Mathf.FloorToInt(Screen.height * renderScale));
private Fsr2Context _context;
private readonly Fsr2.DispatchDescription _dispatchDescription = new Fsr2.DispatchDescription();
private CommandBuffer _commandBuffer;
private void Start()
{
_started = true;
OnEnable();
}
private void OnEnable()
{
// Delay OnEnable until we're sure all fields and properties are set
if (!_started)
return;
_context = Fsr2.CreateContext(DisplaySize, RenderSize, Fsr2.InitializationFlags.EnableMotionVectorsJitterCancellation);
_commandBuffer = new CommandBuffer { name = "FSR2 Dispatch" };
}
private void OnDisable()
{
if (_commandBuffer != null)
{
_commandBuffer.Release();
_commandBuffer = null;
}
if (_context != null)
{
_context.Destroy();
_context = null;
}
}
public void SetJitterOffset(Vector2 jitterOffset)
{
_dispatchDescription.JitterOffset = jitterOffset;
}
// For legacy built-in render pipeline
private void OnRenderImage(RenderTexture src, RenderTexture dest)
{
_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(Fsr2Pipeline.UavUpscaledOutput, dest);
}
else
{
// We are rendering to the backbuffer, so we need a temporary render texture for FSR2 to output to
_commandBuffer.GetTemporaryRT(Fsr2Pipeline.UavUpscaledOutput, DisplaySize.x, DisplaySize.y, 0, default, GraphicsFormat.R16G16B16A16_SFloat, 1, true);
}
_dispatchDescription.Color = null;
_dispatchDescription.Depth = null;
_dispatchDescription.MotionVectors = null;
_dispatchDescription.Output = null;
_dispatchDescription.Exposure = null;
_dispatchDescription.Reactive = null;
_dispatchDescription.PreExposure = 0;
_dispatchDescription.EnableSharpening = performSharpenPass;
_dispatchDescription.Sharpness = sharpness;
_dispatchDescription.MotionVectorScale.x = -renderCamera.pixelWidth;
_dispatchDescription.MotionVectorScale.y = -renderCamera.pixelHeight;
_dispatchDescription.RenderSize = RenderSize;
_dispatchDescription.FrameTimeDelta = Time.unscaledDeltaTime;
_dispatchDescription.CameraNear = renderCamera.nearClipPlane;
_dispatchDescription.CameraFar = renderCamera.farClipPlane;
_dispatchDescription.CameraFovAngleVertical = renderCamera.fieldOfView * Mathf.Deg2Rad;
_dispatchDescription.ViewSpaceToMetersFactor = 1.0f; // 1 unit is 1 meter in Unity
_dispatchDescription.Reset = reset;
reset = false;
_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(Fsr2Pipeline.UavUpscaledOutput, dest);
_commandBuffer.ReleaseTemporaryRT(Fsr2Pipeline.UavUpscaledOutput);
}
Graphics.ExecuteCommandBuffer(_commandBuffer);
// Shut up the Unity warning about not writing to the destination texture
Graphics.SetRenderTarget(dest);
}
}