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 Fsr2.QualityMode qualityMode; [SerializeField] private bool enableJitter; private Fsr2Controller _fsr2Controller; private float _renderScale; private void OnEnable() { _renderScale = 1.0f / Fsr2.GetUpscaleRatioFromQualityMode(qualityMode); gameCamera = GetComponent(); 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(); outputCamera.eventMask = 0; _fsr2Controller = outputCameraObject.AddComponent(); _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() { 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; _fsr2Controller.SetJitterOffset(new Vector2(jitterX, jitterY)); } else { _fsr2Controller.SetJitterOffset(Vector2.zero); } } private void OnPostRender() { gameCamera.rect = _tempRect; gameCamera.ResetProjectionMatrix(); } }