public PerlinNoise(int octaves, float amplitude, float roughness, Vector2 offset, NormaliseMode normaliseMode)
    {
        this.seed          = new System.Random().Next(1000000000);
        this.octaves       = octaves;
        this.amplitude     = amplitude;
        this.roughness     = roughness;
        this.offset        = offset;
        this.normaliseMode = normaliseMode;

        System.Random prng = new System.Random(this.seed);
        this.octaveOffsets = new Vector2[this.octaves];
        for (int i = 0; i < octaves; i++)
        {
            float offsetX = prng.Next(-100000, 100000) + this.offset.x;
            float offsetY = prng.Next(-100000, 100000) - this.offset.y;

            this.octaveOffsets[i] = new Vector2(offsetX, offsetY);

            maxPossibleHeight += (float)Mathf.Pow(this.roughness, i) * this.amplitude;
        }
    }
Esempio n. 2
0
    public static float[,] GenerateNoiseMap(int width, int height, float scale, int octaves, float persistance, float lacunarity, int seed, Vector2 offset, NormaliseMode normMode)
    {
        if (scale <= 0)
        {
            scale = 0.001f;
        }


        System.Random prng = new System.Random(seed);

        float amplitude   = 1;
        float freq        = 1;
        float noiseHeight = 0;

        float maxPossHeight = 0f;
        float minPossHeight = 0f;

        // Sample each octave from a new part (increases noise)
        Vector2[] octaveOffsets = new Vector2[octaves];
        for (int i = 0; i < octaves; i++)
        {
            float offsetX = prng.Next(-100000, 100000) + offset.x;
            float offsetY = prng.Next(-100000, 100000) + offset.y;
            octaveOffsets[i] = new Vector2(offsetX, offsetY);
            maxPossHeight   += amplitude;
            amplitude       *= persistance;
        }

        // Used to normalise the noisemap at end
        float maxNoiseVal = float.MinValue;
        float minNoiseVal = float.MaxValue;

        // Used to offset the noise to the centre instead of top-left
        float hWidth  = width / 2f;
        float hHeight = height / 2f;


        float[,] noiseMap = new float[width, height];
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                amplitude   = 1;
                freq        = 1;
                noiseHeight = 0;

                for (int i = 0; i < octaves; i++)
                {
                    float sampleX = (x - hWidth + octaveOffsets[i].x) / scale * freq;
                    float sampleY = (y - hHeight + octaveOffsets[i].y) / scale * freq;

                    float perlinVal = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    noiseHeight += perlinVal * amplitude;

                    amplitude *= persistance;
                    freq      *= lacunarity;
                }

                if (noiseHeight > maxNoiseVal)
                {
                    maxNoiseVal = noiseHeight;
                }
                else if (noiseHeight < minNoiseVal)
                {
                    minNoiseVal = noiseHeight;
                }

                noiseMap[x, height - 1 - y] = noiseHeight;
            }
        }

        // Normalise noisemap between min and max values to be between 0f - 1f
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                if (normMode == NormaliseMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minNoiseVal, maxNoiseVal, noiseMap[x, y]);
                }
                if (normMode == NormaliseMode.Global)
                {
                    noiseMap[x, y] = ((noiseMap[x, y] + 1) / (2f * maxPossHeight / 1.75f));
                }
            }
        }

        return(noiseMap);
    }
