First signs of success

Yesterday, I integrated CUDA into the project which went rather easily, except that I had to update some graphics drivers on my dual-booted Ubuntu to get my Nvidia 1070 running. 

According to CUDA specification, the result of inverse cuFFT is un-normalized, meaning that the result is scaled by the input size; in my case, 512x512.

iFFT(FFT(A) = length(A) * A

This means that the result of the cuFFT operation has to be normalized and divided by the problem size. However after normalization, the result did still not look like I expected. 




It was like every other pixel were a little darker. And after scratching my head for a while I finally found a master's thesis by Fredrik Larsson (2012) named "Deterministic Ocean Waves", where he intuitively and clearly explains the wave transformation using FFT. 

In equation 4.6, he clearly shows how the translation from the frequency domain h-tilde(k, t) to the spatial domain h(q, t) essentially alternates signs due to the definition of k and that q = rD / R.

  


The essencial property I found was explaining why the pixels seemed to alternate between a darker and a lighter hue, namely that the result of the inverse discrete fourier transform actually is multiplied with pow(-1, m + n). When taking this factor into account, the result was absolutely perfect.

Image represents a displacement map to be used to displace vertices and create the surface of the water.



Code

  double min_r = std::numeric_limits<double>::min();
  double max_r = std::numeric_limits<double>::min();
for (int m = 0; m < N; m++) {
for (int n = 0; n < N; n++) {
int i = m * N + n;
int sign = (m + n) % 2 == 0 ? 1 : -1; // Larsson (2012), Equation 4.6
h_k[i] /= sign * (N * N);

if (h_k[i].real() < min_r)
min_r = h_k[i].real();
if (h_k[i].real() > max_r)
max_r = h_k[i].real();
}
}

Image displacement_image(N, N, GL_RGB);
for (int m = 0; m < N; m++) {
for (int n = 0; n < N; n++) {
int i = m * N + n;
double value = h_k[i].real() - min_r / (max_r - min_r);
GLubyte color = value * 255;
displacement_image.set_pixel(n, m, color, color, color);
}
}

Kommentarer

Populära inlägg i den här bloggen

Dear ImGui - Interactive settings for ocean water

CUDA cuFFT vs FFTW

Gradients and Choppy waves.