Jump to content
  • Advertisement
Sign in to follow this  
jdub

Help Me With My 3D Perlin Noise

This topic is 2648 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

Here's a link to a video of it:


Although it might be kind of hard to make out in the vid, my noise function looks like a slideshow in that it has a smooth blurry transition. However, I'm not getting the smooth flowing noise that I should be getting... Is anything obviously wrong with my implementation from looking at the video?

Here is the relevant code for my noise implementation (Sorry, it is a little hard to read. I might clean it up and repost in a little while):



//The main noise function

public static double Noise(int x, int y, double z)
{
int numLevels = 3;
double frequency = 1d;
double amplitude = 1d;
double persistence = 0.5d;
double level = 1d/ Math.Pow(2, numLevels - 1);
double value = 0;

//create each level
for (int i = 0; i < numLevels; i++)
{
value += noiseAtLvl(x , y , z , frequency * level, amplitude);

frequency *= 2d;
amplitude *= persistence;
level *= 2d;
}

return value;
}

private static double noiseAtLvl(double x, double y, double z, double frequency, double amplitude)
{
return interpolateNoise3D(x * frequency, y * frequency, z) * amplitude;
}

/// <summary>
/// Smooth a point based on the colors of its surrounding pixels and a little randomness
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private static double smoothNoise3D(int x, int y, int z)
{
//lvl 0 The noise level below the current one
double corners0 = (noise3D(x - 1, y - 1, z - 1) + noise3D(x + 1, y - 1, z - 1) + noise3D(x + 1, y + 1, z - 1) + noise3D(x - 1, y + 1, z - 1)) / 16d;
double sides0 = (noise3D(x + 1, y, z - 1) + noise3D(x - 1, y, z - 1) + noise3D(x, y + 1, z - 1) + noise3D(x, y - 1, z - 1)) / 8d;
double pix0 = noise3D(x, y, z - 1) / 4d;

double level0 = corners0 + sides0 + pix0;

//lvl current
double corners = (noise3D(x - 1, y - 1, z) + noise3D(x + 1, y - 1, z) + noise3D(x + 1, y + 1, z) + noise3D(x - 1, y + 1, z)) / 16d;
double sides = (noise3D(x + 1, y, z) + noise3D(x - 1, y, z) + noise3D(x, y + 1, z) + noise3D(x, y - 1, z)) / 8d;
double pix = noise3D(x, y, z) / 4d;

double levelCurrent = corners + sides + pix;

//lvl 1 The noise level above the current one
double corners1 = (noise3D(x - 1, y - 1, z + 1) + noise3D(x + 1, y - 1, z + 1) + noise3D(x + 1, y + 1, z + 1) + noise3D(x - 1, y + 1, z + 1)) / 16d;
double sides1 = (noise3D(x + 1, y, z + 1) + noise3D(x - 1, y, z + 1) + noise3D(x, y + 1, z + 1) + noise3D(x, y - 1, z + 1)) /8d;
double pix1 = noise3D(x, y, z + 1) / 4d;

double level1 = corners1 + sides1 + pix1;

return ( ( level0 / 3d) + (levelCurrent / 3d ) + (level1 / 3d) );
}

/// <summary>
/// Smooth noise point more through interpolation
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
private static double interpolateNoise3D(double x, double y, double z)
{
int intX = (int)Math.Floor(x);
int intY = (int)Math.Floor(y);
int intZ = (int)Math.Floor(z);

double fractionX = x - intX;
double fractionY = y - intY;
double fractionZ = z - intZ;

double ulcorner0 = smoothNoise3D(intX, intY, intZ);
double urcorner0 = smoothNoise3D(intX + 1, intY, intZ);
double blcorner0 = smoothNoise3D(intX, intY + 1, intZ);
double brcorner0 = smoothNoise3D(intX + 1, intY + 1, intZ);
double xlvl0_1 = cosInterpolate(ulcorner0, urcorner0, fractionX);
double xlvl0_2 = cosInterpolate(blcorner0, brcorner0, fractionX);

double lvl0 = cosInterpolate(xlvl0_1, xlvl0_2, fractionY);

double ulcorner1 = smoothNoise3D(intX, intY, intZ + 1);
double urcorner1 = smoothNoise3D(intX + 1, intY, intZ + 1);
double blcorner1 = smoothNoise3D(intX, intY + 1, intZ + 1);
double brcorner1 = smoothNoise3D(intX + 1, intY + 1, intZ + 1);
double xlvl1_1 = cosInterpolate(ulcorner1, urcorner1, fractionX);
double xlvl1_2 = cosInterpolate(blcorner1, brcorner1, fractionX);

double lvl1 = cosInterpolate(xlvl1_1, xlvl1_2, fractionY);

return cosInterpolate(lvl0, lvl1, fractionZ);
}

Share this post


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

  • Advertisement
×

Important Information

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

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!