32 static float alpha_beta_spectrum(
const float alpha,
36 const float peakomega)
38 return (alpha *
sqrt(gamma) /
pow(omega, 5.0)) *
exp(-
beta *
pow(peakomega / omega, 4.0));
41 static float peak_sharpen(
const float omega,
const float m_peakomega,
const float m_gamma)
43 const float peak_sharpening_sigma = (omega < m_peakomega) ? 0.07 : 0.09;
44 const float peak_sharpening =
pow(
45 m_gamma,
exp(-
sqrt((omega - m_peakomega) / (peak_sharpening_sigma * m_peakomega)) / 2.0));
47 return peak_sharpening;
53 static float ocean_spectrum_wind_and_damp(
const Ocean *oc,
58 const float k2 = kx * kx + kz * kz;
59 const float k_mag_inv = 1.0f / k2;
60 const float k_dot_w = (kx * k_mag_inv * oc->_wx) + (kz * k_mag_inv * oc->_wz);
63 float newval = val *
pow(
fabs(k_dot_w), oc->_wind_alignment);
70 if (oc->_wind_alignment > 0.0) {
71 newval *= oc->_damp_reflections;
78 static float jonswap(
const Ocean *oc,
const float k2)
81 const float k_mag =
sqrt(k2);
83 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
84 const float omega =
sqrt(m_omega);
86 const float m_fetch = oc->_fetch_jonswap;
90 float m_gamma = oc->_sharpen_peak_jonswap;
98 const float m_windspeed = oc->_V;
100 const float m_dimensionlessFetch =
fabs(GRAVITY * m_fetch /
sqrt(m_windspeed));
101 const float m_alpha = 0.076 *
pow(m_dimensionlessFetch, -0.22);
103 const float m_tau =
M_PI * 2;
104 const float m_peakomega = m_tau * 3.5 *
fabs(GRAVITY / oc->_V) *
105 pow(m_dimensionlessFetch, -0.33);
107 const float beta = 1.25f;
109 float val = alpha_beta_spectrum(m_alpha,
beta, GRAVITY, omega, m_peakomega);
112 val *= peak_sharpen(m_omega, m_peakomega, m_gamma);
119 const float k2 = kx * kx + kz * kz;
127 const float peak_omega_PM = 0.87f * GRAVITY / oc->_V;
129 const float k_mag =
sqrt(k2);
130 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
132 const float omega =
sqrt(m_omega);
133 const float alpha = 0.0081f;
134 const float beta = 1.291f;
136 float val = alpha_beta_spectrum(alpha,
beta, GRAVITY, omega, peak_omega_PM);
138 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
145 const float k2 = kx * kx + kz * kz;
152 float val = jonswap(oc, k2);
154 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
157 const float m_depth = oc->_depth;
160 const float k_mag =
sqrt(k2);
162 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
163 const float omega =
sqrt(m_omega);
165 const float kitaigorodskiiDepth_wh = omega * gain;
166 const float kitaigorodskiiDepth = 0.5 + (0.5 *
tanh(1.8 * (kitaigorodskiiDepth_wh - 1.125)));
168 val *= kitaigorodskiiDepth;
170 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
177 const float k2 = kx * kx + kz * kz;
184 float val = jonswap(oc, k2);
186 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
float BLI_ocean_spectrum_piersonmoskowitz(const struct Ocean *oc, float kx, float kz)
float BLI_ocean_spectrum_jonswap(const struct Ocean *oc, float kx, float kz)
float BLI_ocean_spectrum_texelmarsenarsloe(const struct Ocean *oc, float kx, float kz)
ccl_device_inline float2 fabs(const float2 &a)
ccl_device_inline float3 exp(float3 v)
ccl_device_inline float3 pow(float3 v, float e)
INLINE Rall1d< T, V, S > tanh(const Rall1d< T, V, S > &arg)
ccl_device_inline float beta(float x, float y)