/// <summary> /// Smooths a noise field. /// </summary> /// <param name="whiteNoise">Noise field to smooth.</param> /// <param name="octave">The current octave.</param> /// <returns></returns> public NoiseField <float> SmoothNoiseField(NoiseField <float> whiteNoise, int octave) { NoiseField <float> smooth = new NoiseField <float>(whiteNoise.Width, whiteNoise.Height); int samplePeriod = 1 << octave; float sampleFrequency = 1.0f / samplePeriod; for (int x = 0; x < smooth.Width; x++) { int sampleX1 = (x / samplePeriod) * samplePeriod; int sampleX2 = (sampleX1 + samplePeriod) % smooth.Width; float horizontalBlend = (x - sampleX1) * sampleFrequency; for (int y = 0; y < smooth.Height; y++) { int sampleY1 = (y / samplePeriod) * samplePeriod; int sampleY2 = (sampleY1 + samplePeriod) % smooth.Height; float verticalBlend = (y - sampleY1) * sampleFrequency; float top = Interpolation(whiteNoise.Field[sampleX1, sampleY1], whiteNoise.Field[sampleX2, sampleY1], horizontalBlend); float bottom = Interpolation(whiteNoise.Field[sampleX1, sampleY2], whiteNoise.Field[sampleX2, sampleY2], horizontalBlend); smooth.Field[x, y] = Interpolation(top, bottom, verticalBlend); } } return(smooth); }
/// <summary> /// Generates wa field of white noise (random noise) /// </summary> /// <param name="width">Width of the field</param> /// <param name="height">Height of the field</param> /// <param name="random">Random number generator to use. Can be pre-seeded.</param> /// <returns></returns> public NoiseField <float> GenerateWhiteNoise(int width, int height, Random random) { NoiseField <float> field = new NoiseField <float>(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { field.Field[x, y] = (float)random.NextDouble() % 1; } } return(field); }
/// <summary> /// Generates a new Perlin Noise field. /// </summary> /// <param name="baseNoise">Base noise to use. Should be white noise.</param> /// <param name="octaveCount">Number of octaves to go over (number of fields to average)</param> /// <param name="persistence">Persistence factor</param> /// <returns></returns> public NoiseField <float> PerlinNoiseField(NoiseField <float> baseNoise) { NoiseField <float>[] smoothNoise = new NoiseField <float> [OctaveCount]; for (int i = 0; i < OctaveCount; i++) { smoothNoise[i] = SmoothNoiseField(baseNoise, i); } NoiseField <float> perlinNoise = new NoiseField <float>(baseNoise.Width, baseNoise.Height); float amplitude = 1.0f; float totalAmplitude = 0.0f; for (int octave = OctaveCount - 1; octave >= 0; octave--) { amplitude *= Persistence; totalAmplitude += amplitude; for (int x = 0; x < baseNoise.Width; x++) { for (int y = 0; y < baseNoise.Height; y++) { perlinNoise.Field[x, y] += smoothNoise[octave].Field[x, y] * amplitude; } } } // Normalize the fields for (int x = 0; x < baseNoise.Width; x++) { for (int y = 0; y < baseNoise.Height; y++) { perlinNoise.Field[x, y] /= totalAmplitude; } } return(perlinNoise); }
/// <summary> /// Performs all steps using cosineInterpolation for a new perlin noise. /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="octaveCount"></param> /// <param name="persistence"></param> /// <returns></returns> public NoiseField <float> GeneratePerlinNoise(int width, int height) { NoiseField <float> whiteNoise = GenerateWhiteNoise(width, height); return(PerlinNoiseField(whiteNoise)); }
/// <summary> /// Performs all steps using cosineInterpolation for a new perlin noise. /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="octaveCount"></param> /// <param name="persistence"></param> /// <returns></returns> public NoiseField <float> GeneratePerlinNoise(int width, int height, int x_start_coord, int y_start_coord) { NoiseField <float> whiteNoise = GenerateWhiteNoise(width, height, x_start_coord, y_start_coord); return(PerlinNoiseField(whiteNoise)); }