// Copyright (c) 2024 Nico de Poel // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. using UnityEngine; namespace FidelityFX.FrameInterpolation { /// /// Scriptable object containing all shader resources required by FidelityFX Frame Interpolation. /// These can be stored in an asset file and referenced from a scene or prefab, avoiding the need to load the shaders from a Resources folder. /// [CreateAssetMenu(fileName = "Frame Interpolation Assets", menuName = "FidelityFX/Frame Interpolation Assets", order = 1112)] public class FrameInterpolationAssets : ScriptableObject { public FrameInterpolationShaders shaders; #if UNITY_EDITOR private void Reset() { shaders = new FrameInterpolationShaders { reconstructAndDilate = FindComputeShader("ffx_frameinterpolation_reconstruct_and_dilate_pass"), setup = FindComputeShader("ffx_frameinterpolation_setup_pass"), reconstructPreviousDepth = FindComputeShader("ffx_frameinterpolation_reconstruct_previous_depth_pass"), gameMotionVectorField = FindComputeShader("ffx_frameinterpolation_game_motion_vector_field_pass"), opticalFlowVectorField = FindComputeShader("ffx_frameinterpolation_optical_flow_vector_field_pass"), disocclusionMask = FindComputeShader("ffx_frameinterpolation_disocclusion_mask_pass"), interpolation = FindComputeShader("ffx_frameinterpolation_pass"), inpaintingPyramid = FindComputeShader("ffx_frameinterpolation_compute_inpainting_pyramid_pass"), inpainting = FindComputeShader("ffx_frameinterpolation_inpainting_pass"), gameVectorFieldInpaintingPyramid = FindComputeShader("ffx_frameinterpolation_compute_game_vector_field_inpainting_pyramid_pass"), debugView = FindComputeShader("ffx_frameinterpolation_debug_view_pass"), }; } private static ComputeShader FindComputeShader(string name) { string[] assetGuids = UnityEditor.AssetDatabase.FindAssets($"t:ComputeShader {name}"); if (assetGuids == null || assetGuids.Length == 0) return null; string assetPath = UnityEditor.AssetDatabase.GUIDToAssetPath(assetGuids[0]); return UnityEditor.AssetDatabase.LoadAssetAtPath(assetPath); } #endif } /// /// All the compute shaders used by Frame Interpolation. /// [System.Serializable] public class FrameInterpolationShaders { /// /// The compute shader used by the reconstruct and dilate pass. /// public ComputeShader reconstructAndDilate; /// /// The compute shader used by the setup pass. /// public ComputeShader setup; /// /// The compute shader used by the reconstruct previous depth pass. /// public ComputeShader reconstructPreviousDepth; /// /// The compute shader used by the game motion vector field pass. /// public ComputeShader gameMotionVectorField; /// /// The compute shader used by the optical flow vector field pass. /// public ComputeShader opticalFlowVectorField; /// /// The compute shader used by the disocclusion mask pass. /// public ComputeShader disocclusionMask; /// /// The compute shader used by the interpolation pass. /// public ComputeShader interpolation; /// /// The compute shader used by the inpainting pyramid pass. /// public ComputeShader inpaintingPyramid; /// /// The compute shader used by the inpainting pass. /// public ComputeShader inpainting; /// /// The compute shader used by the game vector field inpainting pyramid pass. /// public ComputeShader gameVectorFieldInpaintingPyramid; /// /// The compute shader used by the debug view pass. /// public ComputeShader debugView; /// /// Returns a copy of this class and its contents. /// public FrameInterpolationShaders Clone() { return (FrameInterpolationShaders)MemberwiseClone(); } /// /// Returns a copy of this class with clones of all its shaders. /// This can be useful if you're running multiple Frame Interpolation instances with different shader configurations. /// Be sure to clean up these clones through Dispose once you're done with them. /// public FrameInterpolationShaders DeepCopy() { return new FrameInterpolationShaders { reconstructAndDilate = Object.Instantiate(reconstructAndDilate), setup = Object.Instantiate(setup), reconstructPreviousDepth = Object.Instantiate(reconstructPreviousDepth), gameMotionVectorField = Object.Instantiate(gameMotionVectorField), opticalFlowVectorField = Object.Instantiate(opticalFlowVectorField), disocclusionMask = Object.Instantiate(disocclusionMask), interpolation = Object.Instantiate(interpolation), inpaintingPyramid = Object.Instantiate(inpaintingPyramid), inpainting = Object.Instantiate(inpainting), gameVectorFieldInpaintingPyramid = Object.Instantiate(gameVectorFieldInpaintingPyramid), debugView = Object.Instantiate(debugView), }; } /// /// Destroy all the shaders within this instance. /// Use this only on clones created through DeepCopy. /// public void Dispose() { Object.Destroy(debugView); Object.Destroy(gameVectorFieldInpaintingPyramid); Object.Destroy(inpainting); Object.Destroy(inpaintingPyramid); Object.Destroy(interpolation); Object.Destroy(disocclusionMask); Object.Destroy(opticalFlowVectorField); Object.Destroy(gameMotionVectorField); Object.Destroy(reconstructPreviousDepth); Object.Destroy(setup); Object.Destroy(reconstructAndDilate); } } }