Skip to content
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

Fix scaling in OpenSimplex #149

Open
Razaekel opened this issue Mar 2, 2017 · 7 comments
Open

Fix scaling in OpenSimplex #149

Razaekel opened this issue Mar 2, 2017 · 7 comments
Labels

Comments

@Razaekel
Copy link
Owner

Razaekel commented Mar 2, 2017

As mentioned in #102 the output range of OpenSimplex needs to be fixed.

@Razaekel Razaekel added the bug label Mar 2, 2017
@jeffparsons
Copy link
Contributor

I would very much like to be able to rely on output values being within a known range. I believe I just ran into this after assuming ~[-1, +1]. 😅

@Razaekel
Copy link
Owner Author

Razaekel commented May 5, 2017

Mathematically calculating the output range for OpenSimplex is not easy. The range for Perlin was produced through trial-and-error, essentially. See #96.

The same work would need to be done for OpenSimplex, unless somebody can derive the actual result range based on the implementation.

@mystise
Copy link
Contributor

mystise commented Jun 3, 2017

As a possible alternative in the meantime until further work is done, Super Simplex (added in 051f8f7) is scaled to [-1, 1] as close as is possible with f64 precision. It's only implemented in 2D and 3D, as no 4D reference implementation exists. So if you only need 2D and 3D noise, Super Simplex has a much better range than Open Simplex at the moment.

As for Open Simplex, I have done the math and rescaled 2D in my branch (https://github.com/adudney/noise-rs/tree/opensimplex_extra_vertices), but it's heavily in development and doesn't have 3D or 4D scaling factors fixed yet. The math on them is quite a bit more annoying than the math was for Super Simplex, so I'm not certain if it'll be possible to compute them like I did with 2D and Super Simplex.

@BenWiederhake
Copy link
Contributor

BenWiederhake commented Apr 27, 2018

On the general topic of scaling: both input and output scales vary significantly between the implementations in this library. It's not possible to "just try something out" and expect a good result.

I tried to get an overview of the 2D-functions in this crate: sideways CDF plot of various noise functions
More specifically their output ranges, and it's rather surprising: OpenSimplex and fbm are not scaled to anything in particular, Billow's range is negative for no obvious reason. RidgedMulti maybe has a good reason, but is surprising anyway. Supersimplex looks wonky towards the extremes, and that's not due to precision loss (I only sample on the square of (0,0)×(65535,65535)).

EDIT: I forgot to annotate the axes. Y is the output value. X is the sample number, after the samples have been sorted. So if you scale X to [0%, 100%], then it's a plot of percentiles. So the left-most value tells you the minimum (0th percentile), the right-most value tells you the maximum (100th percentile), the middle tells you the median (50th percentile), and so forth. END EDIT

Here's the code.

Suggestion for this or #22: Document output range, document input scale, and ideally set sane defaults so that all of these are identical.

@Razaekel
Copy link
Owner Author

Razaekel commented Apr 28, 2018

Ideally, we'd have a formal proof of the range for each of the generators, similar to what's done for Perlin here: http://digitalfreepen.com/2017/06/20/range-perlin-noise.html. Then we'd have a solid mathematical backing for the procedural functions with well-defined effects from varying the inputs and coefficients.

@Cazadorro
Copy link

Finally, people just act like the distributions of these coherent noise functions are fine with out actually testing it first. This is a problem all noise libraries seem to have. I'm not sure formal proof is necessary though more than testing enough to have a good confidence interval of the true distribution. You are going to run into issues with many functions trying to find proofs of them when many aren't "nice" like perlin noise is.

@mystise
Copy link
Contributor

mystise commented Apr 28, 2018

I can't speak for any of the other generators, but I can at least speak for SuperSimplex. While I don't have formal mathematical proof, I did use Mathematica to find the min & max as accurately as possible in a float 64, so as long as my math is correct it should be impossible for the noise to ever generate something outside of the range [-1,1], although I make no guarantees as to the usual distribution of output values within that range 😊

Note also that the min & max were calculated with a certain set of gradients and would have to be re-calculated if the gradients were to ever change. Taking a quick glance, I don't think the gradients have changed since I checked in SuperSimplex, so the min & max should still be valid.

The Mathematica code (and some reasoning behind it) is present in this file: https://github.com/Razaekel/noise-rs/blob/develop/examples/super_simplex.rs#L120

As to the weirdness in the graph, I can't tell for certain that it's an issue? All that I understand the graph to say is that of the filtered, sorted list of samples on integer X,Y coords, the seed you chose doesn't have a smooth distribution of values outside a certain range ([-0.3,0.3] or so). If this were to actually manifest as discontinuities in the output that would be a concern, but I believe the samples are too far apart to determine that.

As for input scale on SuperSimplex: There is no internal scaling of coordinates. However, since SuperSimplex noise is based on a skewed grid, plotting SuperSimplex and (for example) Perlin on top of each other will appear to be different scales.

Hope this helps!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants