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.4 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using FidelityFX;
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class SubsampleTest : MonoBehaviour
{
private Camera gameCamera;
private GameObject outputCameraObject;
private Camera outputCamera;
[SerializeField]
private float renderScale = 0.5f;
[SerializeField]
private bool enableJitter;
private Fsr2Controller _fsr2Controller;
private void OnEnable()
{
gameCamera = GetComponent<Camera>();
if (outputCameraObject == null)
{
outputCameraObject = new GameObject("FSR2 Camera Object");
outputCameraObject.transform.SetParent(transform);
outputCameraObject.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
//outputCameraObject.transform.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
outputCamera = outputCameraObject.AddComponent<Camera>();
outputCamera.eventMask = 0;
_fsr2Controller = outputCameraObject.AddComponent<Fsr2Controller>();
_fsr2Controller.gameCamera = gameCamera;
_fsr2Controller.outputCamera = outputCamera;
_fsr2Controller.renderScale = renderScale;
_fsr2Controller.enabled = true;
//outputCamera.CopyFrom(gameCamera);
outputCamera.cullingMask = 0;
outputCamera.clearFlags = CameraClearFlags.Nothing;
}
else
{
_fsr2Controller.enabled = true;
}
gameCamera.targetTexture = new RenderTexture(
(int)(Screen.width * renderScale), (int)(Screen.height * renderScale),
24, // Can we copy depth value from original camera?
RenderTextureFormat.ARGBHalf); // Can we copy format from original camera? Or renderer quality settings?
gameCamera.depthTextureMode = DepthTextureMode.Depth | DepthTextureMode.DepthNormals | DepthTextureMode.MotionVectors;
gameCamera.targetTexture.name = "FSR2 Source Texture";
gameCamera.targetTexture.Create();
// Adjust texture mipmap LOD bias by log2(renderResolution/displayResolution) - 1.0;
// May need to leave this to the game dev, as we don't know which textures do and don't belong to the 3D scene
float biasOffset = GetMipmapBiasOffset();
Fsr2.GlobalCallbacks.ApplyMipmapBias(biasOffset);
}
private void OnDisable()
{
float biasOffset = GetMipmapBiasOffset();
Fsr2.GlobalCallbacks.ApplyMipmapBias(-biasOffset);
gameCamera.targetTexture.Release();
gameCamera.targetTexture = null;
_fsr2Controller.enabled = false;
outputCamera.enabled = false;
}
public float GetMipmapBiasOffset()
{
return Mathf.Log(renderScale) - 1.0f;
}
private void Update()
{
outputCamera.enabled = gameCamera.enabled;
//outputCamera.CopyFrom(gameCamera);
outputCamera.clearFlags = CameraClearFlags.Color;
}
private Rect tempRect;
private void OnPreRender()
{
gameCamera.aspect = (Screen.width * gameCamera.rect.width) / (Screen.height * gameCamera.rect.height);
tempRect = gameCamera.rect;
gameCamera.rect = new Rect(0, 0, 1, 1);
if (enableJitter)
{
// Perform custom jittering of the camera's projection matrix according to FSR2's instructions
// Unity already does jittering behind the scenes for certain post-effects, so can we perhaps integrate with that?
int jitterPhaseCount = Fsr2.GetJitterPhaseCount(gameCamera.targetTexture.width, Screen.width);
Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount);
jitterX = 2.0f * jitterX / gameCamera.targetTexture.width;
jitterY = -2.0f * jitterY / gameCamera.targetTexture.height;
var jitterTranslationMatrix = Matrix4x4.Translate(new Vector3(jitterX, jitterY, 0));
gameCamera.projectionMatrix = jitterTranslationMatrix * gameCamera.nonJitteredProjectionMatrix;
}
}
private void OnRenderImage(RenderTexture src, RenderTexture dest)
{
_fsr2Controller.UpdateInputResources(src);
}
private void OnPostRender()
{
gameCamera.rect = tempRect;
gameCamera.ResetProjectionMatrix();
}
}