Jump to content

  • Log In with Google      Sign In   
  • 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.

  • You cannot reply to this topic
4 replies to this topic

#1 N1ghtDr34m3r   Members   -  Reputation: 152

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. smile.png

I found the code for it here: Click me smile.png

 

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. sad.png

 

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.


Sponsor:

#2 David Manzanares   Members   -  Reputation: 161

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.

 

About your particular problem:

  • 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


#3 N1ghtDr34m3r   Members   -  Reputation: 152

Like
0Likes
Like

Posted 08 August 2014 - 09:44 AM

Thank you very much for replying. wink.png 

 

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. smile.png

 

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? rolleyes.gif

 

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. biggrin.png


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


#4 samoth   Crossbones+   -  Reputation: 5038

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.



#5 N1ghtDr34m3r   Members   -  Reputation: 152

Like
0Likes
Like

Posted 11 August 2014 - 01:51 PM

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






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