3 layout(local_size_x = 64) in;
5 layout(std430, binding = 0) readonly buffer Distribution
10 layout(std430, binding = 1) writeonly buffer HeightmapFFT
15 layout(binding = 2, std140) uniform UBO
20 vec2 alias(vec2 i, vec2 N)
22 return mix(i, i - N, greaterThan(i, 0.5 * N));
25 vec4 cmul(vec4 a, vec4 b)
32 return R0 + vec4(-R1.x, R1.y, -R1.z, R1.w);
35 vec2 cmul(vec2 a, vec2 b)
42 return R0 + vec2(-R1.x, R1.y);
47 return packHalf2x16(v);
52 return uvec2(packHalf2x16(v.xy), packHalf2x16(v.zw));
55 uvec2 workaround_mix(uvec2 a, uvec2 b, bvec2 sel)
57 return uvec2(sel.x ? b.x : a.x, sel.y ? b.y : a.y);
60 void generate_heightmap()
62 uvec2 N = gl_WorkGroupSize.xy * gl_NumWorkGroups.xy;
63 uvec2 i = gl_GlobalInvocationID.xy;
64 // Pick out the negative frequency variant.
65 uvec2 wi = workaround_mix(N - i, uvec2(0u), equal(i, uvec2(0u)));
67 // Pick out positive and negative travelling waves.
68 vec2 a = distribution[i.y * N.x + i.x];
69 vec2 b = distribution[wi.y * N.x + wi.x];
71 vec2 k = uModTime.xy * alias(vec2(i), vec2(N));
72 float k_len = length(k);
76 // If this sample runs for hours on end, the cosines of very large numbers will eventually become unstable.
77 // It is fairly easy to fix this by wrapping uTime,
78 // and quantizing w such that wrapping uTime does not change the result.
79 // See Tessendorf's paper for how to do it.
80 // The sqrt(G * k_len) factor represents how fast ocean waves at different frequencies propagate.
81 float w = sqrt(G * k_len) * uModTime.z;
85 // Complex multiply to rotate our frequency samples.
86 a = cmul(a, vec2(cw, sw));
87 b = cmul(b, vec2(cw, sw));
88 b = vec2(b.x, -b.y); // Complex conjugate since we picked a frequency with the opposite direction.
89 vec2 res = a + b; // Sum up forward and backwards travelling waves.
90 heights[i.y * N.x + i.x] = pack2(res);