Jump to content
  • Advertisement
Sign in to follow this  
hupsilardee

Perlin Noise

This topic is 2639 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey everybody. I have written a Perlin noise generator. The texture created is used as a VTF source for a terrain, and another function has already created the normal map, so I can have large terrains with only two bytes per vertex. However, the noise this function is creating is a little too sharp, so I wondered if there was a way of smoothing the results?


IDirect3DTexture9* CreatePerlinNoise(unsigned short size, int numOctaves)
{
IDirect3DTexture9* pTexture = NULL;
HRESULT hr = pd3dDevice->CreateTexture(size, size, 1, 0, D3DFMT_R32F, D3DPOOL_MANAGED, &pTexture, NULL);
if (FAILED(hr))
return NULL;

float* pData;
D3DLOCKED_RECT lr;
pTexture->LockRect(0, &lr, NULL, 0);
pData = (float*)lr.pBits;
ZeroMemory(pData, sizeof(float) * size * size);

float maxStrength = 1.f / (float)numOctaves;
for (int numblocks = 1; numblocks < numOctaves; numblocks++)
{
int blocksize = size / numblocks;
for (int x = 0; x < numblocks; x++)
{
for (int y = 0; y < numblocks; y++)
{
float amount = randf() * maxStrength;
for (int xx = 0; xx < blocksize; xx++)
{
for (int yy = 0; yy < blocksize; yy++)
{
int pixelX = x * blocksize + xx;
int pixelY = y * blocksize + yy;
pData[pixelX * size + pixelY] += amount;
}
}
}
}
}

pTexture->UnlockRect(0);

return pTexture;
}


If not I guess I could just make a gaussian blur function to go with this.

Share this post


Link to post
Share on other sites
Advertisement
Standard fBm Perlin Noise will attenuate the signal added by each successive octave, making it so that deeper octaves contribute less over all signal. In your posted code, you are attenuating amount by maxStrength, but maxStrength never changes. So each octave will contribute the same amplitude of signal as the preceding octaves, meaning that the result will in fact approach the level of white noise. A solution would be to reduce maxStrength each octave by some amount (usually determined by the frequency of the octave; ie divide it by two each successive octave).

More importantly, there is no smoothing of noise signals being done at all in your code. You are generating your noise as successive layers of white noise. And if you add white noise to white noise, you'll get white noise regardless of how the octaves are attenuated. Perlin noise is properly constructed out of randomized waveforms, where the waveforms themselves are smooth and continuous, despite the fact that the wave crests and valleys are of randomized amplitude. A waveform is smoothed by interpolating the generated wave crests and valleys, to generate the intermediate values along the curve of the wave. The frequency of each successive octave in a typical Perlin fractal is twice the frequency of the preceding octave. In this way, ever smaller and more tightly packed "features" are added in to the waveform.

You might want to read the description at http://freespace.vir...ls/m_perlin.htm to understand it better. (Although be aware that the noise discussed at this link is not actually correctly called Perlin noise. It is randomized continuous noise, of course, but true Perlin noise will be of the gradient or simplex varieties that Perlin himself devised. Still, the explanation at that link is fairly good.)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!