• Create Account

# Perlin Noise gives too small values?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

4 replies to this topic

### #1N1ghtDr34m3r  Members   -  Reputation: 355

Like
0Likes
Like

Posted 04 August 2014 - 03:12 PM

Hello.

Today I've implemented a perlin noise algorithm with extra methods like pertubation and eroding to create a terrain.

I found the code for it here: Click me

After the "addPerlinNoise()" method, you can see 3 reference pictures on that page (in the middle), build with the frequencies 1.0f, 4.0f and 1.0f + 8.0f (without perturb or sth like that, just plain noise).

If I use a frequency of 4.0f, this is my output (plain noise): https://imgur.com/7OElD3n

And when I use 64.0f as my frequency, I get this: https://imgur.com/dqA04N6

Can you help me to achieve something like the reference pictures with the reference frequencies (1.0f, 4.0f, 1.0f + 8.0f)?

I only understand a little behind the maths of it, so I can't really do something to fix it.

The code on the linked site is in C#, mine is in C++.

The only things, which are different between my code and the code on the site is the following part:

void PerlinGenerator::initGradients()
{
//Type of random number distribution
std::uniform_real_distribution<float> dist(0.0f, 1.0f);  //(min, max)

//Mersenne Twister: Good quality random number generator
std::mt19937 rng;
//Initialize with non-deterministic seeds
rng.seed(std::random_device{}());

for (int i = 0; i < gradientTableSize; i++)
{
float z = 1.0f - 2.0f * dist(rng);
float r = (float)sqrt(1.0f - z * z);
float theta = 2 * (float)M_PI * dist(rng);
gradients[i * 3] = r * cos(theta);
gradients[i * 3 + 1] = r * sin(theta);
gradients[i * 3 + 2] = z;
}
}


Can it be the random double, which is used for the computing?

For the rendering I determine the vertex coordinates for a VBO like this and render it with glDrawElements(...) :

void Terrain::createVBO()
{
// Create vertex data
float *vertices = new float[3 * heightMap->size * heightMap->size];
float blockSize = 16.0f;
int vertex = 0;

for (int y = 0; y < heightMap->size; y++) {
for (int x = 0; x < heightMap->size; x++) {
vertices[vertex++] = x * blockSize;
vertices[vertex++] = y * blockSize;
vertices[vertex++] = heightMap->heights[y][x] * blockSize;
}
}

// Create index data
[...]

// Create VAO
[...]

// Create VBO
[...]

// Create EBO
[...]

// Handle vertex attributes in shader prog
[...]
}


Hopefully you can help me, thanks,

NightDreamer

Edited by N1ghtDr34m3r, 04 August 2014 - 04:11 PM.

### #2David Manzanares  Members   -  Reputation: 164

Like
6Likes
Like

Posted 05 August 2014 - 06:27 AM

I found some ugly things in your link: http://www.float4x4.net/index.php/2010/06/generating-realistic-and-playable-terrain-height-maps/

1. This is 3D perlin noise. However heightmaps should use 2D noise. Using 3D noise with heightmaps is useless, at the end you will be discarding one coordinate:  Heights[i, j] += Perlin.Noise(f * i / (float)Size, f * j / (float)Size, 0); Watch that zero, the third coordinate is useless. Using 3D perlin noise can work, but 2D noise is easier and cheaper(in terms of performance).
2. The smooth function use the old 3p² - 2p³. However this is not C2 (it is C1), it should be 6p^5-15p^4+10p^3 (http://mrl.nyu.edu/~perlin/paper445.pdf)
3. The implementation uses a permutation table. This is a performance optimization. However for a 2D noise generator I will use a simple gradient table, without permutations.
4. I think that the way InitGradients initialize the gradients is complex and performance expensive. Try this:
Rng rng=new rng(-1,1);//Random numbers on [-1,1] interval
vec3 g=(rng.next(),rng.next(),rng.next());
g=normalize(g);


I prefer this Perlin noise reference: http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html I think that this link is very comprehensible.

• Your second picture looks good. Noise won't be noticeable if the frecuency is too high compared to the vertex density (vertex/triangles per unit²).
• Even though your second picture looks good you may want more abrupt terrain. Try increasing the amplitude:
public void AddPerlinNoise(float f, float amplitude)
{
for (int i = 0; i < Size; i++)
{
for (int j = 0; j < Size; j++)
{
Heights[i, j] += amplitude*Perlin.Noise(f * i / (float)Size, f * j / (float)Size, 0);
}
}
}



Developer of Raiseland, a real-time procedural terrain generator. Check out our Greenlight: http://steamcommunity.com/sharedfiles/filedetails/?id=280019434

### #3N1ghtDr34m3r  Members   -  Reputation: 355

Like
0Likes
Like

Posted 08 August 2014 - 09:44 AM

Thank you very much for replying.

This is 3D perlin noise. However heightmaps should use 2D noise. Using 3D noise with heightmaps is useless, at the end you will be discarding one coordinate:  Heights[i, j] += Perlin.Noise(f * i / (float)Size, f * j / (float)Size, 0); Watch that zero, the third coordinate is useless. Using 3D perlin noise can work, but 2D noise is easier and cheaper(in terms of performance).

Alright, I think I will implement 2D noise.

The smooth function use the old 3p² - 2p³. However this is not C2 (it is C1), it should be 6p^5-15p^4+10p^3 (http://mrl.nyu.edu/~perlin/paper445.pdf)

I don't know, what you mean by "C2 (it is C1)". Would you explain that to me?

I prefer this Perlin noise reference: http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html I think that this link is very comprehensible.

Thank you very much. I'll have a look at it and try it out.

Edited by N1ghtDr34m3r, 08 August 2014 - 09:44 AM.

### #4samoth  Crossbones+   -  Reputation: 7998

Like
2Likes
Like

Posted 08 August 2014 - 11:27 AM

I don't know, what you mean by "C2 (it is C1)". Would you explain that to me? rolleyes.gif
C0 = points are connected, no holes (basically a polyline)

C1 = tangents (the "first derivative") interpolate smoothly (e.g. a typica cubic spline)

C2 = tangents interpolate smoothly and curvature (the "second derivtative") is smooth, too.

In particular, in this case it means that the second derivative is zero both for t = 0 and t = 1. The difference between C1 and C2 appears to be not so important, after all, the curve is "smooth" either way. However, it becomes grossly visible once you do something like e.g. bump mapping. C1 will give you nasty artifacts.

### #5N1ghtDr34m3r  Members   -  Reputation: 355

Like
0Likes
Like

Posted 11 August 2014 - 01:51 PM

Ah, okay, thank you very much!
Due to the word "derivative" I now know what you meant.
Just didn't know, that you can name it as C0/C1/...
In university, we only use "derivative"...

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS