46 static float alpha_beta_spectrum(
const float alpha,
50 const float peakomega)
55 static float peak_sharpen(
const float omega,
const float m_peakomega,
const float m_gamma)
57 const float peak_sharpening_sigma = (omega < m_peakomega) ? 0.07 : 0.09;
58 const float peak_sharpening =
pow(
59 m_gamma,
exp(-
sqrt((omega - m_peakomega) / (peak_sharpening_sigma * m_peakomega)) / 2.0));
61 return peak_sharpening;
67 static float ocean_spectrum_wind_and_damp(
const Ocean *oc,
72 const float k2 = kx * kx + kz * kz;
73 const float k_mag_inv = 1.0f / k2;
74 const float k_dot_w = (kx * k_mag_inv * oc->_wx) + (kz * k_mag_inv * oc->_wz);
77 float newval = val *
pow(
fabs(k_dot_w), oc->_wind_alignment);
84 if (oc->_wind_alignment > 0.0) {
85 newval *= oc->_damp_reflections;
92 static float jonswap(
const Ocean *oc,
const float k2)
95 const float k_mag =
sqrt(k2);
97 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
98 const float omega =
sqrt(m_omega);
100 const float m_fetch = oc->_fetch_jonswap;
104 float m_gamma = oc->_sharpen_peak_jonswap;
112 const float m_windspeed = oc->_V;
114 const float m_dimensionlessFetch =
fabs(GRAVITY * m_fetch /
sqrt(m_windspeed));
115 const float m_alpha = 0.076 *
pow(m_dimensionlessFetch, -0.22);
117 const float m_tau =
M_PI * 2;
118 const float m_peakomega = m_tau * 3.5 *
fabs(GRAVITY / oc->_V) *
119 pow(m_dimensionlessFetch, -0.33);
121 const float beta = 1.25f;
123 float val = alpha_beta_spectrum(m_alpha,
beta, GRAVITY, omega, m_peakomega);
126 val *= peak_sharpen(m_omega, m_peakomega, m_gamma);
138 const float k2 = kx * kx + kz * kz;
146 const float peak_omega_PM = 0.87f * GRAVITY / oc->_V;
148 const float k_mag =
sqrt(k2);
149 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
151 const float omega =
sqrt(m_omega);
152 const float alpha = 0.0081f;
153 const float beta = 1.291f;
155 float val = alpha_beta_spectrum(
alpha,
beta, GRAVITY, omega, peak_omega_PM);
157 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
168 const float k2 = kx * kx + kz * kz;
175 float val = jonswap(oc, k2);
177 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
180 const float m_depth = oc->_depth;
183 const float k_mag =
sqrt(k2);
185 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
186 const float omega =
sqrt(m_omega);
188 const float kitaigorodskiiDepth_wh = omega * gain;
189 const float kitaigorodskiiDepth = 0.5 + (0.5 *
tanh(1.8 * (kitaigorodskiiDepth_wh - 1.125)));
191 val *= kitaigorodskiiDepth;
193 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
208 const float k2 = kx * kx + kz * kz;
215 float val = jonswap(oc, k2);
217 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
float BLI_ocean_spectrum_texelmarsenarsloe(const struct Ocean *oc, const float kx, const float kz)
float BLI_ocean_spectrum_piersonmoskowitz(const struct Ocean *oc, const float kx, const float kz)
float BLI_ocean_spectrum_jonswap(const struct Ocean *oc, const float kx, const float kz)
static CCL_NAMESPACE_BEGIN const double alpha
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
INLINE Rall1d< T, V, S > tanh(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > exp(const Rall1d< T, V, S > &arg)
ccl_device_inline float beta(float x, float y)
ccl_device_inline float2 fabs(const float2 &a)