Razaekel / noise-rs

Procedural noise generation library for Rust.
Apache License 2.0
855 stars 120 forks source link

open_simplex2 shows triangular artifacts #141

Open Stoeoef opened 8 years ago

Stoeoef commented 8 years ago

open_simplex2 shows some triangular artifacts, see the following image:

open_simplex

The noise function is not smooth at the edges of the open simplex triangle grid. The shown surface is a regular grid, its height is given by a function call similar to noise::open_simplex2(&seed, coord) * 0.5

Maybe there are some rounding issues at the triangle borders? These artifacts do not occur when using perlin2. The artifacts remain even when I switched to other randomly generated seeds, so this should be reproducible.

Stoeoef commented 8 years ago

Oh, I forgot: the artifacts are visible on version 0.2.0 and on a current github checkout.

mystise commented 7 years ago

So it turns out this is because Open Simplex surflets have a slightly larger radius than one simplex, and as such vertices outside the current simplex have to be taken into account for certain places.

Funnily enough, this was previously discovered in this library in early 2015. No idea what happened to the Open Simplex extra vertices in between then and now, but they seem to have been removed (or never implemented for 4D, not sure):

I have a partial fix implemented in https://github.com/adudney/noise-rs/tree/opensimplex_extra_vertices

2D and 3D are finished, but 4D is going to be painful just because of the sheer amount of extra vertices you have to take into account. Honestly at this point I'm considering just giving up on this and implementing Super Simplex noise, it seems like a much simpler implementation and it handles all this stuff in for loops rather than complex branching logic. I'll make a PR with the current state if I decide to do this, so that at least 2D and 3D can be fixed.

Note additionally that this not only makes the code more complex, it also makes it slower. This is required for a correct implementation however, as what is currently implemented is incomplete, the extra vertices are part of the original Open Simplex implementation here: https://gist.github.com/KdotJPG/b1270127455a94ac5d19

Edit: Found the pull request: https://github.com/brendanzab/noise-rs/pull/55 "superfluous" is correct only if you don't care about having a continuous function and/or derivative :P I don't blame them though, this is a really hard bug both to notice and to maintain the fix for. (The branching logic for determining closest points is incredibly confusing, and only gets worse the more dimensions you add)

vallentin commented 5 years ago

@adudney any progress with the PR?

Was about to post an issue, before I found this. I noticed something was off. Scaled it up and sampled a bit more "extremely" and suddenly I had the same triangle artifacts.

Cazadorro commented 5 years ago

@adudney What is super simplex noise?

mystise commented 4 years ago

@vallentin It's been a while so I'm a bit fuzzy, but I'm pretty sure I abandoned OpenSimplex in favor of SuperSimplex

EDIT: or, as per my comment above, just revert: https://github.com/Razaekel/noise-rs/pull/55 which will put it back into the correct but slower state it was originally in.

@Cazadorro SuperSimplex is not described in a blog post or anything, it was merely another algorithm from the same person behind OpenSimplex, that as far as I recall, doesn't have the same triangular artifacts.

The only source for SuperSimplex is a single java file linked in their reddit history:

https://www.reddit.com/r/proceduralgeneration/comments/dfs9fv/procedural_rivers_4km_8km_long_that_change/f35x9pr/

https://www.reddit.com/r/proceduralgeneration/comments/97lnvp/is_analytical_integration_of_perlin_noise_possible/e4i64pi/

vjackson725 commented 3 years ago

Can confirm this is still a problem.

Image of Triangular Artifacts in The Derivative of OpenSimplex

I encountered this problem when I was approximating the derivative of each cell by summing the scaled direction to each cell's neighbours, then taking the angle of the resulting vector.

Git Repo

vjackson725 commented 3 years ago

Ah. After looking at it a bit more, it seems the answer is (if you want 2d/3d noise) use SuperSimplex, which has been implemented in noise-rs now (#168).