using UnityEngine; using UnityEngine.Experimental.Rendering; namespace FidelityFX.FrameGen { internal class OpticalFlowResources: FfxResourcesBase { public readonly RenderTexture[][] OpticalFlowInputLevels = { new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], }; public readonly RenderTexture[][] OpticalFlowLevels = { new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], new RenderTexture[2], }; public RenderTexture OpticalFlowSCDHistogram; public RenderTexture OpticalFlowSCDPreviousHistogram; public RenderTexture OpticalFlowSCDTemp; public void Create(in OpticalFlow.ContextDescription contextDescription) { Vector2Int opticalFlowInputTextureSize = contextDescription.resolution; Vector2Int opticalFlowTextureSize = OpticalFlow.GetOpticalFlowTextureSize(contextDescription.resolution, OpticalFlow.MinBlockSize); for (int level = 0; level < OpticalFlow.OpticalFlowMaxPyramidLevels; ++level) { CreateDoubleBufferedResource(OpticalFlowInputLevels[level], $"OPTICALFLOW_OpticalFlowInputLevel{level}-", opticalFlowInputTextureSize, GraphicsFormat.R8_UInt); CreateDoubleBufferedResource(OpticalFlowLevels[level], $"OPTICALFLOW_OpticalFlowLevel{level}-", opticalFlowTextureSize, GraphicsFormat.R16G16_SInt); opticalFlowTextureSize = NextLevelSize(opticalFlowTextureSize); opticalFlowInputTextureSize = new Vector2Int(opticalFlowInputTextureSize.x >> 1, opticalFlowInputTextureSize.y >> 1); } OpticalFlowSCDHistogram = CreateResource("OPTICALFLOW_OpticalFlowSCDHistogram", new Vector2Int(OpticalFlow.GetSCDHistogramTextureWidth(), 1), GraphicsFormat.R32_UInt); OpticalFlowSCDPreviousHistogram = CreateResource("OPTICALFLOW_OpticalFlowSCDPreviousHistogram", new Vector2Int(OpticalFlow.GetSCDHistogramTextureWidth(), 1), GraphicsFormat.R32_SFloat); OpticalFlowSCDTemp = CreateResource("OPTICALFLOW_OpticalFlowSCDTemp", new Vector2Int(3, 1), GraphicsFormat.R32_UInt); } public void Destroy() { DestroyResource(ref OpticalFlowSCDTemp); DestroyResource(ref OpticalFlowSCDPreviousHistogram); DestroyResource(ref OpticalFlowSCDHistogram); for (int level = 0; level < OpticalFlow.OpticalFlowMaxPyramidLevels; ++level) { DestroyResource(OpticalFlowLevels[level]); DestroyResource(OpticalFlowInputLevels[level]); } } private static Vector2Int NextLevelSize(Vector2Int size) { return new Vector2Int(AlignUp(size.x, 2) / 2, AlignUp(size.y, 2) / 2); } private static int AlignUp(int x, int y) { return (x + (y - 1)) & ~(y - 1); } } }