40static float alpha_beta_spectrum(
const float alpha,
44 const float peakomega)
46 return (alpha *
sqrt(gamma) /
pow(omega, 5.0)) *
exp(-
beta *
pow(peakomega / omega, 4.0));
49static float peak_sharpen(
const float omega,
const float peakomega,
const float gamma)
52 const float sigma = (omega < peakomega) ? 0.07 : 0.09;
53 const float exponent = -
square((omega - peakomega) / (sigma * peakomega)) / 2.0;
54 return pow(gamma,
exp(exponent));
60static float ocean_spectrum_wind_and_damp(
const Ocean *oc,
65 const float k2 = kx * kx + kz * kz;
66 const float k_mag_inv = 1.0f / k2;
67 const float k_dot_w = (kx * k_mag_inv * oc->_wx) + (kz * k_mag_inv * oc->_wz);
70 float newval = val *
pow(
fabs(k_dot_w), oc->_wind_alignment);
77 if (oc->_wind_alignment > 0.0) {
78 newval *= oc->_damp_reflections;
85static float jonswap(
const Ocean *oc,
const float k2)
88 const float k_mag =
sqrt(k2);
90 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
91 const float omega =
sqrt(m_omega);
93 const float m_fetch = oc->_fetch_jonswap;
97 float m_gamma = oc->_sharpen_peak_jonswap;
98 m_gamma = std::max<double>(m_gamma, 1.0);
99 m_gamma = std::min<double>(m_gamma, 6.0);
101 const float m_windspeed = oc->_V;
108 const float m_dimensionlessFetch =
fabs(GRAVITY * m_fetch /
sqrt(m_windspeed));
109 const float m_alpha = 0.076 *
pow(m_dimensionlessFetch, -0.22);
111 const float m_tau =
M_PI * 2;
112 const float m_peakomega = m_tau * 3.5 *
fabs(GRAVITY / oc->_V) *
113 pow(m_dimensionlessFetch, -0.33);
115 const float beta = 1.25f;
117 float val = alpha_beta_spectrum(m_alpha,
beta, GRAVITY, omega, m_peakomega);
120 val *= peak_sharpen(omega, m_peakomega, m_gamma);
127 const float k2 = kx * kx + kz * kz;
135 const float peak_omega_PM = 0.87f * GRAVITY / oc->_V;
137 const float k_mag =
sqrt(k2);
138 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
140 const float omega =
sqrt(m_omega);
141 const float alpha = 0.0081f;
142 const float beta = 1.291f;
144 float val = alpha_beta_spectrum(alpha,
beta, GRAVITY, omega, peak_omega_PM);
146 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
153 const float k2 = kx * kx + kz * kz;
160 float val = jonswap(oc, k2);
162 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
165 const float m_depth = oc->_depth;
168 const float k_mag =
sqrt(k2);
170 const float m_omega = GRAVITY * k_mag *
tanh(k_mag * oc->_depth);
171 const float omega =
sqrt(m_omega);
173 const float kitaigorodskiiDepth_wh = omega * gain;
174 const float kitaigorodskiiDepth = 0.5 + (0.5 *
tanh(1.8 * (kitaigorodskiiDepth_wh - 1.125)));
176 val *= kitaigorodskiiDepth;
178 val = ocean_spectrum_wind_and_damp(oc, kx, kz, val);
185 const float k2 = kx * kx + kz * kz;
192 float val = jonswap(oc, k2);
194 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 float beta(const float x, const float y)
ccl_device_inline float2 fabs(const float2 a)