Esempio n. 3
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormaliseMode normalisedMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

        System.Random prng          = new System.Random(seed);
        Vector2[]     octaveOffsets = new Vector2[octaves];

        float maxPossibleHeight = 0;
        float amplitude         = 1;
        float frequency         = 1;

        for (int i = 0; i < octaves; i++)
        {
            float offsetX = prng.Next(-100000, 100000) + offset.x;
            float offsetY = prng.Next(-100000, 100000) - offset.y;
            octaveOffsets[i] = new Vector2(offsetX, offsetY);

            maxPossibleHeight += amplitude;
            amplitude         *= persistance;
        }

        if (scale <= 0)
        {
            scale = 0.0001f;
        }

        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

        float halfWidth  = mapWidth / 2f;
        float halfHeight = mapHeight / 2f;

        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                amplitude = 1;
                frequency = 1;
                float noiseHeight = 0;
                for (int i = 0; i < octaves; i++)
                {
                    float sampleX = (x - halfWidth + octaveOffsets[i].x) / scale * frequency;
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / scale * frequency;

                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    noiseHeight += perlinValue * amplitude;

                    amplitude *= persistance;
                    frequency += lacunarity;
                }

                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }

                noiseMap[x, y] = noiseHeight;
            }
        }

        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalisedMode == NormaliseMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalisedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight);
                    noiseMap[x, y] = Mathf.Clamp(normalisedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
Esempio n. 4
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, float scale, int octaves, float persistance, float lacunarity, int seed, Vector2 offset, NormaliseMode normaliseMode)
    {
        System.Random prng           = new System.Random(seed);
        Vector2[]     octavesOffsets = new Vector2[octaves];

        float maxPossibleHeight = 0;
        float amplitude         = 1;
        float frequency         = 1;

        for (int i = 0; i < octaves; i++)                          //randomly offset octabes from each other to make random landscape
        {
            float offsetx = prng.Next(-100000, 100000) + offset.x; //empirical values
            float offsety = prng.Next(-100000, 100000) - offset.y;
            octavesOffsets [i] = new Vector2(offsetx, offsety);

            maxPossibleHeight += amplitude;
            amplitude         *= persistance;
        }

        float[,] noiseMap = new float [mapWidth, mapHeight];

        if (scale <= 0)
        {
            scale = 0.0001f;
        }

        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;


        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                amplitude = 1;
                frequency = 1;
                float noiseHeight = 0;

                for (int i = 0; i < octaves; i++)
                {
                    float sampleX = (x + octavesOffsets [i].x) / scale * frequency;                  // + offset.x;
                    float sampleY = (y + octavesOffsets[i].y) / scale * frequency;                   //+ offset.y;

                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;                 // multiply by 2 and negate one to ensure in range -1 to 1
                    noiseHeight += perlinValue * amplitude;

                    amplitude *= persistance;
                    frequency *= lacunarity;
                }

                //get range of noise height values to defina a max and a min value (to allow for normalisation)
                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }

                noiseMap [x, y] = noiseHeight;
            }
        }

        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normaliseMode == NormaliseMode.local)                                                           //if generating single chunk - ie not procedural
                {
                    noiseMap [x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap [x, y]); //inverselerp method standardises the noiseheingt (it returns a value between 0-1)
                }
                else
                {
                    float normalisedHeight = (noiseMap [x, y] + 1) / (2f * maxPossibleHeight / 5f);                   //reverses the operation above. The final float is an empirical correction to compensate for scaling by the maxpossible height
                    noiseMap[x, y] = Mathf.Clamp(normalisedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
    public static float[,] GenerateNoiseMap(int _width, int _height, int _seed, float _scale, int _octaves, float _persistence, float _lacunarity, Vector2 _offset, NormaliseMode _normaliseMode)
    {
        float[,] noiseMap = new float[_width, _height];

        System.Random prng          = new System.Random(_seed);
        Vector2[]     octaveOffsets = new Vector2[_octaves];

        float maxGlobalNoiseHeight = 0;
        float amplitude            = 1;
        float frequency            = 1;

        for (int i = 0; i < _octaves; i++)
        {
            float offsetX = prng.Next(-100000, 100000) + _offset.x;
            float offsetY = prng.Next(-100000, 100000) - _offset.y;
            octaveOffsets[i] = new Vector2(offsetX, offsetY);

            maxGlobalNoiseHeight += amplitude;
            amplitude            *= _persistence;
        }

        if (_scale <= 0)
        {
            _scale = 0.0001f;
        }

        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

        float halfWidth  = _width / 2;
        float halfHeight = _height / 2;


        for (int y = 0; y < _height; y++)
        {
            for (int x = 0; x < _width; x++)
            {
                frequency = 1;
                amplitude = 1;
                float noiseHeight = 0;

                for (int i = 0; i < _octaves; i++)
                {
                    // the higher the freuency, the further away the sample points,
                    // this means the height changes more rapidly
                    float sampleX = (x - halfWidth + octaveOffsets[i].x) / _scale * frequency;
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / _scale * frequency;

                    // generate values between -1 and 1 so that there can be dips in the
                    // terrain when it is later generated
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    noiseHeight += perlinValue * amplitude;

                    amplitude *= _persistence;

                    // frequency increases per octave since lacunarity is greater
                    // than 1.
                    frequency *= _lacunarity;
                }

                // work out the range of the noisemap values
                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }
                noiseMap[x, y] = noiseHeight;
            }
        }


        // normalise the noise map
        for (int y = 0; y < _height; y++)
        {
            for (int x = 0; x < _width; x++)
            {
                if (_normaliseMode == NormaliseMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    // make the height values consistent across the entire map
                    float normalizedHeight = (noiseMap[x, y] + 1) / (2 * maxGlobalNoiseHeight / 1.75f);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }
        return(noiseMap);
    }