RuralPowerCompetition_yizhe.../RuralPowerCompetition_yizheng1/Assets/3rdPart/Ocean/Scripts/WavesCascade.cs

161 lines
7.8 KiB
C#

using System;
using UnityEngine;
public class WavesCascade
{
public RenderTexture Displacement => displacement;
public RenderTexture Derivatives => derivatives;
public RenderTexture Turbulence => turbulence;
public Texture2D GaussianNoise => gaussianNoise;
public RenderTexture PrecomputedData => precomputedData;
public RenderTexture InitialSpectrum => initialSpectrum;
readonly int size;
readonly ComputeShader initialSpectrumShader;
readonly ComputeShader timeDependentSpectrumShader;
readonly ComputeShader texturesMergerShader;
readonly FastFourierTransform fft;
readonly Texture2D gaussianNoise;
readonly ComputeBuffer paramsBuffer;
readonly RenderTexture initialSpectrum;
readonly RenderTexture precomputedData;
readonly RenderTexture buffer;
readonly RenderTexture DxDz;
readonly RenderTexture DyDxz;
readonly RenderTexture DyxDyz;
readonly RenderTexture DxxDzz;
readonly RenderTexture displacement;
readonly RenderTexture derivatives;
readonly RenderTexture turbulence;
float lambda;
public WavesCascade(int size,
ComputeShader initialSpectrumShader,
ComputeShader timeDependentSpectrumShader,
ComputeShader texturesMergerShader,
FastFourierTransform fft,
Texture2D gaussianNoise)
{
this.size = size;
this.initialSpectrumShader = initialSpectrumShader;
this.timeDependentSpectrumShader = timeDependentSpectrumShader;
this.texturesMergerShader = texturesMergerShader;
this.fft = fft;
this.gaussianNoise = gaussianNoise;
KERNEL_INITIAL_SPECTRUM = initialSpectrumShader.FindKernel("CalculateInitialSpectrum");
KERNEL_CONJUGATE_SPECTRUM = initialSpectrumShader.FindKernel("CalculateConjugatedSpectrum");
KERNEL_TIME_DEPENDENT_SPECTRUMS = timeDependentSpectrumShader.FindKernel("CalculateAmplitudes");
KERNEL_RESULT_TEXTURES = texturesMergerShader.FindKernel("FillResultTextures");
initialSpectrum = FastFourierTransform.CreateRenderTexture(size, RenderTextureFormat.ARGBFloat);
precomputedData = FastFourierTransform.CreateRenderTexture(size, RenderTextureFormat.ARGBFloat);
displacement = FastFourierTransform.CreateRenderTexture(size, RenderTextureFormat.ARGBFloat);
derivatives = FastFourierTransform.CreateRenderTexture(size, RenderTextureFormat.ARGBFloat, true);
turbulence = FastFourierTransform.CreateRenderTexture(size, RenderTextureFormat.ARGBFloat, true);
paramsBuffer = new ComputeBuffer(2, 8 * sizeof(float));
buffer = FastFourierTransform.CreateRenderTexture(size);
DxDz = FastFourierTransform.CreateRenderTexture(size);
DyDxz = FastFourierTransform.CreateRenderTexture(size);
DyxDyz = FastFourierTransform.CreateRenderTexture(size);
DxxDzz = FastFourierTransform.CreateRenderTexture(size);
}
public void Dispose()
{
paramsBuffer?.Release();
}
public void CalculateInitials(WavesSettings wavesSettings, float lengthScale,
float cutoffLow, float cutoffHigh)
{
lambda = wavesSettings.lambda;
initialSpectrumShader.SetInt(SIZE_PROP, size);
initialSpectrumShader.SetFloat(LENGTH_SCALE_PROP, lengthScale);
initialSpectrumShader.SetFloat(CUTOFF_HIGH_PROP, cutoffHigh);
initialSpectrumShader.SetFloat(CUTOFF_LOW_PROP, cutoffLow);
wavesSettings.SetParametersToShader(initialSpectrumShader, KERNEL_INITIAL_SPECTRUM, paramsBuffer);
initialSpectrumShader.SetTexture(KERNEL_INITIAL_SPECTRUM, H0K_PROP, buffer);
initialSpectrumShader.SetTexture(KERNEL_INITIAL_SPECTRUM, PRECOMPUTED_DATA_PROP, precomputedData);
initialSpectrumShader.SetTexture(KERNEL_INITIAL_SPECTRUM, NOISE_PROP, gaussianNoise);
initialSpectrumShader.Dispatch(KERNEL_INITIAL_SPECTRUM, size / LOCAL_WORK_GROUPS_X, size / LOCAL_WORK_GROUPS_Y, 1);
initialSpectrumShader.SetTexture(KERNEL_CONJUGATE_SPECTRUM, H0_PROP, initialSpectrum);
initialSpectrumShader.SetTexture(KERNEL_CONJUGATE_SPECTRUM, H0K_PROP, buffer);
initialSpectrumShader.Dispatch(KERNEL_CONJUGATE_SPECTRUM, size / LOCAL_WORK_GROUPS_X, size / LOCAL_WORK_GROUPS_Y, 1);
}
public void CalculateWavesAtTime(float time)
{
// Calculating complex amplitudes
timeDependentSpectrumShader.SetTexture(KERNEL_TIME_DEPENDENT_SPECTRUMS, Dx_Dz_PROP, DxDz);
timeDependentSpectrumShader.SetTexture(KERNEL_TIME_DEPENDENT_SPECTRUMS, Dy_Dxz_PROP, DyDxz);
timeDependentSpectrumShader.SetTexture(KERNEL_TIME_DEPENDENT_SPECTRUMS, Dyx_Dyz_PROP, DyxDyz);
timeDependentSpectrumShader.SetTexture(KERNEL_TIME_DEPENDENT_SPECTRUMS, Dxx_Dzz_PROP, DxxDzz);
timeDependentSpectrumShader.SetTexture(KERNEL_TIME_DEPENDENT_SPECTRUMS, H0_PROP, initialSpectrum);
timeDependentSpectrumShader.SetTexture(KERNEL_TIME_DEPENDENT_SPECTRUMS, PRECOMPUTED_DATA_PROP, precomputedData);
timeDependentSpectrumShader.SetFloat(TIME_PROP, time);
timeDependentSpectrumShader.Dispatch(KERNEL_TIME_DEPENDENT_SPECTRUMS, size / LOCAL_WORK_GROUPS_X, size / LOCAL_WORK_GROUPS_Y, 1);
// Calculating IFFTs of complex amplitudes
fft.IFFT2D(DxDz, buffer, true, false, true);
fft.IFFT2D(DyDxz, buffer, true, false, true);
fft.IFFT2D(DyxDyz, buffer, true, false, true);
fft.IFFT2D(DxxDzz, buffer, true, false, true);
// Filling displacement and normals textures
texturesMergerShader.SetFloat("DeltaTime", Time.deltaTime);
texturesMergerShader.SetTexture(KERNEL_RESULT_TEXTURES, Dx_Dz_PROP, DxDz);
texturesMergerShader.SetTexture(KERNEL_RESULT_TEXTURES, Dy_Dxz_PROP, DyDxz);
texturesMergerShader.SetTexture(KERNEL_RESULT_TEXTURES, Dyx_Dyz_PROP, DyxDyz);
texturesMergerShader.SetTexture(KERNEL_RESULT_TEXTURES, Dxx_Dzz_PROP, DxxDzz);
texturesMergerShader.SetTexture(KERNEL_RESULT_TEXTURES, DISPLACEMENT_PROP, displacement);
texturesMergerShader.SetTexture(KERNEL_RESULT_TEXTURES, DERIVATIVES_PROP, derivatives);
texturesMergerShader.SetTexture(KERNEL_RESULT_TEXTURES, TURBULENCE_PROP, turbulence);
texturesMergerShader.SetFloat(LAMBDA_PROP, lambda);
texturesMergerShader.Dispatch(KERNEL_RESULT_TEXTURES, size / LOCAL_WORK_GROUPS_X, size / LOCAL_WORK_GROUPS_Y, 1);
derivatives.GenerateMips();
turbulence.GenerateMips();
}
const int LOCAL_WORK_GROUPS_X = 8;
const int LOCAL_WORK_GROUPS_Y = 8;
// Kernel IDs:
int KERNEL_INITIAL_SPECTRUM;
int KERNEL_CONJUGATE_SPECTRUM;
int KERNEL_TIME_DEPENDENT_SPECTRUMS;
int KERNEL_RESULT_TEXTURES;
// Property IDs
readonly int SIZE_PROP = Shader.PropertyToID("Size");
readonly int LENGTH_SCALE_PROP = Shader.PropertyToID("LengthScale");
readonly int CUTOFF_HIGH_PROP = Shader.PropertyToID("CutoffHigh");
readonly int CUTOFF_LOW_PROP = Shader.PropertyToID("CutoffLow");
readonly int NOISE_PROP = Shader.PropertyToID("Noise");
readonly int H0_PROP = Shader.PropertyToID("H0");
readonly int H0K_PROP = Shader.PropertyToID("H0K");
readonly int PRECOMPUTED_DATA_PROP = Shader.PropertyToID("WavesData");
readonly int TIME_PROP = Shader.PropertyToID("Time");
readonly int Dx_Dz_PROP = Shader.PropertyToID("Dx_Dz");
readonly int Dy_Dxz_PROP = Shader.PropertyToID("Dy_Dxz");
readonly int Dyx_Dyz_PROP = Shader.PropertyToID("Dyx_Dyz");
readonly int Dxx_Dzz_PROP = Shader.PropertyToID("Dxx_Dzz");
readonly int LAMBDA_PROP = Shader.PropertyToID("Lambda");
readonly int DISPLACEMENT_PROP = Shader.PropertyToID("Displacement");
readonly int DERIVATIVES_PROP = Shader.PropertyToID("Derivatives");
readonly int TURBULENCE_PROP = Shader.PropertyToID("Turbulence");
}