114 lines
2.8 KiB
C#
114 lines
2.8 KiB
C#
using UnityEngine;
|
|
|
|
namespace UltimateWater.Internal
|
|
{
|
|
public abstract class GpuFFT
|
|
{
|
|
private Texture2D _Butterfly;
|
|
|
|
protected RenderTexturesCache _RenderTexturesSet;
|
|
|
|
protected int _Resolution;
|
|
|
|
protected int _NumButterflies;
|
|
|
|
protected int _NumButterfliesPow2;
|
|
|
|
protected bool _TwoChannels;
|
|
|
|
private readonly bool _HighPrecision;
|
|
|
|
private readonly bool _UsesUav;
|
|
|
|
public Texture2D Butterfly
|
|
{
|
|
get
|
|
{
|
|
return _Butterfly;
|
|
}
|
|
}
|
|
|
|
public int Resolution
|
|
{
|
|
get
|
|
{
|
|
return _Resolution;
|
|
}
|
|
}
|
|
|
|
protected GpuFFT(int resolution, bool highPrecision, bool twoChannels, bool usesUAV)
|
|
{
|
|
_Resolution = resolution;
|
|
_HighPrecision = highPrecision;
|
|
_NumButterflies = (int)(Mathf.Log(resolution) / Mathf.Log(2f));
|
|
_NumButterfliesPow2 = Mathf.NextPowerOfTwo(_NumButterflies);
|
|
_TwoChannels = twoChannels;
|
|
_UsesUav = usesUAV;
|
|
RetrieveRenderTexturesSet();
|
|
CreateTextures();
|
|
}
|
|
|
|
public abstract void SetupMaterials();
|
|
|
|
public abstract void ComputeFFT(Texture tex, RenderTexture target);
|
|
|
|
public virtual void Dispose()
|
|
{
|
|
if (_Butterfly != null)
|
|
{
|
|
_Butterfly.Destroy();
|
|
_Butterfly = null;
|
|
}
|
|
}
|
|
|
|
private void CreateTextures()
|
|
{
|
|
CreateButterflyTexture();
|
|
}
|
|
|
|
private void RetrieveRenderTexturesSet()
|
|
{
|
|
RenderTextureFormat format = (_TwoChannels ? ((!_HighPrecision) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGBFloat) : ((!_HighPrecision) ? RenderTextureFormat.RGHalf : RenderTextureFormat.RGFloat));
|
|
_RenderTexturesSet = RenderTexturesCache.GetCache(_Resolution << 1, _Resolution << 1, 0, format, true, _UsesUav);
|
|
}
|
|
|
|
protected virtual void FillButterflyTexture(Texture2D butterfly, int[][] indices, Vector2[][] weights)
|
|
{
|
|
float num = _Resolution << 1;
|
|
Color color = default(Color);
|
|
for (int i = 0; i < _NumButterflies; i++)
|
|
{
|
|
for (int j = 0; j < 2; j++)
|
|
{
|
|
int num2 = ((j != 0) ? _Resolution : 0);
|
|
for (int k = 0; k < _Resolution; k++)
|
|
{
|
|
int num3 = _NumButterflies - i - 1;
|
|
int num4 = k << 1;
|
|
color.r = ((float)(indices[num3][num4] + num2) + 0.5f) / num;
|
|
color.g = ((float)(indices[num3][num4 + 1] + num2) + 0.5f) / num;
|
|
color.b = weights[i][k].x;
|
|
color.a = weights[i][k].y;
|
|
butterfly.SetPixel(num2 + k, i, color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void CreateButterflyTexture()
|
|
{
|
|
_Butterfly = new Texture2D(_Resolution << 1, _NumButterfliesPow2, (!_HighPrecision) ? TextureFormat.RGBAHalf : TextureFormat.RGBAFloat, false, true)
|
|
{
|
|
hideFlags = HideFlags.DontSave,
|
|
filterMode = FilterMode.Point,
|
|
wrapMode = TextureWrapMode.Clamp
|
|
};
|
|
int[][] indices;
|
|
Vector2[][] weights;
|
|
ButterflyFFTUtility.ComputeButterfly(_Resolution, _NumButterflies, out indices, out weights);
|
|
FillButterflyTexture(_Butterfly, indices, weights);
|
|
_Butterfly.Apply();
|
|
}
|
|
}
|
|
}
|