-
Notifications
You must be signed in to change notification settings - Fork 300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Periodicity along diagonal #15
Comments
Yes, this is a known issue, and unfortunately it's a tough nut to crack.
Planar cuts through 3D noise are problematic, even for the simplex grid.
(It's much worse than this for the "classic" axis-aligned grid.) Try adding
some small slope in z to the cut, and the problem might be much less
pronounced:
n = snoise(vec3(coords.xy, coords.x*0.2);
Even using "n = snoise(coords.xy, 0.0)" instead of n=snoise(0.0, coords.xy)
could have a positive effect. X, Y and Z are treated slightly differently
in the hash value computation.
As for the 2D case, well, the permutation is far from optimal - it's not
even particularly good. We just settled for something that was "good
enough" for most practical purposes and lent itself to implementation
within the limited integer range of 32-bit float values. Our original
article contains details on how the permutation polynomial is constructed,
and why we chose 289 (17*17) as the period. A larger period is perfectly
possible, and there may be polynomials that make less objectionable visual
patterns, but it's tricky to find them, and the choices are not all that
many if you want to use "float" which has an effective integer range
equivalent to 23 bits. (Larger numbers chop off some of the least
significant bits in the integer, which makes any hash function break down.)
Switching to 32-bit integers would make the problem a lot easier, but our
goal was to keep it compatible with OpenGL ES and WebGL, where integers are
still not available in most implementations. A real 32-bit integer data
type and logical operations (AND, OR, XOR) would make it possible to use a
more traditional integer hash function, of which there are many variants
published by other authors.
Some links that may or may not be useful to you:
www.cs.utah.edu/~aek/research/noise.pdf
This article points out the cause of the problem you found, but implements
a fix using permutation tables, which are undesirable for SIMD
implementations because of memory accesses.
https://briansharpe.wordpress.com/2011/10/01/gpu-texture-free-noise/
This also points to the problem you found, but offers no solution.
https://umbcgaim.wordpress.com/2010/07/01/gpu-random-numbers/
Presents a solution requiring 32-bit integer math. (Lots of similar hash
functions, some even simpler, exist in literature.)
www.sinfocol.org/archivos/2009/11/Goulburn06.pdf
Presents the Goulburn function, which has very good "randomness" but takes
a fair amout of cycles to compute. It also uses an in-memory table, even
though its use might be optional in this particular application.
Note that avoiding memory accesses at all costs is not always a good idea.
The traditional method of using a permutation table lends itself quite well
to implementation as a texture lookup. If you have texture bandwidth to
spare, a texture access might actually be faster than a permutation
function on current generation GPUs. You can compare the speed in this test:
http://www.itn.liu.se/~stegu/simplexnoise/GLSL-noise-vs-noise.zip
http://www.itn.liu.se/~stegu/simplexnoise/GLSL-noise-vs-noise-Win32.zip
/Stefan Gustavson
|
Hey, thank you for your detailed reply. It seems like using any axis-aligned plane ( Adding a small z slope actually helps a fair bit: the noise is no longer so obviously and drastically periodic, but general recurring patterns are still fairly obvious, and additionally the general patterns now seem to repeat in two directions instead of just one. Thanks for the other notes and links. I'll probably end up doing something with integers or using a texture lookup. Just one more question: what are you referring to by "our original article"? I thought you might mean this but it doesn't appear to contain anything on permutation polynomials. Cheers! |
Sorry for the confusion, I meant the write-up by Ian McEwan and myself on |
The thread is a detailed description of problems that still exist in the implementation, so I'm keeping it open. |
Ian McEwan and I are in the process of writing new noise functions, and in that process we found a better permutation polynomial that does not cause these ugly diagonal streaks. I have now retroactively changed the permutation polynomial across the board for all these old functions as well. It's only a matter of changing a "1.0" to "10.0". Sad that it took this long to find that simple remedy, but finding permutations to generate "apparent randomness" are a really tricky subject where there is little relevant previous work. |
The problem seems to have gone "poof" with that slight change to the permutation polynomial, so I'm closing this thread. |
Hey, this might be a dupe of issue 10 but the links are broken in that one so I couldn't be sure. Apologies if so.
It seems like both the 2D and 3D simplex noise functions are periodic with respect to a particular diagonal direction. The problem is not quite so obvious in 2D, but it's definitely still there. I tried various fixes mentioned in other issues without luck. Did I do something wrong?
In the samples below I zoomed out a lot to show the problem but it's also quite noticeable in real situations. Increasing the period would be fine for my use case I guess, it just seems very small at the moment.
I tried changing the value of 289 used in the permutation to something much higher, which did fix the periodicity problem, but it also introduced discontinuities in the noise function along diagonal lines. I guess it needs to be a real permutation polynomial rather than some number I made up, but I'm not sure how those values were constructed in the first place.
Here are code samples and results for both cases. It's just the fragment shader and I'm rendering a quad over the whole screen.
The text was updated successfully, but these errors were encountered: