Razaekel / noise-rs

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

What is the amplitude of a BrownianX? #102

Closed Binero closed 7 years ago

Binero commented 8 years ago

How do I change the aplitude of a BrownianX noise generator. I am running a Brownian2 with a open_simplex2 noise generator. After generating 65,536 values, I found these statistics:

min: -1.0851247
avg: -0.005162108
max: 0.96951514

Am I to assume the aplitude here was 1? Is the fact that the min is slightly below -1 just a rounding error? It it always 1?

brendanzab commented 8 years ago

Could you try it with the current master branch? You can do this using:

noise = { git = "https://github.com/bjz/noise-rs.git" }

We've done some work on the algorithm, but I'm yet to publish it yet. Let me know if this fixes things!

Binero commented 8 years ago

For perlin2:

min: -1
avg: -0.00012103994
max: 1

For open_simplex2:

min: -0.54393464
avg: 0.00005978137
max: 0.5439705

For perlin2 using Brownian with 4 quads, no set wavelength:

min: -0.8027274
avg: -0.000063343985
max: 0.7899839

For open_simplex2 using Brownian with 4 quads, no set wavelength:

min: -0.51776856
avg: -0.0000017186136
max: 0.49948424
brendanzab commented 8 years ago

Is this a more expected result for you?

cc. @amaranth @Aatch

Aatch commented 8 years ago

What do you mean by "quads" here?

Aatch commented 8 years ago

So I took a look at this and am pretty sure it's expected.

Brownian noise is generated by taking a noise function then scaling it and adding it back in. Specifically, the default doubles the frequency each step and halves the amplitude. At the end, it then scales result by the sum of the amplitudes (basically taking a weighted average of the values). Intuitively, it seems that the range for brownian noise should be the same as the input noise, since if you got the maximum for each octave you'd have 1 + 0.5 + 0.25 + 0.125... which would be divided by 1 + 0.5 + 0.25 + 0.125...

However, the way perlin noise and brownian noise work means that is never going to happen. Assuming that you're sampling a (0, 0) - (1, 1) square with the lowest frequency being 1, if that grid square contains the maximum value possible, it must be in the middle of the square, (0.5, 0.5). However, this means that the next sample will be at a grid point (1, 1), which is always 0 (or close to it). So the maximum value at that point actually tends towards 0.5 as the number of octaves increases. Instead, the maximum possible value is actually elsewhere, but figuring out where is quite difficult. Similarly figuring out what that value should be is difficult.

I think the values you have there are about right. I'd probably need a maths degree to properly understand why though.

brendanzab commented 8 years ago

Ok, I'm going to stop procrastinating and actually publish v0.2.0 now! >_>

Binero commented 8 years ago

@Aatch I'm still confused on what the amplitude of open_simplex2 would be though. It's not a neat -1 or +1 like perlin, nor does it have the issue of multiple 'layers' Brownian has.

amaranth commented 8 years ago

The open simplex implementation is in need of a cleanup and fixing to scale the output to fit the desired -1 to 1 range like perlin does.

Razaekel commented 7 years ago

Closing since it was apparently fixed in v0.2.0.