You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

102 lines
3.8 KiB

using System;
using System.Runtime.InteropServices;
using UnityEngine;
namespace FidelityFX.FrameGen
{
public static class OpticalFlow
{
internal const int MinBlockSize = 8;
internal const int OpticalFlowMaxPyramidLevels = 7;
internal const int HistogramBins = 256;
internal const int HistogramsPerDim = 3;
internal const int HistogramShifts = 3;
public static OpticalFlowContext CreateContext(Vector2Int resolution, OpticalFlowShaders shaders)
{
Debug.Log($"Setting up Optical Flow with resolution: {resolution.x}x{resolution.y}");
var contextDescription = new ContextDescription
{
resolution = resolution,
shaders = shaders,
};
var context = new OpticalFlowContext();
context.Create(contextDescription);
return context;
}
public struct ContextDescription
{
public Vector2Int resolution;
public OpticalFlowShaders shaders;
}
public class DispatchDescription
{
public ResourceView Color;
public ResourceView OpticalFlowVector;
public ResourceView OpticalFlowSCD;
public bool Reset;
public BackbufferTransferFunction BackbufferTransferFunction;
public Vector2 MinMaxLuminance;
}
internal static Vector2Int GetOpticalFlowTextureSize(Vector2Int displaySize, int opticalFlowBlockSize)
{
int width = (displaySize.x + opticalFlowBlockSize - 1) / opticalFlowBlockSize;
int height = (displaySize.y + opticalFlowBlockSize - 1) / opticalFlowBlockSize;
return new Vector2Int(width, height);
}
internal static Vector2Int GetOpticalFlowHistogramSize(int level)
{
const int searchRadius = 8;
int maxVelocity = searchRadius * (1 << (OpticalFlowMaxPyramidLevels - 1 - level));
int binsPerDimension = 2 * maxVelocity + 1;
return new Vector2Int(binsPerDimension, binsPerDimension);
}
internal static Vector2Int GetGlobalMotionSearchDispatchSize(int level)
{
const int threadGroupSizeX = 16;
const int threadGroupSizeY = 16;
Vector2Int opticalFlowHistogramSize = GetOpticalFlowHistogramSize(level);
int additionalElementsDueToShiftsX = opticalFlowHistogramSize.x / threadGroupSizeX;
int additionalElementsDueToShiftsY = opticalFlowHistogramSize.y / threadGroupSizeY;
int dispatchX = (opticalFlowHistogramSize.x + additionalElementsDueToShiftsX + threadGroupSizeX - 1) / threadGroupSizeX;
int dispatchY = (opticalFlowHistogramSize.y + additionalElementsDueToShiftsY + threadGroupSizeY - 1) / threadGroupSizeY;
return new Vector2Int(dispatchX, dispatchY);
}
internal static int GetSCDHistogramTextureWidth()
{
return HistogramBins * (HistogramsPerDim * HistogramsPerDim);
}
[Serializable, StructLayout(LayoutKind.Sequential)]
internal struct OpticalFlowConstants
{
public Vector2Int inputLumaResolution;
public uint opticalFlowPyramidLevel;
public uint opticalFlowPyramidLevelCount;
public int frameIndex;
public uint backbufferTransferFunction;
public Vector2 minMaxLuminance;
}
[Serializable, StructLayout(LayoutKind.Sequential)]
internal struct SpdConstants
{
public FfxSpd.SpdConstants spd;
public uint numWorkGroupsOpticalFlowInputPyramid;
public uint pad0_;
public uint pad1_;
public uint pad2_;
}
}
}