Perlin noise implementation in p5.js

Hi.

I noticed the outcomes of noise() function in Processing and p5.js is different (setting the same seeds). Do they use different implementations? Why?

1 Like

Let’s take a look at the source!

You’ll have to ctrl-f “noise” to get to the definition:

As far as I can tell (on mobile :grimacing:) they use the same implementation, but use their own native Random-objects. In the end, a result of their environments.

1 Like
2 Likes

But I am getting different results (for the same seed). Try this simple code:

// PROCESSING CODE
float x = 0.0;

void setup() {
  noiseSeed(10);
  for(int i = 1; i <=10; i++) { 
   println(noise(x));
   x = x + 0.01;
  }
}
// P5.JS CODE
var x = 0.0;

function setup() {
  noiseSeed(0);
  for(var i = 1; i <=10; i++) { 
   console.log(noise(x));
   x = x + 0.01;
  }
}

I get different values from the two sketches (I am using Processing IDE):

// PROCESSING OUTPUT
0.6847784
0.68429047
0.682773
0.6802819
0.6769151
0.67296404
0.6680481
0.66287524
0.6574523
0.65191317
// P5.JS OUTPUT
0.224947028546012
0.22484679351723308
0.2245499223713059
0.2240676994293296
0.22341822023287683
0.2226253699109923
0.2217174816614504
0.22072575742505776
0.2196825472000809
0.21861959179466206

The two vectors do not differ for a constant and their ratio is not constant. Nevertheless, they are positively correlated (Perason 0.9999822).

@HEX0x6C We need to look into formatting the code properly in this forum. Do you know how to do that?

Kf

No. I do not. Thanks for telling.

Please format your code :blush:

It consist on these two steps:

  1. In your code editor (PDE, VS code, Eclipse, etc) ensure you execute the beautifier function. This function automatically indents your code. Auto-indenting makes your code easier to read and helps catching bugs due to mismatch parenthesis, for instance. In the PDE, you use the key combination: ctrl+t
  2. You copy and paste your code in the forum. Then you select the code and you hit the formatting button aka. the button with this symbol: </>

That’s it! Please notice you do not create a new post in case you need to format something you already posted. You can edit your post, copy the code to the PDE, indent the code properly there and then past it back here, format the code and >> save << the edits.

Extra info:

Formatting your code makes everybody’s life easier, your code looks much better plus it ensures your code integrity is not affected by the forum’s formatting (Do you know the forum processes markup code?) Please visit the sticky posts or the FAQ section/post to learn about this, other advantages and super powers you can get in this brand new forum.

Kf

On the surface it may look identical, but we have to ask ourselves “what is being seeded?”

Java is calling this:
perlin[i] = Math.random();

while JavaScript is calling this:
perlinRandom = new Random();

I assume that Java and JS implement random seeding differently.

1 Like

All right, I did it. Thanks for your patience.

I think (I am not an expert on JavaScript random) that the issue here isn’t a Java vs JavaScript implementation of a PRNG (pseudo-random number generator)…

…it is Java vs Chrome vs Firefox vs Safari vs Opera vs etc.

So now the question is: what PRNG does JavaScript use?
The answer: none.
It’s up to the browser

From: How does JavaScript’s Math.random() generate random numbers?

If you want to be able to have specific random seeds produce the exact same effect across Java and JavaScript, and if high-quality randomness is not important to you, then one approach might be to implement your own very simple PRNG in-code in both the Java and JavaScript sketches, and completely ignore the respective language built-in random() / Math.random().

For examples and discussion of simple LCG algorithms for PRNGs, see:

2 Likes

So, thinking about this a little further, your essential issue is that noiseSeed() and noise() in Java are both built on java.util.Random() – and you can’t route around those internal initialization calls, even by providing your own series seeds generated by your own a non-Java source.

So, in addition to needing a cross-platform RPNG for seeds, I believe (?) (on quick inspection) that you cannot then to manually iterate a seed and pass each to noise. Instead, as the library currently stands you would also would also have to write your own Perlin functions.

If you want to start with a cross-language PNRG, I would recommend starting with an extremely simple LCG that is already implemented in Python / Java / JavaScript and gives the same results in each. See this answer re XorShift:

Note however that the given solution for Java is actually returning a long, not an int (!) There is no such thing as a primitive 32-bit unsigned int in Java.

1 Like

Okay, I have posted a preliminary cross-language implementation for random / randomSeed, here:

There is no noise / noiseSeed included yet, but that might be built on top of it.

3 Likes

Wow, this is awesome! Thanks for your endeavor!

Glad you like it – thanks for sharing an interesting problem. I would also be curious to hear more about what your application is for cross-language noise.

Good luck, and if you can build on it, please share!

My app is here. Originally I developed it in Processing. Then, I noticed that the sketches in P5.js and Processing generate different coils for the same hash string, hence I posted the question.

Thank you.