// calculate response for the samples in cb and fraction time tau // in comments Ti is input sampling period double src::re_samp(double tau ) { int p; int k; double sum,h,sample; p = (x_cb_i)-1; // this is youngest sample index sum=0.0; for (k=0; k<NTaps; k++) { if (p <0 ) { // circular buffer p = NTaps-1; } h = h_t(tau+k); // k+tau represents t=k*Ti+tau sample = x_cb[p]; // samples sum = sum + h*sample; // the older the sample, the longer last its partial response p = p-1; // go to older sample } return (sum); }
float OceanSurface::h(float x, float z, float t) { complex_number height; glm::vec2 x_v = glm::vec2(x, z); for (int i = 0; i < N; i++) { float k_x = M_PI * (2.0f * i - N) / L_x; for (int j = 0; j < M; j++) { int pos = i * M + j; float k_z = M_PI * (2.0f * j - M) / L_z; glm::vec2 k = glm::vec2(k_x, k_z); // k is wavevector float d = glm::dot(k, x_v); complex_number h_0_t = h_t(i, j, t); complex_number c1(cos(d), sin(d)); height = height + c1 * h_0_t; } } return height.re; }
void OceanSurface::updateOcean(float t) { if (!gpu) { for (int i = 0; i < N; i++) { float k_x = float(M_PI) * (2.0f * i - N) / L_x; // x-coordinate of wavevector at 'pos' for (int j = 0; j < M; j++) { int pos = i * M + j; float k_z = M_PI * (2.0f * j - M) / L_z; // z-coordinate of wavevector at 'pos' float k_length = sqrtf(k_x * k_x + k_z * k_z); // length of wavevector 'k' // calc all complex amplitudes in time t h_fft[pos] = h_t(i, j, t); // calc all displacements in time t if (k_length < 0.000001) { // ignore small wavevectors, put (0, 0) displacement dx_fft[pos] = complex_number(); dz_fft[pos] = complex_number(); } else { // calculate displacement via formula dx_fft[pos] = complex_number(0.0f, -k_x / k_length) * h_fft[pos]; dz_fft[pos] = complex_number(0.0f, -k_z / k_length) * h_fft[pos]; } // calc x-, and z- component of gradient of h_fft gradient_x[pos] = complex_number(0.0f, k_x) * h_fft[pos]; gradient_z[pos] = complex_number(0.0f, k_z) * h_fft[pos]; } } // row flipping /*/complex_number *h_fft_2 = new complex_number[N * N]; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { int pos_1 = i * M + j; int pos_2 = (N - i - 1) * M + j; h_fft_2[pos_2] = h_fft[pos_1]; } }*/ } else { // first update height map with time amplitudes (and displacement map with gradient map); glUseProgram(upd_height_program); glUniform1f(total_time_location, t); // height map glBindImageTexture(0, texture_H_t0, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, texture_H_t0_cc, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(2, texture_H_t, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); // displacement map glBindImageTexture(3, texture_Dx, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glBindImageTexture(4, texture_Dz, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); // gradient map glBindImageTexture(5, texture_Gradx, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glBindImageTexture(6, texture_Gradz, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(N, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glUseProgram(0); // fft in compute shader glUseProgram(fft_comp_program); // update texture /*glBindTexture(GL_TEXTURE_2D, texture_H_t); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, N, N, GL_RG, GL_FLOAT, h_fft); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, N, N, 0, GL_RG, GL_FLOAT, h_fft); glBindTexture(GL_TEXTURE_2D, 0);*/ // bind reverse indices glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, rev_ind_buffer); /*______________HEIGHT MAP FFT________________*/ // fft per rows glUniform1i(fft_column_location, 0); glBindImageTexture(0, texture_H_t, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, texture_H_fft_t_row, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); // fft per columns glUniform1i(fft_column_location, 1); glBindImageTexture(0, texture_H_fft_t_row, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, texture_H_fft_t_col, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); /*______________DISPLACEMENT-X MAP FFT________________*/ // fft per rows glUniform1i(fft_column_location, 0); glBindImageTexture(0, texture_Dx, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, tex_dx_fft_row, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); // fft per columns glUniform1i(fft_column_location, 1); glBindImageTexture(0, tex_dx_fft_row, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, tex_dx_fft, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); /*______________DISPLACEMENT-Z MAP FFT________________*/ // fft per rows glUniform1i(fft_column_location, 0); glBindImageTexture(0, texture_Dz, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, tex_dz_fft_row, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); // fft per columns glUniform1i(fft_column_location, 1); glBindImageTexture(0, tex_dz_fft_row, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, tex_dz_fft, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); /*______________GRADIENT-X MAP FFT________________*/ // fft per rows glUniform1i(fft_column_location, 0); glBindImageTexture(0, texture_Gradx, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, tex_gradx_fft_row, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); // fft per columns glUniform1i(fft_column_location, 1); glBindImageTexture(0, tex_gradx_fft_row, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, tex_gradx_fft, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); /*______________GRADIENT-Z MAP FFT________________*/ // fft per rows glUniform1i(fft_column_location, 0); glBindImageTexture(0, texture_Gradz, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, tex_gradz_fft_row, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); // fft per columns glUniform1i(fft_column_location, 1); glBindImageTexture(0, tex_gradz_fft_row, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RG32F); glBindImageTexture(1, tex_gradz_fft, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RG32F); glDispatchCompute(1, N, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); glUseProgram(0); } int error = glGetError(); if (error != GL_NO_ERROR) { int b = 4; } if (gpu) { return; } for (unsigned int i = 0; i < N; i++) { // horizontal fft for rows /*fft->fft(h_fft, h_fft, 1, i * M); fft->fft(dx_fft, dx_fft, 1, i * M); fft->fft(dz_fft, dz_fft, 1, i * M); fft->fft(gradient_x, gradient_x, 1, i * M); fft->fft(gradient_z, gradient_z, 1, i * M);*/ myFFT->processVertical(h_fft, 1, i * M); myFFT->processVertical(dx_fft, 1, i * M); myFFT->processVertical(dz_fft, 1, i * M); myFFT->processVertical(gradient_x, 1, i * M); myFFT->processVertical(gradient_z, 1, i * M); } for (unsigned int j = 0; j < M; j++) { // vertical fft for columns /*fft->fft(h_fft, h_fft, M, j); fft->fft(dx_fft, dx_fft, M, j); fft->fft(dz_fft, dz_fft, M, j); fft->fft(gradient_x, gradient_x, M, j); fft->fft(gradient_z, gradient_z, M, j);*/ myFFT->processHorizontal(h_fft, M, j); myFFT->processHorizontal(dx_fft, M, j); myFFT->processHorizontal(dz_fft, M, j); myFFT->processHorizontal(gradient_x, M, j); myFFT->processHorizontal(gradient_z, M, j); } glm::vec3 normal; // temp variable for normal calculation int sign; float signs[] = { 1.0f, -1.0f }; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { int pos = i * M + j; // flip sign for height sign = signs[(i + j) & 1]; grid[pos].y = h_fft[pos].re * sign; // flip sign for displacement dx_fft[pos] = dx_fft[pos] * sign; dz_fft[pos] = dz_fft[pos] * sign; // then calc displacement for original position in grid //grid[pos].x = init_positions[pos].x + lambda * dx_fft[pos].re; //grid[pos].z = init_positions[pos].z + lambda * dz_fft[pos].re; // flip sign for gradient component; gradient_x[pos] = gradient_x[pos] * sign; gradient_z[pos] = gradient_z[pos] * sign; // then calculate normal of vertex and normalize it normal = glm::vec3(-gradient_x[pos].re, 1.0f, -gradient_z[pos].re); normal = glm::normalize(normal); // and save it to vertex structure grid[pos].normal_x = normal.x; grid[pos].normal_y = normal.y; grid[pos].normal_z = normal.z; } } }