using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; public class FSR2Thing : MonoBehaviour { [SerializeField] private bool performSharpenPass = true; [HideInInspector] public Camera gameCamera; [HideInInspector] public Camera outputCamera; [HideInInspector] public float renderScale; private RenderTexture _upscaleRT; private RenderTexture _rcasOutput; private Material _testMaterial; private Material TestMaterial { get { if (_testMaterial == null) { var testShader = Shader.Find("FSR2/FSRTest"); _testMaterial = new Material(testShader); } return _testMaterial; } } private ComputeShader _rcasComputeShader; private ComputeShader RCASComputeShader { get { if (_rcasComputeShader == null) { // TODO: this is nasty, I don't like this. How do we manage/bind compute shaders best? // GPUInstancer used Resources, we modified that to load stuff from asset bundles instead. Maybe provide a custom loader callback interface? _rcasComputeShader = Resources.Load("Shaders/ffx_fsr2_rcas_pass"); } return _rcasComputeShader; } } private void OnEnable() { RenderPipelineManager.endContextRendering += OnEndContextRendering; _upscaleRT = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGBHalf); _upscaleRT.Create(); _rcasOutput = new RenderTexture(Screen.width, Screen.height, 24, RenderTextureFormat.ARGBHalf); _rcasOutput.enableRandomWrite = true; _rcasOutput.Create(); } private void OnDisable() { _rcasOutput.Release(); _upscaleRT.Release(); RenderPipelineManager.endContextRendering -= OnEndContextRendering; } // For scriptable rendering pipeline private void OnEndContextRendering(ScriptableRenderContext context, List 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); if (performSharpenPass) { // Run the RCAS sharpening filter on the upscaled image int rcasKernel = RCASComputeShader.FindKernel("CS"); RCASComputeShader.SetTexture(rcasKernel, "r_rcas_input", _upscaleRT); RCASComputeShader.SetTexture(rcasKernel, "rw_upscaled_output", _rcasOutput); RCASComputeShader.Dispatch(rcasKernel, Screen.width, Screen.height, 1); // TODO: not sure how these thread groups work... // Output sharpened image to screen Graphics.Blit(_rcasOutput, dest); } else { Graphics.Blit(_upscaleRT, dest); } } }