-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
noise() is not Perlin noise #7430
Comments
Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, please make sure to fill out the inputs in the issue forms. Thank you! |
Hi, thank you pointing out the differences between the current implementation and traditional Perlin noise. I tried to fix it, and this is what i did, please review them:
My Solution 👇
|
@subhraneel2005 that was quick :) I haven't reviewed your code (yet). I want to emphasize that transitioning to Perlin noise in p5.js could have unintended side effects. One concern is the zero-noise-at-grid-locations issue: if you generate a noise image by sampling positions that fall on integer grid locations (e.g., exact pixel locations), the noise values will be all zeros. From a first glance, your implementation generates gradient vectors that are always 2-dimensional. From a scientific perspective, gradients should have the same number of dimensions as the surrounding space. Also, in https://mrl.cs.nyu.edu/~perlin/paper445.pdf the gradients aren't chosen to be random, but rather pre-defined to avoid artefacts. |
The implementation in p5.js comes directly from Processing and I believe the intention is for a more useful noise function that is random based. It is fine to edit the documentation to indicate this minor difference but I don't think we will be changing the implementation. |
thanks for the insights |
alright then, i will not change any code implementaion. thanks for letting me know :) |
It's true that the p5 noise implementation is not quite Perlin noise, and is based on the Processing noise implementation (which I hear is based on demoscene code from 2001, possibly for code size or performance constraints that were more important when it was first added?) Anyway, this topic has definitely come up before, but there's balance we have to find with how complex we keep the reference. Especially in explaining what the deviation is -- talking about dot products with vector offsets seems maybe a little too much technical detail for the p5.js reference. One option might be to use actual Perlin noise, although it has been brought up that, at this point, being able to use the same noise function that has been in Processing from the start is also kinda important. We've also thought about having different noise modes, where a library could possibly implement e.g. simplex noise. @limzykenneth @ksen0 let me know if you have any thoughts on this one! |
oh haha I see you added a comment in the mean time while Github was having issues |
@davepagurek, @limzykenneth Agreed. I think that changing the implementation is an overkill here - but I believe the deviations should be mentioned in case anyone is using p5.js for scientific visualizations. Probably one can shorten this to something along the lines:
Since processing and p5js is widely spread, this inaccuracy gets wide-spread. For example Kahn academy is teaching Perlin noise: https://www.khanacademy.org/computing/computer-programming/programming-natural-simulations/programming-noise/a/perlin-noise which is not Perlin noise :) |
I think I'm still in the camp that mentioning iso-contours is beyond the reading level of the target audience for the reference, which is more aimed at a grade school reading level, so my inclination would be to mention that p5's noise is "inspired by Perlin noise". It would be good to have the technical details somewhere though. One idea: maybe we could put a README.md in the src/math directory with a paragraph with the background and info in this thread, and then link to that from the reference? |
@davepagurek you may need to sift through examples as well. Its called Perlin noise at quite a few locations. |
Fascinating! I checked and the Processing documentation for
Are you telling me it's neither? 😅 (edit: some context for the above) As it turns out, both Processing and p5.js use a form of value noise:
I agree with @limzykenneth that we should keep the implementation as it is, especially given how central I'd suggest revising the documentation to include something like:
What do you think? DigressionsThe original inspiration was the demo "Art" by the German demoscene group Farbrausch. The source code is available in a file deceptively called Interestingly, the Wikipedia page for value noise notes:
|
@SableRaf , I believe As previously mentioned, I agree that re-writing the implementation solely to align with the documentation would be misguided. Gradient noise possesses unique properties that might surprise your user base. However, it also offers distinct advantages over value noise. Notably, gradient noise places greater emphasis on higher frequencies compared to lower frequencies, which helps to reduce the prevalence of flat areas in the noise landscape. Side note, the hash function used in the current implementation may additionally limit the randomness of the output (see #7431). As @davepagurek suggested, providing a link to this discussion or a page with detailed clarifications would be a good starting point for readers seeking more information. |
For added context, this has been discussed within Processing in the past: Perlin noise documentation #51 A |
Good catch @cheind! Yeah, I probably went too far with connecting the reference to an important bit of history -- agreed that I should have just corrected the inaccuracy. @SableRaf's suggested revision strikes a nice balance. I believe there's one minor typo:
|
@nickmcintyre these things happen all the time :) Right now, I'm sifting through the 1985 original paper to double-check and indeed he introduces a random value
So who knows what's truly Perlin noise after all :) |
The real Perlin noise is the friends you make along the way ;) |
Just to give a little more historic perspective here: I ported that Farbrausch code for processing.core back in summer 2003. Back then there:
Sorry for any inconvenience caused, heh! :) |
Thanks @postspectacular for the historical context! Grateful you took the time to share 😃 |
I talked to Casey about this earlier today. He didn't remember as much as Karsten, but he had a good suggestion regarding the documentation. Do mention at some point that there are different kinds of |
While we're going down rabbit holes, here's another one. The claim on the p5.js documentation that noise was "invented by Ken Perlin while animating the original Tron film in the 1980s" seemed suspicious, especially since the Wikipedia page for Perlin noise (likely source for that factoid) says Perlin invented Besides, the 3D models in TRON don't have any textures 🤔 So I had a look at the source for that reference: In the beginning: The Pixel Stream Editor, in Chapter 4 of this SIGGRAPH 2002 Course Notes on Real-Time Shading Languages. Here is what Ken Perlin writes (with added ellipses for concision):
How cool is that? In summary, Perlin started to think seriously about procedural textures while working on Tron in 1981, precisely because they could not use regular textures. Only later—in 1983—did he develop the So in conclusion, it seems very probable that Ken Perlin did NOT invent Thank you for PS: On a side note, it's funny to see that Perlin noise is still being used in the exact way it was intended:
|
For those interested, I reached out to Ken for historical clarification. In particular on the scalar I keep everyone posted, once I receive a reply (or maybe he finds the time to post here). |
Hey, as noted in #7430 (comment), I kindly asked Ken Perlin to clarify the following point
to which Ken replied (quoting with permission)
Wishing everyone a smooth start into the new year. |
noise() is not Perlin noise
Hi,
I've been browsing the documentation of the noise function
and continued to study its implementation. From a first sight, I believe that the implementation found in p5.js deviates from Perlin noise in two characteristics:
Perlin noise defines gradients at integer grid locations
The noise value associated with a grid locations is given by the dot-product between the stored gradient and the offset vector. If I read your implementation correctly, you are directly assigning a random value to each integer location that is later interpolated.
Perlin noise is zero at all integer grid locations
if the dot-product becomes zero, either because of orthogonality between the gradient direction and the offset vector or because the offset vector is zero (at integer locations), the resulting noise value becomes zero. Hence, at integer locations the resulting noise should be zero. See https://en.wikipedia.org/wiki/Perlin_noise. In p5.js
noise(x=0,0,0)
will not return a zero noise value in general.Hence,
noise()
provides smooth noise, but not Perlin noise. I don't believe that's an issue for the intended audience, but in case one relies on the above Perlin characteristics to hold true, you should mentioned the deviations in the docs.The text was updated successfully, but these errors were encountered: