diff --git a/Runtime/FrameInterpolation.meta b/Runtime/FrameInterpolation.meta new file mode 100644 index 0000000..037845b --- /dev/null +++ b/Runtime/FrameInterpolation.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: bd29728b817dd3f478a426dcb34e360b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/FrameInterpolation/FrameInterpolationAssets.cs b/Runtime/FrameInterpolation/FrameInterpolationAssets.cs new file mode 100644 index 0000000..85761d4 --- /dev/null +++ b/Runtime/FrameInterpolation/FrameInterpolationAssets.cs @@ -0,0 +1,176 @@ +// 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); + } + } +} diff --git a/Runtime/FrameInterpolation/FrameInterpolationAssets.cs.meta b/Runtime/FrameInterpolation/FrameInterpolationAssets.cs.meta new file mode 100644 index 0000000..080d2d8 --- /dev/null +++ b/Runtime/FrameInterpolation/FrameInterpolationAssets.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1f0e52bd03044d74f8e7ea17af3c8d7b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/OpticalFlow.meta b/Runtime/OpticalFlow.meta new file mode 100644 index 0000000..22fc45e --- /dev/null +++ b/Runtime/OpticalFlow.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 52b9ee437d2c45248a5410ed4160929e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Runtime/OpticalFlow/OpticalFlowAssets.cs b/Runtime/OpticalFlow/OpticalFlowAssets.cs new file mode 100644 index 0000000..105cc43 --- /dev/null +++ b/Runtime/OpticalFlow/OpticalFlowAssets.cs @@ -0,0 +1,144 @@ +// 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.OpticalFlow +{ + /// + /// Scriptable object containing all shader resources required by FidelityFX Optical Flow. + /// 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 = "Optical Flow Assets", menuName = "FidelityFX/Optical Flow Assets", order = 1111)] + public class OpticalFlowAssets : ScriptableObject + { + public OpticalFlowShaders shaders; + +#if UNITY_EDITOR + private void Reset() + { + shaders = new OpticalFlowShaders + { + generateOpticalFlowInputPyramid = FindComputeShader("ffx_opticalflow_compute_luminance_pyramid_pass"), + prepareLuma = FindComputeShader("ffx_opticalflow_prepare_luma_pass"), + generateScdHistogram = FindComputeShader("ffx_opticalflow_generate_scd_histogram_pass"), + computeScdDivergence = FindComputeShader("ffx_opticalflow_compute_scd_divergence_pass"), + computeOpticalFlow = FindComputeShader("ffx_opticalflow_compute_optical_flow_advanced_pass_v5"), + filterOpticalFlow = FindComputeShader("ffx_opticalflow_filter_optical_flow_pass_v5"), + scaleOpticalFlow = FindComputeShader("ffx_opticalflow_scale_optical_flow_advanced_pass_v5"), + }; + } + + 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 Optical Flow. + /// + [System.Serializable] + public class OpticalFlowShaders + { + /// + /// The compute shader used by the generate optical flow input pass. + /// + public ComputeShader generateOpticalFlowInputPyramid; + + /// + /// The compute shader used by the prepare luma pass. + /// + public ComputeShader prepareLuma; + + /// + /// The compute shader used by the generate SCD histogram pass. + /// + public ComputeShader generateScdHistogram; + + /// + /// The compute shader used by the compute SCD divergence pass. + /// + public ComputeShader computeScdDivergence; + + /// + /// The compute shader used by the compute optical flow pass. + /// + public ComputeShader computeOpticalFlow; + + /// + /// The compute shader used by the filter optical flow pass. + /// + public ComputeShader filterOpticalFlow; + + /// + /// The compute shader used by the scale optical flow mask. + /// + public ComputeShader scaleOpticalFlow; + + /// + /// Returns a copy of this class and its contents. + /// + public OpticalFlowShaders Clone() + { + return (OpticalFlowShaders)MemberwiseClone(); + } + + /// + /// Returns a copy of this class with clones of all its shaders. + /// This can be useful if you're running multiple Optical Flow instances with different shader configurations. + /// Be sure to clean up these clones through Dispose once you're done with them. + /// + public OpticalFlowShaders DeepCopy() + { + return new OpticalFlowShaders + { + generateOpticalFlowInputPyramid = Object.Instantiate(generateOpticalFlowInputPyramid), + prepareLuma = Object.Instantiate(prepareLuma), + generateScdHistogram = Object.Instantiate(generateScdHistogram), + computeScdDivergence = Object.Instantiate(computeScdDivergence), + computeOpticalFlow = Object.Instantiate(computeOpticalFlow), + filterOpticalFlow = Object.Instantiate(filterOpticalFlow), + scaleOpticalFlow = Object.Instantiate(scaleOpticalFlow), + }; + } + + /// + /// Destroy all the shaders within this instance. + /// Use this only on clones created through DeepCopy. + /// + public void Dispose() + { + Object.Destroy(scaleOpticalFlow); + Object.Destroy(filterOpticalFlow); + Object.Destroy(computeOpticalFlow); + Object.Destroy(computeScdDivergence); + Object.Destroy(generateScdHistogram); + Object.Destroy(prepareLuma); + Object.Destroy(generateOpticalFlowInputPyramid); + } + } +} diff --git a/Runtime/OpticalFlow/OpticalFlowAssets.cs.meta b/Runtime/OpticalFlow/OpticalFlowAssets.cs.meta new file mode 100644 index 0000000..118b851 --- /dev/null +++ b/Runtime/OpticalFlow/OpticalFlowAssets.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0ac13db1d14fa3f498ce3c78c44dfb84 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: