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

Worley noise has incomplete kernels #176

Open
tayloraswift opened this issue Jun 8, 2017 · 3 comments
Open

Worley noise has incomplete kernels #176

tayloraswift opened this issue Jun 8, 2017 · 3 comments

Comments

@tayloraswift
Copy link

tayloraswift commented Jun 8, 2017

Sampling worley noise at half-kernels requires a minimum of eight generating points to be samples. Your library only wanders the control points around a disk of radius 0.5 instead of filling out the whole grid cell though, so it may be possible to only consider 6 points though I haven’t worked out the math.

    //          O ------- far
    //          |    |    |
    //          |----+----|
    //          |  * |    |
    //       near ------- O

    //               xb   xb + 1
    //          +------------------+
    //          |     |      |     |
    //       yb X---- O//////O ----|
    //          |     |//////|     |
    //   yb + 1 X---- O//////O ----|
    //          |     |      |     |
    //          +-----X------X-----+

The generating points marked with an X are missing from the kernel.

Here is an example of an artifact caused by this:

selection_020

@Razaekel
Copy link
Owner

Razaekel commented Jun 9, 2017

Thank you for pointing this out. Could you provide the settings that you used when you discovered this error?

The way a basic implementation of Worley noise is supposed to work is that it divides the sampled space into squares with a size of 1/frequency, and then places a point in a random location within each square. It then takes the point you're asking for, finds the square that it's located in, and tests the surrounding squares for the nearest points. This means that it should be checking 25 squares in 2d. This means in 2d, at least 9 squares need to be tested, if the point is exactly at the middle of the square, and up to 12 squares if the point is at the corner.

Thinking about it, the radius for 2d should be sqrt(2) (diagonal of a square), not 0.5. And 3d should be the diagonal of the cube, sqrt(3). And so on.

The Worley noise was a direct conversion of the older functional implementation. It wasn't checked for correctness.

@tayloraswift
Copy link
Author

tayloraswift commented Jun 9, 2017

Actually I discovered you need to consider exactly twelve points for 2D. See noise-swift:CellNoise2D for an explanation.

The screenshot I attached was given as an example of “correct” output in issue #175 (worley-linear-range_2d). It’s in the center-left of the image there.

3D forces us to expand the kernel to two layers in some cases, I haven’t worked it out. It is probably on the order of ~40 or so points…

@tayloraswift
Copy link
Author

tayloraswift commented Jun 9, 2017

Did the math. Exactly 90 cells must be considered for 3D worley noise. Early exit is possible if the cells are checked in groups in a certain order.

Working implementation: noise-swift:CellNoise3D › evaluate(:::)

Razaekel added a commit that referenced this issue Aug 20, 2023
Getting it working right would need more effort, easier to strip it out for now and maybe re-implement it later (or never)

Closes #175, #176
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants