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.
 
 
 
 

136 lines
4.9 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using FidelityFX;
using UnityEngine;
[RequireComponent(typeof(Camera))]
public class SubsampleTest : MonoBehaviour
{
private Camera gameCamera;
private GameObject outputCameraObject;
private Camera outputCamera;
[SerializeField]
private Fsr2.QualityMode qualityMode;
[SerializeField]
private bool enableJitter;
private Fsr2Controller _fsr2Controller;
private float _renderScale;
private void OnEnable()
{
_renderScale = 1.0f / Fsr2.GetUpscaleRatioFromQualityMode(qualityMode);
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;
}
Fsr2.GetRenderResolutionFromQualityMode(out var renderWidth, out var renderHeight, Screen.width, Screen.height, qualityMode);
gameCamera.targetTexture = new RenderTexture(
renderWidth, renderHeight,
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 = Fsr2.GetMipmapBiasOffset(_renderScale);
Fsr2.GlobalCallbacks.ApplyMipmapBias(biasOffset);
}
private void OnDisable()
{
float biasOffset = Fsr2.GetMipmapBiasOffset(_renderScale);
Fsr2.GlobalCallbacks.ApplyMipmapBias(-biasOffset);
gameCamera.targetTexture.Release();
gameCamera.targetTexture = null;
_fsr2Controller.enabled = false;
outputCamera.enabled = false;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.F12))
{
string path = Path.Combine(Directory.GetCurrentDirectory(), $"screenshot-{DateTime.Now:yyyyMMdd-HHmmss}.png");
ScreenCapture.CaptureScreenshot(path);
Debug.Log($"Screenshot saved to: {path}");
}
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);
_fsr2Controller.SetJitterOffset(new Vector2(jitterX, jitterY));
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;
}
else
{
_fsr2Controller.SetJitterOffset(Vector2.zero);
}
}
private void OnPostRender()
{
gameCamera.rect = _tempRect;
gameCamera.ResetProjectionMatrix();
}
}