I am working on an implementation of Tessendorf’s Ocean Water. I have two backends in my renderer. One that converts shaders in GLSL to MSL and runs on Metal, and another that uses the GLSL within OpenGL on Windows.
The ocean is generated by running an FFT on an Ocean spectrum texture to generate a heightmap. The data is stored in a RGBA32F
texture. I’ve tested the FFT both as a single-pass (per direction) compute shader, as well as a multi-pass compute shader, with log2(N) passes (per direction). The shaders use double
s wherever possible, but the texture precision cannot be increased for obvious reasons.
The FFT works well on Metal, but on windows, there is a large amount of noise, which I am fairly sure comes from a lack of precision. How can I reduce the noise in the shader, or increase the precision?
Here are my possible ideas:
- Use an SSBO with 64-bit precision, and map it to a texture at the end.
- Apply some form of smoothing to the final image.
- Some other precision magic I don’t know about.
Here is the heightmap on Windows:
Here is the heightmap on macOS:
The images have different color mapping because of the way they were exported (RenderDoc vs Xcode), but the vertical noise is clear in the the first image. Both of these images are 256×256, and the noise is much less visible at small sizes.