31 using namespace GLFFT;
38 vec2 normalmap_freq_mod)
40 wind_velocity(wind_velocity),
42 Nx(resolution.
x), Nz(resolution.
y), size(size), size_normal(size / normalmap_freq_mod)
45 L =
vec_dot(wind_velocity, wind_velocity) /
G;
54 amplitude *= 0.3f / sqrt(size.
x * size.
y);
58 amplitude * sqrt(normalmap_freq_mod.
x * normalmap_freq_mod.
y), 0.02f);
79 unsigned out_width =
Nx >> rate_log2;
80 unsigned out_height =
Nz >> rate_log2;
82 for (
unsigned z = 0; z < out_height; z++)
84 for (
unsigned x = 0;
x < out_width;
x++)
86 int alias_x =
alias(
x, out_width);
87 int alias_z =
alias(z, out_height);
99 out[z * out_width +
x] = in[alias_z *
Nx + alias_x];
113 float kL = k_len *
L;
119 exp(-1.0 * k_len * k_len * max_l * max_l) *
120 exp(-1.0
f / (kL * kL)) *
129 for (
unsigned z = 0; z <
Nz; z++)
131 for (
unsigned x = 0;
x <
Nx;
x++)
133 auto &
v = distribution[z * Nx +
x];
138 v = dist * amplitude * sqrt(0.5
f *
phillips(k, max_l));
168 GL_CHECK(glUniform2f(0, mod_normal.
x, mod_normal.
y));
173 GL_CHECK(glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT));
184 GL_CHECK(glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT));
201 GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D));
203 GL_CHECK(glGenerateMipmap(GL_TEXTURE_2D));
207 for (
unsigned l = 0; (
Nx >> l) >= 8 && (
Nz >> l) >= 8; l++)
214 Nx >> l,
Nz >> l, l + 1);
216 Nx >> l,
Nz >> l, l + 1);
222 GL_CHECK(glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT));
239 GL_CHECK(glActiveTexture(GL_TEXTURE0));
241 GL_CHECK(glActiveTexture(GL_TEXTURE1));
260 GL_CHECK(glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT));
265 GL_CHECK(glActiveTexture(GL_TEXTURE0));
266 GL_CHECK(glBindTexture(GL_TEXTURE_2D, texture.get()));
269 glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &min_filter);
271 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST));
275 GL_CHECK(glBindImageTexture(0, texture.get(), l, GL_FALSE, 0, GL_WRITE_ONLY,
format));
276 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, l - 1));
278 GL_CHECK(glUniform2f(1, 1.0
f / Nx, 1.0
f / Nz));
280 unsigned threads_x = Nx / 2;
281 unsigned threads_z = Nz / 2;
282 GL_CHECK(glDispatchCompute(threads_x / 4, threads_z / 4, 1));
284 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 1000));
285 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter));
291 tex.init(width, height, levels, format, GL_REPEAT, GL_REPEAT, min_filter, mag_filter);
306 auto cache = make_shared<ProgramCache>();
312 options.type.output_fp16 =
FFT_FP16;
315 options.performance.workgroup_size_x = 8;
316 options.performance.workgroup_size_y = 4;
317 options.performance.vector_size = 4;
318 options.performance.shared_banked =
false;
330 for (
unsigned i = 0; i < 2; i++)
349 GL_RGBA16F, normal_levels - 2,
352 GL_LINEAR_MIPMAP_NEAREST);
355 GL_RGBA16F, normal_levels - 2,
358 GL_LINEAR_MIPMAP_LINEAR);
GLFFT::Buffer freq_height
void update_phase(float time)
GLFFT::Program prog_mipmap_height
GLFFT::Texture normalmap[2]
std::normal_distribution< float > normal_dist
unsigned displacement_downsample
GLFFT::Buffer freq_displacement
FFTWater(float amplitude, vec2 wind_velocity, uvec2 resolution, vec2 size, vec2 normalmap_freq_mod)
std::unique_ptr< GLFFT::FFT > fft_displacement
std::unique_ptr< GLFFT::FFT > fft_normal
float vec_dot(const T &a, const T &b)
void init_texture(GLFFT::Texture &tex, GLenum format, unsigned levels, unsigned width, unsigned height, GLenum mag_filter, GLenum min_filter)
GLint GLsizei GLsizei height
GLuint common_compile_compute_shader_from_file(const char *cs_source)
cfloat phillips(vec2 k, float max_l)
Complex-to-real transform. N / 2 + 1 complex values are used per row with a stride of N complex sampl...
std::unique_ptr< GLFFT::FFT > fft_height
GLint GLsizei GLsizei GLenum format
GLFFT::Texture displacementmap[2]
bool fp16
Whether internal shader should be mediump float.
GLFFT::Texture heightmap[2]
void downsample_distribution(cfloat *out, const cfloat *in, unsigned rate_log2)
GLFFT::Program prog_mipmap_gradient_jacobian
float vec_length(const T &vec)
std::vector< cfloat > distribution_normal
GLFFT::Program prog_generate_displacement
Options for FFT implementation. Defaults for performance as conservative.
void init(const void *data, size_t size, GLenum access)
GLFFT::Buffer freq_normal
void generate_distribution(cfloat *distribution, vec2 size, float amplitude, float max_l)
static int alias(int x, int N)
#define M_PI
The value of pi.
bool common_has_extension(const char *ext)
GLFFT::Texture heightdisplacementmap[2]
GL_SHADER_STORAGE_BUFFER.
GLFFT::Buffer distribution_buffer_displacement
Functions for working with textures.
float max(float x, float y)
Regular complex-to-complex transform.
GLFFT::Program prog_generate_normal
GLenum GLuint GLintptr GLsizeiptr size
GLFFT::Buffer distribution_buffer
GLFFT::Program prog_mipmap_normal
GLint GLint GLint GLint GLint x
T vec_normalize(const T &vec)
std::vector< cfloat > distribution
std::default_random_engine engine
void bake_height_gradient()
GLFFT::Buffer distribution_buffer_normal
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
GLFFT::Texture gradientjacobianmap[2]
void compute_mipmap(const GLFFT::Program &program, const GLFFT::Texture &texture, GLenum format, unsigned Nx, unsigned Nz, unsigned level)
GLFFT::Program prog_generate_height
std::complex< float > cfloat
struct GLFFT::FFTOptions::Type type
std::vector< cfloat > distribution_displacement
GLFFT::Program prog_bake_height_gradient