diff --git a/Assets/Scripts/Fsr2Controller.cs b/Assets/Scripts/Fsr2Controller.cs
index c0a8b58..f817239 100644
--- a/Assets/Scripts/Fsr2Controller.cs
+++ b/Assets/Scripts/Fsr2Controller.cs
@@ -1,127 +1,145 @@
using System.Collections;
-using System.Collections.Generic;
using FidelityFX;
using UnityEngine;
-using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
-///
-/// 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.
-///
-public class Fsr2Controller : MonoBehaviour // TODO: rename this to Fsr2Dispatcher and move most of the functionality to Fsr2Controller (now SubsampleTest)
+[RequireComponent(typeof(Camera))]
+public class Fsr2Controller : MonoBehaviour
{
- [SerializeField]
- private bool performSharpenPass = true;
+ [SerializeField]
+ private Fsr2.QualityMode qualityMode;
+
+ private Camera _renderCamera;
+ private RenderTexture _originalRenderTarget;
- [SerializeField, Range(0, 1)]
- private float sharpness = 0.8f;
+ private GameObject _displayCameraObject;
+ private Camera _displayCamera;
+ private Fsr2Dispatcher _dispatcher;
- [SerializeField]
- private bool reset;
+ private Fsr2.QualityMode _prevQualityMode;
+ private Vector2Int _prevScreenSize;
+
+ private CommandBuffer _opaqueOnlyCommandBuffer;
+ private CommandBuffer _inputsCommandBuffer;
- [HideInInspector]
- public Camera renderCamera;
+ private void OnEnable()
+ {
+ _renderCamera = GetComponent();
+ if (_displayCameraObject == null)
+ {
+ _displayCameraObject = new GameObject("FSR2 Camera Object");
+ _displayCameraObject.transform.SetParent(transform);
+ _displayCameraObject.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
+ //outputCameraObject.transform.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
- [HideInInspector]
- public float renderScale;
+ // Create a camera that does nothing except output the upscaled image
+ _displayCamera = _displayCameraObject.AddComponent();
+ _displayCamera.backgroundColor = Color.clear;
+ _displayCamera.clearFlags = CameraClearFlags.Nothing;
+ _displayCamera.eventMask = 0;
+ _displayCamera.cullingMask = 0;
+ _displayCamera.useOcclusionCulling = false;
+ _displayCamera.orthographic = true;
+ _displayCamera.allowMSAA = false;
+ _displayCamera.renderingPath = RenderingPath.Forward;
- 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));
+ _dispatcher = _displayCameraObject.AddComponent();
+ }
+
+ _dispatcher.renderCamera = _renderCamera;
+ _dispatcher.renderScale = 1.0f / Fsr2.GetUpscaleRatioFromQualityMode(qualityMode);
+ _dispatcher.enabled = true;
- private Fsr2Context _context;
- private readonly Fsr2.DispatchDescription _dispatchDescription = new Fsr2.DispatchDescription();
- private CommandBuffer _commandBuffer;
+ Fsr2.GetRenderResolutionFromQualityMode(out var renderWidth, out var renderHeight, Screen.width, Screen.height, qualityMode);
+
+ _originalRenderTarget = _renderCamera.targetTexture; // TODO: if this isn't null, could maybe reuse this for the output texture?
- private void Start()
- {
- _started = true;
- OnEnable();
- }
+ _renderCamera.targetTexture = new RenderTexture(
+ renderWidth, renderHeight,
+ _originalRenderTarget != null ? _originalRenderTarget.depth : 32,
+ _originalRenderTarget != null ? _originalRenderTarget.format : RenderTextureFormat.ARGBHalf) { name = "FSR2 Input Texture" };
+
+ _renderCamera.targetTexture.Create();
- private void OnEnable()
- {
- // Delay OnEnable until we're sure all fields and properties are set
- if (!_started)
- return;
+ _renderCamera.depthTextureMode |= DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
+
+ _opaqueOnlyCommandBuffer = new CommandBuffer { name = "FSR2 Opaque Input" };
+ // TODO: may need to copy the opaque-only render buffer to a temp RT here, in which case we'll need an additional CommandBuffer to release the temp RT again
+ _opaqueOnlyCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvOpaqueOnly, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color);
+ _renderCamera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, _opaqueOnlyCommandBuffer);
+
+ _inputsCommandBuffer = new CommandBuffer { name = "FSR2 Inputs" };
+ _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputColor, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color);
+ _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputDepth, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth);
+ _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputMotionVectors, BuiltinRenderTextureType.MotionVectors);
+ _renderCamera.AddCommandBuffer(CameraEvent.BeforeImageEffects, _inputsCommandBuffer);
- _context = Fsr2.CreateContext(DisplaySize, RenderSize, Fsr2.InitializationFlags.EnableMotionVectorsJitterCancellation);
- _commandBuffer = new CommandBuffer { name = "FSR2 Dispatch" };
+ // 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(renderWidth, Screen.width);
+ Fsr2.GlobalCallbacks.ApplyMipmapBias(biasOffset);
+
+ _prevScreenSize = new Vector2Int(Screen.width, Screen.height);
+ _prevQualityMode = qualityMode;
}
private void OnDisable()
{
- if (_commandBuffer != null)
- {
- _commandBuffer.Release();
- _commandBuffer = null;
- }
+ float biasOffset = Fsr2.GetMipmapBiasOffset(_renderCamera.targetTexture.width, _prevScreenSize.x);
+ Fsr2.GlobalCallbacks.ApplyMipmapBias(-biasOffset);
- if (_context != null)
- {
- _context.Destroy();
- _context = null;
- }
- }
+ _renderCamera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, _opaqueOnlyCommandBuffer);
+ _opaqueOnlyCommandBuffer.Release();
+ _opaqueOnlyCommandBuffer = null;
+
+ _renderCamera.RemoveCommandBuffer(CameraEvent.BeforeImageEffects, _inputsCommandBuffer);
+ _inputsCommandBuffer.Release();
+ _inputsCommandBuffer = null;
- public void SetJitterOffset(Vector2 jitterOffset)
- {
- _dispatchDescription.JitterOffset = jitterOffset;
+ _renderCamera.targetTexture.Release();
+ _renderCamera.targetTexture = _originalRenderTarget;
+
+ _dispatcher.enabled = false;
+ _displayCamera.enabled = false;
}
- // For legacy built-in render pipeline
- private void OnRenderImage(RenderTexture src, RenderTexture dest)
+ private void Update()
{
- _commandBuffer.Clear();
+ _displayCamera.enabled = _renderCamera.enabled;
- 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)
+ if (Screen.width != _prevScreenSize.x || Screen.height != _prevScreenSize.y || qualityMode != _prevQualityMode)
{
- _commandBuffer.Blit(Fsr2Pipeline.UavUpscaledOutput, dest);
- _commandBuffer.ReleaseTemporaryRT(Fsr2Pipeline.UavUpscaledOutput);
+ // Force all resources to be destroyed and recreated with the new settings
+ OnDisable();
+ OnEnable();
}
+ }
+
+ private Rect _tempRect;
+
+ private void OnPreRender()
+ {
+ _tempRect = _renderCamera.rect;
+ _renderCamera.aspect = (Screen.width * _tempRect.width) / (Screen.height * _tempRect.height);
+ _renderCamera.rect = new Rect(0, 0, 1, 1);
- Graphics.ExecuteCommandBuffer(_commandBuffer);
+ // Perform custom jittering of the camera's projection matrix according to FSR2's instructions
+ int jitterPhaseCount = Fsr2.GetJitterPhaseCount(_renderCamera.targetTexture.width, Screen.width);
+ Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount);
- // Shut up the Unity warning about not writing to the destination texture
- Graphics.SetRenderTarget(dest);
+ _dispatcher.SetJitterOffset(new Vector2(jitterX, jitterY));
+
+ var targetTexture = _renderCamera.targetTexture;
+ jitterX = 2.0f * jitterX / targetTexture.width;
+ jitterY = 2.0f * jitterY / targetTexture.height;
+
+ var jitterTranslationMatrix = Matrix4x4.Translate(new Vector3(jitterX, jitterY, 0));
+ _renderCamera.projectionMatrix = jitterTranslationMatrix * _renderCamera.nonJitteredProjectionMatrix;
+ }
+
+ private void OnPostRender()
+ {
+ _renderCamera.rect = _tempRect;
+ _renderCamera.ResetProjectionMatrix();
}
}
diff --git a/Assets/Scripts/Fsr2Controller.cs.meta b/Assets/Scripts/Fsr2Controller.cs.meta
index f9c76b6..229652b 100644
--- a/Assets/Scripts/Fsr2Controller.cs.meta
+++ b/Assets/Scripts/Fsr2Controller.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: d59d37e0744f1344e95cf689136fc9d9
+guid: 955cb66a9ecc20441a7e32934c9b4690
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/Scripts/Fsr2Dispatcher.cs b/Assets/Scripts/Fsr2Dispatcher.cs
new file mode 100644
index 0000000..d1cc161
--- /dev/null
+++ b/Assets/Scripts/Fsr2Dispatcher.cs
@@ -0,0 +1,127 @@
+using System.Collections;
+using System.Collections.Generic;
+using FidelityFX;
+using UnityEngine;
+using UnityEngine.Experimental.Rendering;
+using UnityEngine.Rendering;
+
+///
+/// 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.
+///
+public class Fsr2Dispatcher : 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);
+ }
+}
diff --git a/Assets/Scripts/SubsampleTest.cs.meta b/Assets/Scripts/Fsr2Dispatcher.cs.meta
similarity index 83%
rename from Assets/Scripts/SubsampleTest.cs.meta
rename to Assets/Scripts/Fsr2Dispatcher.cs.meta
index 229652b..f9c76b6 100644
--- a/Assets/Scripts/SubsampleTest.cs.meta
+++ b/Assets/Scripts/Fsr2Dispatcher.cs.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: 955cb66a9ecc20441a7e32934c9b4690
+guid: d59d37e0744f1344e95cf689136fc9d9
MonoImporter:
externalObjects: {}
serializedVersion: 2
diff --git a/Assets/Scripts/SubsampleTest.cs b/Assets/Scripts/SubsampleTest.cs
deleted file mode 100644
index 4fbcd51..0000000
--- a/Assets/Scripts/SubsampleTest.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-using System.Collections;
-using FidelityFX;
-using UnityEngine;
-using UnityEngine.Rendering;
-
-[RequireComponent(typeof(Camera))]
-public class SubsampleTest : MonoBehaviour // TODO: rename this to Fsr2Controller
-{
- [SerializeField]
- private Fsr2.QualityMode qualityMode;
-
- private Camera _renderCamera;
- private RenderTexture _originalRenderTarget;
-
- private GameObject _displayCameraObject;
- private Camera _displayCamera;
-
- private Fsr2Controller _fsr2Controller;
-
- private Fsr2.QualityMode _prevQualityMode;
- private Vector2Int _prevScreenSize;
-
- private CommandBuffer _opaqueOnlyCommandBuffer;
- private CommandBuffer _inputsCommandBuffer;
-
- private void OnEnable()
- {
- _renderCamera = GetComponent();
- if (_displayCameraObject == null)
- {
- _displayCameraObject = new GameObject("FSR2 Camera Object");
- _displayCameraObject.transform.SetParent(transform);
- _displayCameraObject.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
- //outputCameraObject.transform.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector;
-
- // Create a camera that does nothing except output the upscaled image
- _displayCamera = _displayCameraObject.AddComponent();
- _displayCamera.backgroundColor = Color.clear;
- _displayCamera.clearFlags = CameraClearFlags.Nothing;
- _displayCamera.eventMask = 0;
- _displayCamera.cullingMask = 0;
- _displayCamera.useOcclusionCulling = false;
- _displayCamera.orthographic = true;
- _displayCamera.allowMSAA = false;
- _displayCamera.renderingPath = RenderingPath.Forward;
-
- _fsr2Controller = _displayCameraObject.AddComponent();
- }
-
- _fsr2Controller.renderCamera = _renderCamera;
- _fsr2Controller.renderScale = 1.0f / Fsr2.GetUpscaleRatioFromQualityMode(qualityMode);
- _fsr2Controller.enabled = true;
-
- Fsr2.GetRenderResolutionFromQualityMode(out var renderWidth, out var renderHeight, Screen.width, Screen.height, qualityMode);
-
- _originalRenderTarget = _renderCamera.targetTexture; // TODO: if this isn't null, could maybe reuse this for the output texture?
-
- _renderCamera.targetTexture = new RenderTexture(
- renderWidth, renderHeight,
- _originalRenderTarget != null ? _originalRenderTarget.depth : 32,
- _originalRenderTarget != null ? _originalRenderTarget.format : RenderTextureFormat.ARGBHalf) { name = "FSR2 Input Texture" };
-
- _renderCamera.targetTexture.Create();
-
- _renderCamera.depthTextureMode |= DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
-
- _opaqueOnlyCommandBuffer = new CommandBuffer { name = "FSR2 Opaque Input" };
- // TODO: may need to copy the opaque-only render buffer to a temp RT here, in which case we'll need an additional CommandBuffer to release the temp RT again
- _opaqueOnlyCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvOpaqueOnly, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color);
- _renderCamera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, _opaqueOnlyCommandBuffer);
-
- _inputsCommandBuffer = new CommandBuffer { name = "FSR2 Inputs" };
- _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputColor, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Color);
- _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputDepth, BuiltinRenderTextureType.CameraTarget, RenderTextureSubElement.Depth);
- _inputsCommandBuffer.SetGlobalTexture(Fsr2Pipeline.SrvInputMotionVectors, BuiltinRenderTextureType.MotionVectors);
- _renderCamera.AddCommandBuffer(CameraEvent.BeforeImageEffects, _inputsCommandBuffer);
-
- // 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(renderWidth, Screen.width);
- Fsr2.GlobalCallbacks.ApplyMipmapBias(biasOffset);
-
- _prevScreenSize = new Vector2Int(Screen.width, Screen.height);
- _prevQualityMode = qualityMode;
- }
-
- private void OnDisable()
- {
- float biasOffset = Fsr2.GetMipmapBiasOffset(_renderCamera.targetTexture.width, _prevScreenSize.x);
- Fsr2.GlobalCallbacks.ApplyMipmapBias(-biasOffset);
-
- _renderCamera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, _opaqueOnlyCommandBuffer);
- _opaqueOnlyCommandBuffer.Release();
- _opaqueOnlyCommandBuffer = null;
-
- _renderCamera.RemoveCommandBuffer(CameraEvent.BeforeImageEffects, _inputsCommandBuffer);
- _inputsCommandBuffer.Release();
- _inputsCommandBuffer = null;
-
- _renderCamera.targetTexture.Release();
- _renderCamera.targetTexture = _originalRenderTarget;
-
- _fsr2Controller.enabled = false;
- _displayCamera.enabled = false;
- }
-
- private void Update()
- {
- _displayCamera.enabled = _renderCamera.enabled;
-
- if (Screen.width != _prevScreenSize.x || Screen.height != _prevScreenSize.y || qualityMode != _prevQualityMode)
- {
- // Force all resources to be destroyed and recreated with the new settings
- OnDisable();
- OnEnable();
- }
- }
-
- private Rect _tempRect;
-
- private void OnPreRender()
- {
- _tempRect = _renderCamera.rect;
- _renderCamera.aspect = (Screen.width * _tempRect.width) / (Screen.height * _tempRect.height);
- _renderCamera.rect = new Rect(0, 0, 1, 1);
-
- // Perform custom jittering of the camera's projection matrix according to FSR2's instructions
- int jitterPhaseCount = Fsr2.GetJitterPhaseCount(_renderCamera.targetTexture.width, Screen.width);
- Fsr2.GetJitterOffset(out float jitterX, out float jitterY, Time.frameCount, jitterPhaseCount);
-
- _fsr2Controller.SetJitterOffset(new Vector2(jitterX, jitterY));
-
- var targetTexture = _renderCamera.targetTexture;
- jitterX = 2.0f * jitterX / targetTexture.width;
- jitterY = 2.0f * jitterY / targetTexture.height;
-
- var jitterTranslationMatrix = Matrix4x4.Translate(new Vector3(jitterX, jitterY, 0));
- _renderCamera.projectionMatrix = jitterTranslationMatrix * _renderCamera.nonJitteredProjectionMatrix;
- }
-
- private void OnPostRender()
- {
- _renderCamera.rect = _tempRect;
- _renderCamera.ResetProjectionMatrix();
- }
-}