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.
148 lines
4.6 KiB
148 lines
4.6 KiB
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using FidelityFX;
|
|
using UnityEngine;
|
|
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
|
|
{
|
|
[SerializeField]
|
|
private bool performSharpenPass = true;
|
|
|
|
[SerializeField, Range(0, 1)]
|
|
private float sharpness = 0.8f;
|
|
|
|
[HideInInspector]
|
|
public Camera gameCamera;
|
|
|
|
[HideInInspector]
|
|
public Camera outputCamera;
|
|
|
|
[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 RenderTexture _upscaleRT;
|
|
private RenderTexture _outputRT;
|
|
private Texture2D _exposure;
|
|
|
|
private Material _testMaterial;
|
|
private Material TestMaterial
|
|
{
|
|
get
|
|
{
|
|
if (_testMaterial == null)
|
|
{
|
|
var testShader = Fsr2.GlobalCallbacks.LoadShader("Shaders/FSRTest");
|
|
_testMaterial = new Material(testShader);
|
|
}
|
|
|
|
return _testMaterial;
|
|
}
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
_started = true;
|
|
OnEnable();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
// Delay OnEnable until we're sure all fields and properties are set
|
|
if (!_started)
|
|
return;
|
|
|
|
RenderPipelineManager.endContextRendering += OnEndContextRendering;
|
|
|
|
// TODO: destroy and recreate context on screen resolution and/or quality mode change
|
|
_context = Fsr2.CreateContext(DisplaySize, RenderSize);
|
|
|
|
_upscaleRT = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGBHalf);
|
|
_upscaleRT.Create();
|
|
|
|
_outputRT = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGBHalf);
|
|
_outputRT.enableRandomWrite = true;
|
|
_outputRT.Create();
|
|
|
|
_exposure = new Texture2D(1, 1);
|
|
_exposure.name = "FSR2 Exposure";
|
|
_exposure.SetPixel(0, 0, Color.white);
|
|
_exposure.Apply();
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
if (_exposure != null)
|
|
{
|
|
Destroy(_exposure);
|
|
_exposure = null;
|
|
}
|
|
|
|
if (_outputRT != null)
|
|
{
|
|
_outputRT.Release();
|
|
_outputRT = null;
|
|
}
|
|
|
|
if (_upscaleRT != null)
|
|
{
|
|
_upscaleRT.Release();
|
|
_upscaleRT = null;
|
|
}
|
|
|
|
if (_context != null)
|
|
{
|
|
_context.Destroy();
|
|
_context = null;
|
|
}
|
|
|
|
RenderPipelineManager.endContextRendering -= OnEndContextRendering;
|
|
}
|
|
|
|
// For scriptable rendering pipeline
|
|
private void OnEndContextRendering(ScriptableRenderContext context, List<Camera> cameras)
|
|
{
|
|
Debug.Log($"OnEndContentRendering, cameras = {string.Join(", ", cameras.Select(c => c.name))}");
|
|
}
|
|
|
|
// For legacy built-in render pipeline
|
|
private void OnRenderImage(RenderTexture src, RenderTexture dest)
|
|
{
|
|
// Do a dumb upscale first
|
|
Graphics.Blit(gameCamera.targetTexture, _upscaleRT, TestMaterial);
|
|
|
|
_dispatchDescription.Input = _upscaleRT;
|
|
_dispatchDescription.Output = _outputRT;
|
|
_dispatchDescription.Exposure = _exposure;
|
|
_dispatchDescription.PreExposure = 1.0f;
|
|
_dispatchDescription.EnableSharpening = performSharpenPass;
|
|
_dispatchDescription.Sharpness = sharpness;
|
|
_dispatchDescription.MotionVectorScale.x = gameCamera.pixelWidth;
|
|
_dispatchDescription.MotionVectorScale.y = gameCamera.pixelHeight;
|
|
_dispatchDescription.RenderSize = RenderSize;
|
|
_dispatchDescription.FrameTimeDelta = Time.unscaledDeltaTime;
|
|
_dispatchDescription.CameraNear = gameCamera.nearClipPlane;
|
|
_dispatchDescription.CameraFar = gameCamera.farClipPlane;
|
|
_dispatchDescription.CameraFovAngleVertical = gameCamera.fieldOfView * Mathf.Deg2Rad;
|
|
|
|
_context.Dispatch(_dispatchDescription);
|
|
|
|
// Output sharpened image to screen
|
|
Graphics.Blit(_outputRT, dest);
|
|
}
|
|
}
|