private float Noise( float x, float y, float z )
{
// Find unit cube that contains point
int iX = ( int )Math.Floor( x ) & 255;
int iY = ( int )Math.Floor( y ) & 255;
int iZ = ( int )Math.Floor( z ) & 255;
// Find relative x, y, z of the point in the cube.
x -= ( float )Math.Floor( x );
y -= ( float )Math.Floor( y );
z -= ( float )Math.Floor( z );
// Compute fade curves for each of x, y, z
float u = Fade( x );
float v = Fade( y );
float w = Fade( z );
// Hash coordinates of the 8 cube corners
int a = p[iX] + iY;
int aa = p[a] + iZ;
int ab = p[a + 1] + iZ;
int b = p[iX + 1] + iY;
int ba = p[b] + iZ;
int bb = p[b + 1] + iZ;
// And add blended results from 8 corners of cube.
return Lerp( w, Lerp( v, Lerp( u, Grad( p[aa], x, y, z ),
Grad( p[ba], x - 1, y, z ) ),
Lerp( u, Grad( p[ab], x, y - 1, z ),
Grad( p[bb], x - 1, y - 1, z ) ) ),
Lerp( v, Lerp( u, Grad( p[aa + 1], x, y, z - 1 ),
Grad( p[ba + 1], x - 1, y, z - 1 ) ),
Lerp( u, Grad( p[ab + 1], x, y - 1, z - 1 ),
Grad( p[bb + 1], x - 1, y - 1, z - 1 ) ) ) );
}