Sign in to follow this  
jdub

Help Me With My 3D Perlin Noise

Recommended Posts

Here's a link to a video of it: [url="http://www.youtube.com/watch?v=r1kfJ4JWN_Q"]http://www.youtube.com/watch?v=r1kfJ4JWN_Q[/url]

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):

[code]

//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);
}
[/code]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this