Beispiel #1
0
 public NoiseParams(float noiseScale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
 {
     this.noiseScale    = noiseScale;
     this.octaves       = octaves;
     this.persistance   = persistance;
     this.lacunarity    = lacunarity;
     this.offset        = offset;
     this.normalizeMode = normalizeMode;
 }
Beispiel #2
0
        public static Tensor MatBgr2Tensor(Mat m, NormalizeMode mode = NormalizeMode.None, int resizeWidth = -1, int resizeHeight = -1, long[] shape = null, float[] imgbuffer = null)
        {
            if (resizeHeight != -1 && resizeWidth != -1)
            {
                m.Resize(new Size(resizeWidth, resizeHeight));
            }

            if (shape == null)
            {
                shape = new long[] { (int)m.Height, (int)m.Width, m.Channel };
            }

            float[] buffer = m.GetArray(imgbuffer);
            if (mode != NormalizeMode.None)
            {
                Vector <float> imgBuf = CreateVector.Dense(buffer);

                switch (mode)
                {
                case NormalizeMode.ZeroMean:
                    imgBuf.Divide(127.5f, imgBuf);
                    imgBuf.Subtract(1.0f, imgBuf);
                    break;

                case NormalizeMode.ZeroOne:
                    imgBuf.Divide(255.0f, imgBuf);
                    break;

                case NormalizeMode.CenterZero:
                    imgBuf.Subtract(imgBuf.Average(), imgBuf);
                    imgBuf.Divide((float)Statistics.StandardDeviation(imgBuf), imgBuf);
                    break;

                default:
                    throw new NotImplementedException("unknown one");
                }

                buffer = imgBuf.Storage.AsArray();
            }
            TFTensor tensor = TFTensor.FromBuffer(new TFShape(shape), buffer, 0, buffer.Length);

            return(new Tensor(tensor));
        }
Beispiel #3
0
    public enum NormalizeMode { local, global } //The way noise maps are localized depends on whether we're using the endlessTerrain system or not


    /// <summary>
    /// Generates a perlin noise map
    /// </summary>
    /// <param name="mapWidth">The width of the map</param>
    /// <param name="mapHeight">The heigh of the map</param>
    /// <param name="seed">The seed for the random offsets</param>
    /// <param name="mapOffset">The complete offset of the map</param>
    /// <param name="scale">The scale of magnification of the map</param>
    /// <param name="octaves">The number of octaves (ie runs of the perlin calculation) for any map value. Think of them as levels of detail</param>
    /// <param name="persistence">The rate of change of reduction influence of each octave. Should be 1 or less</param>
    /// <param name="lacunarity">The rate of change of reduction of gradualness (like, how jagged an octive is) per octve </param>
    /// <returns>A 2D map of values from 0 to 1</returns>
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, Vector2 mapOffset, float scale, int octaves, float persistence, float lacunarity, NormalizeMode mode, float globalDivisor)
    {
        float[,] map = new float[mapWidth, mapHeight];

        System.Random random       = new System.Random(seed);
        Vector2[]     octaveOffets = new Vector2[octaves]; //These offsets are applied to ocatves to add variance

        //Calculating the max possible non-clamped value attainable
        float maxPossibleHeight = 0;
        float tempAmplitude     = 1;

        for (int i = 0; i < octaves; i++)
        {
            octaveOffets[i]    = new Vector2(random.Next(-10000, 10000) + mapOffset.x, random.Next(-10000, 10000) - mapOffset.y);
            maxPossibleHeight += tempAmplitude;
            tempAmplitude     *= persistence;
        }

        if (scale <= 0)
        {
            scale = 0.0001f;
        }
        float minLocalNoiseHeight = float.MaxValue;
        float maxLocalNoiseHeight = float.MinValue;

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

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

                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY);
                    perlinValue  = perlinValue * 2 - 1; //Changing this value's range from 0-1 to -1-1 to allow some octaves to reduce noiseHeight
                    noiseHeight += perlinValue * amplitude;

                    amplitude *= persistence;
                    frequency *= lacunarity;
                }

                map[x, y] = noiseHeight;
                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }
            }
        }

        //Restricting the range back to 0-1
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (mode == NormalizeMode.local)
                {
                    map[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, map[x, y]);
                }
                else
                {
                    //We first have to devide the values by the maximum attainable value
                    //Then we change their range back from -1-1 to 0-1
                    //We should keep in mind though, that there's little chance that a perlin value will get anywhere close to maxPossibleHeight
                    //So we'll divide maxPossibleHeight by a number to reduce the devision effect
                    float normalizedHeight = ((map[x, y] / (maxPossibleHeight / globalDivisor)) + 1) / 2;
                    map[x, y] = Mathf.Clamp01(normalizedHeight);  //Clamping in case we a high value stayed out of range after out calculations
                }
            }
        }
        return(map);
    }
Beispiel #4
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeigth, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] noisemap = new float[mapWidth, mapHeigth];

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

        float maxPossibleHeight = 0;
        float amplitude         = 1;
        float frequency         = 1;// More frequency more changes in the values(terrain)

        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 maxLocalNoiseHeigth = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

        float halfWidth  = mapWidth / 2f;
        float halfHeigth = mapHeigth / 2f;

        for (int y = 0; y < mapHeigth; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                amplitude = 1;
                frequency = 1;                // More frequency more changes in the values(terrain)
                float noiseHeigth = 0;

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

                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;                     // Values between 0 and 1 we multiply by 2 and sustract 1 to make values between -1  and 1;
                    noiseHeigth += perlinValue * amplitude;

                    amplitude *= persistance;
                    frequency *= lacunarity;
                }
                if (noiseHeigth > maxLocalNoiseHeigth)
                {
                    maxLocalNoiseHeigth = noiseHeigth;
                }
                else if (noiseHeigth < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeigth;
                }

                noisemap [x, y] = noiseHeigth;
            }
        }

        for (int y = 0; y < mapHeigth; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    noisemap [x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeigth, noisemap [x, y]);
                }
                else
                {
                    float normalizeHeigth = (noisemap [x, y] + 1) / (maxPossibleHeight / 1.5f);
                    noisemap [x, y] = Mathf.Clamp(normalizeHeigth, 0, int.MaxValue);
                }
            }
        }

        return(noisemap);
    }
Beispiel #5
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float noiseScale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

        // For seed, in case we need to generate the same map
        System.Random prng         = new System.Random(seed);
        Vector2[]     octaveOffset = 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;
            octaveOffset[i] = new Vector2(offsetX, offsetY);

            maxPossibleHeight += amplitude;
            amplitude         *= persistance;
        }
        // Prevent noise scale from being negative.
        if (noiseScale <= 0)
        {
            noiseScale = 0.0001f;
        }
        //set to temp values. updated in loop
        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++)
                {
                    // Higher frequency  = further apart samples meaning steeper slopes
                    float sampleX = (x - halfWidth + octaveOffset[i].x) / noiseScale * frequency;
                    float sampleY = (y - halfHeight + octaveOffset[i].y) / noiseScale * frequency;
                    //Perlin value in range -1 to 1
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    noiseHeight += perlinValue * amplitude;
                    //Amplitude decreases per octave
                    amplitude *= persistance;
                    //Frequency increases per octave
                    frequency *= lacunarity;
                }

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

                noiseMap[x, y] = noiseHeight;
            }
        }
        // Normalize noisemap
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    //For non-endless terrain
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }
        return(noiseMap);
    }
Beispiel #6
0
    public static float[,] PerlinNoise(int size, float scale, int seed, float offsetX, float offsetY, int octaves, float persistence, float lacunarity, NormalizeMode normalizeMode)
    {
        float[,] map = new float[size, size];
        float min = float.MaxValue;
        float max = float.MinValue;
        float maxPossibleHeight = 0;
        float frequency         = 1;
        float amplitude         = 1;

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

        float halfSize = size / 2f;

        Vector2[] octaveOffsets = new Vector2[octaves];
        int       randRange     = 10000;

        for (int i = 0; i < octaves; i++)
        {
            octaveOffsets[i].x = rand.Next(-randRange, randRange) + offsetX / scale;
            octaveOffsets[i].y = rand.Next(-randRange, randRange) - offsetY / scale;

            maxPossibleHeight += amplitude;
            amplitude         *= persistence;
        }


        // Generate the noise
        for (int x = 0; x < size; x++)
        {
            for (int y = 0; y < size; y++)
            {
                float sample = 0;
                frequency = 1;
                amplitude = 1;

                for (int o = 0; o < octaves; o++)
                {
                    float xCoord      = (x - halfSize) / scale + octaveOffsets[o].x;
                    float yCoord      = (y - halfSize) / scale + octaveOffsets[o].y;
                    float perlinValue = Mathf.PerlinNoise(xCoord * frequency, yCoord * frequency) * 2 - 1;
                    sample += perlinValue * amplitude;

                    frequency *= lacunarity;
                    amplitude *= persistence;
                }


                if (sample < min)
                {
                    min = sample;
                }
                if (sample > max)
                {
                    max = sample;
                }

                map[x, y] = sample;
            }
        }

        // Normalize the data
        for (int x = 0; x < size; x++)
        {
            for (int y = 0; y < size; y++)
            {
                if (normalizeMode == NormalizeMode.Global)
                {
                    float normalizedHeight = (map [x, y] + 1) / (maxPossibleHeight * 0.8f);
                    map[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
                else
                {
                    map[x, y] = Mathf.InverseLerp(min, max, map[x, y]);
                }
            }
        }

        return(map);
    }
Beispiel #7
0
    public static float[,] GenerateNoiseMap(
        int mapWidth, int mapHeight, int seed, float scale,
        int octaves, float persistence, float lacunarity, Vector2 offset,
        NormalizeMode normalizeMode
        )
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

        // sample each octave from a different location in the noise domain
        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++)
        {
            // limit to 100K, as higher input returns same noise
            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         *= persistence;
        }

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

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

        // used to scale from the center
        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;

                    // PerlinNoise returns 0..1
                    // To get negative noise values, mul by 2, then subtract 1
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    noiseHeight += perlinValue * amplitude;

                    amplitude *= persistence;   // decrease ampl -- pers is 0..1
                    frequency *= lacunarity;    // increase freq -- lacu s/b > 1
                }

                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 (normalizeMode == NormalizeMode.Local)
                {
                    // normalize noiseHeight: InverseLerp returns 0..1
                    noiseMap[x, y] = Mathf.InverseLerp(
                        minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]
                        );
                }
                else
                {
                    // estimate min/max NoiseHeight across multiple chunks
                    float normalizedHeight = (noiseMap[x, y] + 1)
                                             / (2f * maxPossibleHeight);
                    // reverse (sample * 2 - 1) op that gave negative values

                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
Beispiel #8
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, float scale, int octaves, float persistance, float lacunarity, int seed, Vector2 offset, NormalizeMode normalizeMode)
    {
        float [,] noiseMap = new float[mapWidth, mapHeight];

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

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


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

            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 = 1f;
                frequency = 1f;
                float noiseHeight = 0f;

                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; // * 2 -1 -> to get negative numbers instead of 0->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 (normalizeMode == NormalizeMode.Local)
                {
                    // Good for finite generation, but not for infinete generation because we dont know exactly what min and max height is
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / maxPossibleHeight;
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
Beispiel #9
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

        float maxPossibleHeight = 0f;
        float amplitude         = 1;

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

            maxPossibleHeight += amplitude;
            amplitude          = amplitude * persistance;
        }

        float maxLocalNoiseVal = float.MinValue;
        float minLocalNoiseVal = float.MaxValue;

        float halfW = mapWidth / 2f;
        float halfH = mapHeight / 2f;

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

                for (int i = 0; i < octaves; i++)
                {
                    float xCoord = (x - halfW + octaveOffsets[i].x) / scale * frequency;
                    float yCoord = (y - halfH + octaveOffsets[i].y) / scale * frequency;

                    float val = Mathf.PerlinNoise(xCoord, yCoord) * 2f - 1f;
                    noiseHeight += val * amplitude;

                    amplitude *= persistance;
                    frequency *= lacunarity;

                    if (val > maxLocalNoiseVal)
                    {
                        maxLocalNoiseVal = val;
                    }
                    if (val < minLocalNoiseVal)
                    {
                        minLocalNoiseVal = val;
                    }
                }

                noiseMap[(int)x, (int)y] = noiseHeight;
            }
        }



        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseVal, maxLocalNoiseVal, noiseMap[x, y]);
                }
                else
                {
                    noiseMap[x, y] = Mathf.Clamp((noiseMap[x, y] + 1f) / maxPossibleHeight, 0f, float.MaxValue);
                }
            }
        }
        return(noiseMap);
    }
Beispiel #10
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale,
                                            int octaves, float persistence, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float maxPossibleHeight = 0;         // The maximum possible height of the terrain
        float amplitude         = 1;
        float frequency         = 1;

        // Generates random noise seed
        System.Random prng = new System.Random(seed);          // prng = Pseudo-random number generator
        // Each octave is sampled from a different location
        Vector2[] octaveOffsets = new Vector2[octaves];
        for (int i = 0; i < octaves; i++)
        {
            // Offset allows you to scroll through noise
            float offsetX = prng.Next(-100000, 100000) + offset.x;
            float offsetY = prng.Next(-100000, 100000) - offset.y;              // Subtract y to simulate forward motion
            octaveOffsets [i] = new Vector2(offsetX, offsetY);

            maxPossibleHeight += amplitude;
            amplitude         *= persistence;
        }

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

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

        // Keep track of min and max noise height for normalization later
        float minLocalNoiseHeight = float.MaxValue;
        float maxNoiseHeight      = float.MinValue;

        // Allows you to scale the noise towards the center
        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++)
                {
                    // Point from which height values are sampled
                    // Higher frequency means height will change more rapidly
                    float sampleX = (x - halfWidth + octaveOffsets[i].x) / scale * frequency;
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / scale * frequency;

                    // Determine the height for each point and assign to noise map
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    // Increase noise height by perlin value of each octave
                    noiseHeight += perlinValue * amplitude;

                    amplitude *= persistence;
                    frequency *= lacunarity;
                }

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

                noiseMap [x, y] = noiseHeight;                 // Apply noise height to map at x, y
            }
        }

        // Normalize range of the noise map to between 0, 1
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    // Preferred method if not doing endless terrain
                    noiseMap [x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxNoiseHeight, noiseMap [x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap [x, y] + 1) / maxPossibleHeight;
                    noiseMap [x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
Beispiel #11
0
    public static float[,] GeneratePerlinNoise(int width, int height, int seed, float scale, int octaves, Vector2 offset, float persistance = 0.5f, float lacunarity = 2, float step = 0, NormalizeMode normalizeMode = NormalizeMode.Local)
    {
        float[,] noiseMap = new float[width, height];

        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  = width / 2f;
        float halfHeight = height / 2f;

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

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

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

                    amplitude *= persistance;
                    frequency *= lacunarity;
                }

                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }
                noiseMap[x, y] = noiseHeight;
            }
        }

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (step != 0)
                {
                    noiseMap[x, y] = Mathf.Round(noiseMap[x, y] / step);
                    noiseMap[x, y] = step * noiseMap[x, y];
                    //Debug.Log(noiseMap[x, y]);
                }

                if (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (2f * maxPossibleHeight / 2f);
                    noiseMap[x, y] = normalizedHeight;
                }
            }
        }

        return(noiseMap);
    }
Beispiel #12
0
    /**
     *
     * seed = if we want to get the same map again, we just have to use the same seed
     *  // return a 2d array of float values
     **/
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

        // pnrg = seeder random number generator
        System.Random prng          = new System.Random(seed);
        Vector2[]     octaveOffsets = new Vector2[octaves];

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

        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;

        // used to move to the center when modifying the noiseScale
        float halfWidth  = mapWidth / 2f;
        float halfHeigth = mapHeight / 2f;


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

                for (int i = 0; i < octaves; i++)
                {
                    // the higher the frequency, the further apart the sample points will be
                    // the height values will change more rapidly
                    float sampleX = (x - halfWidth + octaveOffsets[i].x) / scale * frequency;
                    float sampleY = (y - halfHeigth + octaveOffsets[i].y) / scale * frequency;

                    // by default perlin noise is in the range of 0 to 1
                    // but we want our perlin value to be sometimes negative than that so that
                    // our noiseHeight decrease :
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    // we want to increase the noise height by the perlin value of each octave
                    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++)
            {
                // InverseLerp method returns a value between 0 and 1,
                // so f.e if our noiseMap value = to minNoiseHeight => returns 0
                // if it's equals to maxNoiseHeight  => returns 1
                // if it's half way between the two of it it returns 0.5, etc...
                if (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                // doing smtg consistent across the entire map
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / maxPossibleHeight;
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
Beispiel #13
0
        public static float[,] GenerateNoiseMap(int width, int height, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
        {
            float[,] noiseMap = new float[width, height];

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

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

            for (int i = 0; i < octaves; i++)
            {
                octavesOffsets[i]  = new Vector2(prng.Next(-100000, 100000), prng.Next(-100000, 100000)) - offset;
                maxPossibleHeight += amplitude;
                amplitude         *= persistance;
            }

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

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

            float halfWidth  = width * .5f;
            float halfHeight = height * .5f;

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

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

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

                        amplitude *= persistance;
                        frequency *= lacunarity;
                    }

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

                    noiseMap[x, y] = noiseHeight;
                }
            }

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    switch (normalizeMode)
                    {
                    case NormalizeMode.Global:
                        noiseMap[x, y] = Mathf.Clamp((noiseMap[x, y] + 1) / maxPossibleHeight, 0, int.MaxValue);
                        break;

                    default:
                        noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                        break;
                    }
                }
            }

            return(noiseMap);
        }
Beispiel #14
0
    /// <summary>
    /// Generates a perlin noise map.
    /// </summary>
    /// <param name="mapChunkSize">Width of the map (X).</param>
    /// <param name="mapChunkSize">Height of the map (Z).</param>
    /// <param name="seed">Custom seed for random values.</param>
    /// <param name="scale">Scale of the noise (smaller vs bigger).</param>
    /// <param name="octaves">Octave to control amount of detail of the Perlin Noise.</param>
    /// <param name="persistance">How quickly the amplitude diminishes per octave.</param>
    /// <param name="lacunarity">How quickly the frequency increases per octave.</param>
    /// <param name = "offset">Custom offset for scrolling through noise.</param>
    /// <returns>Float[] NoiseMap</returns>
    public static float [,] GenerateNoiseMap(int width, int height, int seed, float scale, int octaves,
                                             float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float [,] noiseMap = new float[width, height];
        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

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

        // Psuedo Random Number Generator
        System.Random prng          = new System.Random(seed);
        Vector2[]     octaveOffsets = new Vector2[octaves];
        for (int i = 0; i < octaves; i++)
        {
            // Generate random offsets per octave
            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;
        }

        // Half values for scaling (zooming) from the center
        float halfWidth  = width / 2f;
        float halfHeight = height / 2f;

        // Loop through all "points" of our map
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                amplitude = 1;
                frequency = 1;
                float noiseHeight = 0;

                // Loop through different "octaves", remember Mountain vs Hill vs Stone
                // The greater the octave, the less effect it has on the overall noise
                for (int i = 0; i < octaves; i++)
                {
                    // Frequency used for number of cycles per unit length
                    // Multiply values by frequency, will "flatten/exaggerate" out the noise
                    // Offset the values per octave for more randomness
                    //  - Added halfHeight and halfWidth for scaling off the center
                    float sampleX = ((x - halfHeight) + octaveOffsets[i].x) / scale * frequency;
                    float sampleY = ((y - halfWidth) + octaveOffsets[i].y) / scale * frequency;

                    // Perlin generates between 0 ~ 1
                    // But lets generate a perlin value between -1 ~ 1 to add more 'height'
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    // Multiply by the amplitude, effecting the overall maximum height
                    noiseHeight += perlinValue * amplitude;
                    // Range 0 - 1
                    amplitude *= persistance;
                    // Range increases
                    frequency *= lacunarity;
                }
                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }
                noiseMap[x, y] = noiseHeight;
            }
        }

        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                // Normalize the noiseMap using InverseLerp
                // InverseLerp returns a value between 0 ~ 1
                // If noiseMap == minLocalNoiseHeight it will return 0
                // If noiseMap == maxLocalNoiseHeight, it will return 1
                if (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    // this reverses perlinValue caluclation
                    float normalizedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight);
                    // this is used for global normalization to get infinite terrain chunks to be about same height
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
                // If generating map chunk by chunk, this min and max noise height will vary between chunks, so the chunks will be slightly off when normalized
            }
        }


        return(noiseMap);
    }
Beispiel #15
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        // scale can never be zero or negative
        if (scale <= 0)
        {
            scale = 0.0001f;
        }

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

        float maxPossibleHeight = 0;
        float frecuencyMod      = 1;
        float amplitudeMod      = 1;

        for (int i = 0; i < octaves; i++)
        {
            // set random limit to get interesting values
            int   limit   = 1000;
            float offsetX = prng.Next(-limit, limit) + offset.x;
            float offsetY = prng.Next(-limit, limit) - offset.y;//y goes the other way around
            octavesOffset[i] = new Vector2(offsetX, offsetY);

            maxPossibleHeight += amplitudeMod;
            // with each octave ammplitude decreases due to persistance having to be between 0 and 1
            amplitudeMod *= persistance;
        }

        float[,] noiseMap = new float[mapWidth, mapHeight];
        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++)
            {
                // reset the values for each position
                frecuencyMod = 1;
                amplitudeMod = 1;
                float noiseHeight = 0;

                // process octaves
                for (int i = 0; i < octaves; i++)
                {
                    float sampleX = (x - halfWidth + octavesOffset[i].x) / scale * frecuencyMod;
                    float sampleY = (y - halfHeight + octavesOffset[i].y) / scale * frecuencyMod;

                    // perlin noise is between 0 and 1 -> turn to -1 to 1 to have more interesting noise
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    noiseHeight += perlinValue * amplitudeMod;

                    // with each octave ammplitude decreases due to persistance having to be between 0 and 1
                    amplitudeMod *= persistance;
                    // with each octave frecuency increases due to lacunarity having to be greater than 1
                    frecuencyMod *= 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 (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalzedHeight = (noiseMap[x, y] + 1) / (2f * maxPossibleHeight / 1.45f);
                    noiseMap[x, y] = Mathf.Clamp(normalzedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
Beispiel #16
0
 private static void NormalizeNoiseMap(float[,] noiseMap, int mapWidth, int mapHeight, float minLocalNoiseHeight, float maxLocalNoiseHeight, float maxGlobalNoiseHeight, NormalizeMode normalizeMode)
 {
     if (normalizeMode == NormalizeMode.Local)
     {
         for (int y = 0; y < mapHeight; y++)
         {
             for (int x = 0; x < mapWidth; x++)
             {
                 noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
             }
         }
     }
 }
Beispiel #17
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacinarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        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 / 2;
        float halfHeight = mapHeight / 2;

        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;

                    //perlin between negative 1 and 1 so noiseheight can decrease and incr not only incr
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    noiseHeight += perlinValue * amplitude;

                    // amplitude decreases every octave
                    amplitude *= persistance;
                    //frequency increases every octave, widers sample = more frequent height change
                    frequency *= lacinarity;
                }
                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++)
            {
                //Only takes into account local chunks mins and maxes so has different normalization
                if (normalizeMode == NormalizeMode.Local)
                {
                    //normalized noisemap return val between min and max between 0 and 1
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, float.MaxValue);
                }
            }
        }
        return(noiseMap);
    }
Beispiel #18
0
    public static float[,] GenerateNoiseMap(
        int mapWidth,
        int mapHeight,
        int seed,
        float noiseScale,
        int octaves,
        float persistence,
        float lacunarity,
        Vector2 offset,
        NormalizeMode normalizeMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

        // Pseudo Random Number Generator
        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         *= persistence;
        }

        if (noiseScale <= 0)
        {
            noiseScale = 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) / noiseScale * frequency;
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / noiseScale * frequency;

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

                    amplitude *= persistence;
                    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 (normalizeMode == NormalizeMode.Local)
                {
                    // Normalize the noise map, so if value is less than minNoiseHeight, return minNoiseHeight.
                    // Same goes for maxLocalNoiseHeight.
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    // Multiply maxPossibleHeight by 2 and divide by some factor 1~2 to mess with max peak height
                    float normalizedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float maxHeight   = 0;                              //altezza massima raggiungibile
        float amplitude   = 1;                              //amplitudine
        float frequency   = 1;                              //frequenza
        float noiseHeight = 0;                              //altezza del rumore

        float[,] noiseMap = new float[mapWidth, mapHeight]; //height map

        System.Random rnd     = new System.Random(seed);    //seed casuale
        Vector2[]     octOffs = new Vector2[octaves];



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

            maxHeight = maxHeight + amplitude;
            amplitude = amplitude * persistance;
        }

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

        float maxNoiseHeight = float.MinValue;      //tener trccia dei valori minori e maggiori
        float minNoiseHeight = 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;
                noiseHeight = 0;

                for (int i = 0; i < octaves; i++)
                {
                    float coordX = (x - halfWidth + octOffs[i].x) / scale * frequency;
                    float coordY = (y - halfHeight + octOffs[i].y) / scale * frequency;

                    float perlinValue = Mathf.PerlinNoise(coordX, coordY) * 2 - 1;          //passo i valori alla funizone di Perlin implementata su Unity
                    noiseHeight += perlinValue * amplitude;

                    amplitude = amplitude * persistance;
                    frequency = frequency * lacunarity;
                }

                if (noiseHeight > maxNoiseHeight)
                {
                    maxNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minNoiseHeight)
                {
                    minNoiseHeight = noiseHeight;
                }
                noiseMap[x, y] = noiseHeight;
            }
        }

        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x, y]);         //ritorna i valori tra 1 e 0 in base ai valori min e max passati
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (2f * maxHeight);
                    noiseMap[x, y] = normalizedHeight;
                }
            }
        }
        return(noiseMap);
    }
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        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(normalizeMode == NormalizeMode.Local) {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                } else {
                    float normalizedHeight = (noiseMap[x, y] + 1) / maxPossibleHeight;
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }
        return noiseMap;
    }
Beispiel #21
0
    /**
     * Method that generates the noise map (a 2D representation of what the 3D terrarin will look like)
     * @param mapChunkSize Width of the generated map
     * @param mapHeight Height of the generated map
     * @param seed The unique seed which determines the appearance of the map
     * @param scale The scale (or zoom) of the map
     * @param octaves Variable that controls the amount of "fine details" in the map
     * @param persistence Controls the amount that the amplitude of the octaves increases
     * @param lacunarity Controls the amount that the frequency of the octaves increases
     * @param offset Allows the generated terrain to be "scrolled"
     * @param normalizeMode The mode in which the terrain heights are normalized based on a curve
     */
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistence, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        // Noise map initialized
        float[,] noiseMap = new float[mapWidth, mapHeight];

        // Random number generator for the offset
        System.Random rng = new System.Random(seed);
        // Allows each octave to sample from a different point in the noise
        Vector2[] octaveOffsets = new Vector2[octaves];

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

        // Set the octave offsets
        for (int i = 0; i < octaves; i++)
        {
            float offsetX = rng.Next(-100000, 100000) + offset.x;
            float offsetY = rng.Next(-100000, 100000) - offset.y;

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

            maxPossibleHeight += amplitude;
            amplitude         *= persistence;
        }

        // Divide-by-zero preventificator
        if (scale <= 0)
        {
            scale = 0.0001f;
        }

        // Variables for keeping track of local max and min noise (terrain) heights
        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

        // For use in aligning the noise scale to the center rather than top right
        float halfWidth  = mapWidth / 2f;
        float halfHeight = mapHeight / 2f;

        // Noise loop
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                // Default values
                amplitude = 1;
                frequency = 1;
                float noiseHeight = 0;

                // Applying the octaves
                for (int i = 0; i < octaves; i++)
                {
                    // Applying all functionality to each coordinate in the noise map
                    float sampleX = (x - halfWidth + octaveOffsets[i].x) / scale * frequency;
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / scale * frequency;

                    // Perlin noise calculation, allowed to use negative values for increased visual appeal
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    // Noise height set accordingly
                    noiseHeight += perlinValue * amplitude;

                    // More functionality of the various variables
                    amplitude *= persistence;
                    frequency *= lacunarity;
                }

                // Set max and min noise heights if need be
                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }

                // Actual assigning of the value to the noise map
                noiseMap[x, y] = noiseHeight;
            }
        }

        // Second pass on the noise map values to apply a reverse linear interpolation (a method of fitting the values to the curve we want)
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    // Map is not infinite
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    // Map is infinite
                    float normalizedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
    public static float[,] NoiseMapData(NoiseSettings settings, Vector2 center, int width, int length, bool preview)
    {
        #region Variables

        Random.State initialState = Random.state;
        Random.InitState(settings.seed);

        NormalizeMode normalizeMode_previewsafe = (preview) ? NormalizeMode.Local : settings.normalizeMode;
        float         scale_previewsafe         = settings.scale;

        float[,] noiseMap = new float[width, length];
        float halfWidth  = width / 2f;
        float halfLength = length / 2f;

        float noiseValue    = 0;
        float noiseEstimate = 0;

        float noiseMin = (normalizeMode_previewsafe == NormalizeMode.Global) ? 0 : float.MaxValue;
        float noiseMax = (normalizeMode_previewsafe == NormalizeMode.Global) ? 0 : float.MinValue;

        float amplitude = 1;
        float frequency = 1;

        #endregion

        #region Random Number Generator

        System.Random prng          = new System.Random(settings.seed);
        Vector2[]     octaveOffsets = new Vector2[settings.octaves];
        for (int o = 0; o < settings.octaves; o++)
        {
            float xOffset = prng.Next(-100000, 100000) + settings.offset.x + center.x;
            float yOffset = prng.Next(-100000, 100000) - settings.offset.y - center.y;
            octaveOffsets[o] = new Vector2(xOffset, yOffset);

            if (normalizeMode_previewsafe == NormalizeMode.Global)
            {
                noiseMax += amplitude * Mathf.Pow(settings.persistance, o);
            }
            else
            {
                noiseEstimate += amplitude;
            }
            amplitude *= settings.persistance;
        }
        if (normalizeMode_previewsafe == NormalizeMode.Global)
        {
            noiseMin = -noiseMax;
        }

        #endregion

        #region Main

        for (int y = 0; y < length; y++)
        {
            for (int x = 0; x < width; x++)
            {
                amplitude  = 1;
                frequency  = 1;
                noiseValue = 0;

                for (int o = 0; o < settings.octaves; o++)
                {
                    float xSample = (x - halfWidth + octaveOffsets[o].x) / scale_previewsafe * frequency;
                    float ySample = (y - halfLength + octaveOffsets[o].y) / scale_previewsafe * frequency;

                    float perlinValue = Mathf.PerlinNoise(xSample, ySample) * 2f - 1f;
                    noiseValue += perlinValue * amplitude;

                    amplitude *= settings.persistance;
                    frequency *= settings.lacunarity;
                }

                #region Normalization

                if (normalizeMode_previewsafe != NormalizeMode.Global)
                {
                    if (noiseValue > noiseMax)
                    {
                        noiseMax = noiseValue;
                    }
                    if (noiseValue < noiseMin)
                    {
                        noiseMin = noiseValue;
                    }
                }

                #endregion

                if (normalizeMode_previewsafe != NormalizeMode.Global)
                {
                    noiseMap[x, y] = noiseValue;
                }
                else
                {
                    noiseMap[x, y] = Mathf.InverseLerp(noiseMin, noiseMax, noiseValue);
                }
            }
        }

        #endregion

        #region Normalization

        if (normalizeMode_previewsafe != NormalizeMode.Global)
        {
            for (int y = 0; y < length; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    if (normalizeMode_previewsafe == NormalizeMode.Local)
                    {
                        noiseMap[x, y] = Mathf.InverseLerp(noiseMin, noiseMax, noiseMap[x, y]);
                    }
                    else
                    {
                        noiseMap[x, y] = Mathf.Clamp((noiseMap[x, y] + 1f) / (2f * noiseEstimate / 1.70f), 0, int.MaxValue);
                    }
                }
            }
        }

        #endregion

        Random.state = initialState;
        return(noiseMap);
    }
Beispiel #23
0
    /// <summary>
    /// Generate a noise map by sampling points from Perlin noise
    /// </summary>
    /// <param name="mapWidth">Width of noise map</param>
    /// <param name="mapHeight">Height of noise map</param>
    /// <param name="seed">Seed for octave offset randomization</param>
    /// <param name="scale">Zoom scale of map</param>
    /// <param name="octaves">Controls number of layers of detail</param>
    /// <param name="persistence">Controls decay in amplitude over octaves</param>
    /// <param name="lacunarity">Controls frequenct/level of detail in an octave</param>
    /// <param name="offset"></param>
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

        System.Random prng = new System.Random(seed);
        // Want each ocatve to be sampled from radically different locations on the Perlin noise
        Vector2[] octaveOffsets = new Vector2[octaves];

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

        // Generate random sample location offset + the user-controlled "pan offset" for the 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);

            // For Global normalize mode
            maxPossibleHeight += amplitude;
            amplitude         *= persistance;
        }

        // To prevent division by 0, scale should be positive
        if (scale <= 0)
        {
            scale = 0.0001f;
        }

        // These will keep track of the highest and lowest height values on the map for normalization
        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

        // Used to make noise scale grow about the centre of the map
        float halfHeight = mapHeight / 2f;
        float halfWidth  = mapWidth / 2f;

        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                // Initial values for a given point
                amplitude = 1;
                frequency = 1;
                float noiseHeight = 0;

                for (int i = 0; i < octaves; i++)
                {
                    // Increased frequency results in points being sampled further apart and therefore more rapid change in heights
                    // Add octaveOffsets to make sure that each octave is sampling from random locations in the Perlin noise
                    float sampleX = (x - halfWidth + octaveOffsets[i].x) / scale * frequency;
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / scale * frequency;

                    // Sample Perlin noise
                    // * 2 - 1 to give range of -1 to 1, and allow some octaves to potentially decrease noiseHeight
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1; // Will give us a range -1 to 1
                    noiseHeight += perlinValue * amplitude;

                    // Update amplitude and frequency for successive octaves
                    amplitude *= persistance; // Amplitude decreases each octave (0 < persistance < 1)
                    frequency *= lacunarity;  // Frequency increases each octave (lacunarity > 1)
                }

                // Max and min height updates
                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }
                noiseMap[x, y] = noiseHeight;
            }
        }

        // Normalize the noise map back to the range 0 to 1
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                // Returns value from 0 to 1
                // i.e. if noiseMap[x,y] == minNoiseHeight, InverseLerp returns 0
                //      if noiseMap[x,y] == maxNoiseHeight, InverseLerp returns 1
                if (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    // Since out actual values in the noiseMap are rarely ever going to come close to the maxPossibleHeight
                    // we just divide maxPossibleHeight by some arbitrary value (1.75) just so that it's a bit more reasonable
                    float normalizedHeight = (noiseMap[x, y] + 1) / (2f * maxPossibleHeight / 1.75f);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }
        return(noiseMap);
    }
Beispiel #24
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

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

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

        //sets the random number with a seed
        //at the end of this loop we have found the maxPossibleHeight value
        for (int i = 0; i < octaves; i++)
        {
            float offsetX = prng.Next(-100000, 100000) + offset.x;
            float offsetY = prng.Next(-100000, 100000) - offset.y; //minus so y offset gets inverted, scroll up to see whats below

            //makes it possible to scroll in x and y
            octaveOffsets[i] = new Vector2(offsetX, offsetY);

            maxPossibleHeight += amplitude;
            amplitude         *= persistance;
        }

        if (scale <= 0)
        {
            scale = 0.0001f; //clamp to min value
        }

        //keep track for max height for normalizing and keeping numbers between 0 and 1
        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

        //zooming in in the middle instead of corner
        float halfWidth  = mapWidth / 2f;
        float halfHeight = mapHeight / 2f;

        //basic changes for perlin noise map
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                amplitude = 1; //reset the values to 1
                frequency = 1;
                float noiseHeight = 0;

                for (int i = 0; i < octaves; i++)
                {
                    //at which point sampling the height values
                    float sampleX = (x - halfWidth + octaveOffsets[i].x) / scale * frequency;  //scale of noise for noninteger values. offset is inside the brackets, so landmasses dont change in shape, while adjusting offset)
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / scale * frequency;

                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1; // for mor interesting results * 2 -1 to get between -1 to 1; so sometimes noise is negative
                    noiseHeight += perlinValue * amplitude;                          //calculates height for each of the octaves. maximum Scenario is when perlinvalue is 1 every single octave  ->

                    amplitude *= persistance;                                        //and amplitude also gets multiplied by persistence
                    frequency *= lacunarity;
                }

                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }
                noiseMap[x, y] = noiseHeight; //apply to noise map
            }
        }

        //normalize noise hight to be between 0 and 1
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalizeMode == NormalizeMode.Local)                                                         //local mode
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]); //min and max noise height will have slightly different values between the chunks, thats why its not perfectly lining up. if we generate the entire map at ones it wouldnt be a problem, because we know the max noise height, but endless terrain makes it a problem when its creates chunk by chunk
                }
                //do something else, that is consistent over the entire map
                else //global mode
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight / 0.9f);  //reverse the operation where perlinValue is *2 and then subtracted with -1 above with adding +1 and dividing with maxPossibleHeight
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue); //Clamp so it is at least not less than 0
                }
            }
        }

        return(noiseMap);
    }
        public static float[,] GenerateNoiseGrid(
            int width,
            int height,
            int seed                    = 0,
            float noiseScale            = 100f,
            int octaves                 = 6,
            float persistance           = 0.5f,
            float lacunarity            = 2f,
            Vector2 offset              = default(Vector2),
            NormalizeMode normalizeMode = NormalizeMode.Local
            )
        {
            noiseScale = (noiseScale <= 0) ? 1 : noiseScale;

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

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

                maxPossibleHeight += amplitude;

                amplitude *= persistance;
            }

            float[,] noiseGrid = new float[width, height];

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

            float halfWidth  = width / 2f;
            float halfheight = height / 2f;

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    amplitude = 1;
                    frequency = 1;

                    float noiseSum = 0;

                    for (int i = 0; i < octaves; i++)
                    {
                        float sampleX = (x - halfWidth + octaveOffsets[i].x) / noiseScale * frequency;
                        float sampleY = (y - halfheight + octaveOffsets[i].y) / noiseScale * frequency;

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

                        amplitude *= persistance;
                        frequency *= lacunarity;
                    }

                    minLocalNoiseHeight = Mathf.Min(minLocalNoiseHeight, noiseSum);
                    maxLocalNoiseHeight = Mathf.Max(maxLocalNoiseHeight, noiseSum);

                    noiseGrid[x, y] = noiseSum;
                }
            }

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    if (normalizeMode == NormalizeMode.Local)
                    {
                        noiseGrid[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseGrid[x, y]);
                    }
                    else
                    {
                        float normalizedHeight = (noiseGrid[x, y] + 1) / (maxPossibleHeight);
                        noiseGrid[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                    }
                }
            }


            return(noiseGrid);
        }
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];
        //float[] noiseMap = new float[mapWidth * mapHeight];

        System.Random prng = new System.Random(seed);           //prng = pseudo random number generator for generating
                                                                //noise at random locations on the map
        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;          //Storing the minimum and maximum
        float minLocalNoiseHeight = float.MaxValue;          //noise values for the terrain

        Perlin.Reseed();

        float halfWidth  = mapWidth / 2f;       //In order to get the central map noise values
        float halfHeight = mapHeight / 2f;      //when zooming in on the terrain map

        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;      //Deciding the sample points
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / scale * frequency;     //where the noise will be sampled and the number of samples

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

                    /*float perlinValue = Perlin.Noise(sampleX, sampleY);
                     * minLocalNoiseHeight = Mathf.Min(minLocalNoiseHeight, noiseHeight);
                     * maxLocalNoiseHeight = Mathf.Max(maxLocalNoiseHeight, noiseHeight);*/

                    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 (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (2f * maxPossibleHeight / 2f);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }
        return(noiseMap);
    }
Beispiel #27
0
    public static float[,] GeneradorRuido(int ancho, int largo, int seed, float escalado, int octaves, float persistencia, float lacunaridad, Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] mapaRuido = new float[ancho, largo];

        System.Random rnd          = new System.Random(seed);
        Vector2[]     octaveOffset = new Vector2[octaves];

        float maxPosibleHeigth = 0;
        float amplitud         = 1f;
        float frecuencia       = 1f;

        //Queremos que cada octave se muestree de una zona diferente del ruido, por eso el offset
        for (int i = 0; i < octaves; i++)
        {
            //En Y restamos para que al alterar el offset de forma positiva vaya hacia abajo. En principio no deberia de haber problema porque estuviera al reves
            octaveOffset[i] = new Vector2(rnd.Next(-100000, 100000) + offset.x, rnd.Next(-100000, 100000) + offset.y);

            //Maxima altura posible (multiplicamos por PerlinNoise pero como su maximo valor es 1 pues no hace falta multiplicar xD). Para el uso de modo global
            maxPosibleHeigth += amplitud;
            amplitud         *= persistencia;
        }

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

        float maxLocalAlturaRuido = float.MinValue;
        float minLocalAlturaRuido = float.MaxValue;

        for (int y = 0; y < largo; y++)
        {
            for (int x = 0; x < ancho; x++)
            {
                //Reduce la altura de cada octava por lo que cada una tendra mayores detalles porque tendremos valores en un menor rango?¿?
                //va en funcion de la persistencia, a mayor valor, mas granular sera cuando se sumen octavas, a menor, menos granular
                amplitud = 1f;
                //Es aproximadamente el 'zoom' que hacemos sobre el ruido en cada octave. Cada vez va a mas para mejorar los detalles al acumular octavas
                frecuencia = 1f;
                float alturaRuido = 0f;

                for (int i = 0; i < octaves; i++)
                {
                    //Valores x e y que vamos a usar para el ruido. restamos a x e y la mitad del mapa para que al aumentar el escalado lo haga hacia el centro de la textura
                    //El restado del offset del octave esta dentro para que tambien le afecte el escalado. Aunque en principio no pasa nada porque este fuera
                    float X = (x - (ancho / 2f)) / escalado * frecuencia + octaveOffset[i].x;
                    float Y = (y - (largo / 2f)) / escalado * frecuencia + octaveOffset[i].y;

                    //*2-1 es para que tambien pueda dar valores negativos lo que hara que alturaRuido pueda reducirse lo que hara que haya ruido mas interesante
                    float valorPerling = Mathf.PerlinNoise(X, Y) * 2 - 1;
                    //La altura que vamos acumulando de juntar diferentes capas de ruido
                    alturaRuido += valorPerling * amplitud;
                    //Reducimos la amplitud por lo que los posibles valores seran reducidos
                    amplitud *= persistencia;
                    //Aumentamos la frecuencia lo que se traduce en un 'zoom' sobre la textura
                    frecuencia *= lacunaridad;
                }
                //Como podemos tener valores negativos (ya no solo entre 0 y 1) vamos a almacenar el valor mas alto y mas bajo para normalizarlo despues
                if (alturaRuido > maxLocalAlturaRuido)
                {
                    maxLocalAlturaRuido = alturaRuido;
                }
                else if (alturaRuido < minLocalAlturaRuido)
                {
                    minLocalAlturaRuido = alturaRuido;
                }

                mapaRuido[x, y] = alturaRuido;
            }
        }

        //Es esto lo que causa que los chunks vecinos no esten perfectamente pegados. El problema es que minLocalAlturaRuido y maxLocalAlturaRuido son diferentes en cada chunk
        //Como podemos tener valores diferentes de [0,1] vamos a normalizarlos
        for (int y = 0; y < largo; y++)
        {
            for (int x = 0; x < ancho; x++)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    //Normaliza el valor de mapaRuido[x,y] entre los valores minLocalAlturaRuido y maxLocalAlturaRuido
                    mapaRuido[x, y] = Mathf.InverseLerp(minLocalAlturaRuido, maxLocalAlturaRuido, mapaRuido[x, y]);
                }
                else
                {
                    //Como dividimos entre maxPosibleHeigth que puede ser muy muy grande, todo quedara pequeño, por eso dividimos entre 1.85 para conseguir valores mas pequeño y normales
                    float normalizedHeight = (mapaRuido[x, y] + 1) / (2f * maxPosibleHeigth / 2f);
                    mapaRuido[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(mapaRuido);
    }
Beispiel #28
0
    //Method to generate the noise map
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        //Creating a 2D float array (noise map) with the defined dimensions
        float[,] noiseMap = new float[mapWidth, mapHeight];

        //Creating a seed with random number generator
        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(-10000, 10000) + offset.x;
            float offsetY = prng.Next(-10000, 10000) - offset.y;

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

            maxPossibleHeight += amplitude;
            amplitude         *= persistance;
        }


        //Clamping the scale value to remove divide by 0 errors
        if (scale <= 0)
        {
            scale = 0.0001f;
        }

        //Used for normalising the noise map at the end of the loops
        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

        //Calculating the values of the centre of the map to allow for the noise scale to zoom in on the centre (default top right)
        float halfWidth  = mapWidth / 2f;
        float halfHeight = mapHeight / 2f;


        //Looping over the noise map
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                amplitude = 1;
                frequency = 1;
                float noiseHeight = 0;

                //Looping through all the octaves
                for (int i = 0; i < octaves; i++)
                {
                    //Setting up float values to sample over
                    //Higher frequency means the height points will change more rapidly
                    float sampleX = (x - halfWidth + octaveOffsets[i].x) / scale * frequency;
                    float sampleY = (y - halfHeight + octaveOffsets[i].y) / scale * frequency;

                    //Generating the Perlin Value (Perlin noise is coherent noise - looks more like mountains)
                    //Multiply by 2 and -1 to give negative perlinValues
                    float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
                    noiseHeight += perlinValue * amplitude;

                    //Amplitude and frequecny increase after each octave as persistance and lacunarity are > 1
                    amplitude *= persistance;
                    frequency *= lacunarity;
                }

                //Updating the min/maxNoiseHeight where necessary
                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++)
            {
                //Returns a value between 0 - 1 to normalise the noiseMap
                // minNoiseHeight returns 0, maxNoiseHeight returns 1
                if (normalizeMode == NormalizeMode.Local)
                {
                    //Ideal method for non endless terrains
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (2f * maxPossibleHeight / 2.25f);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }


        return(noiseMap);
    }
Beispiel #29
0
    public static float[,] generateNoiceMap(int mapWidth, int mapHeight, float scale, int seed, int octaves, float lacunarity, float persistance, Vector2 offset, NormalizeMode mode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

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

        // when scale is increased, the map should zoom in towards the center:
        float halfWidth  = mapWidth / 2f;
        float halfHeight = mapHeight / 2f;

        //seed controls the output of the random object. if the seed is constant, the random generator will always have the same output.
        System.Random prng = new System.Random(seed);
        //Each octave should be sampled from a different location.
        Vector2[] Octaveoffsets = new Vector2[octaves];
        //determining the values for the offset.
        for (int i = 0; i < octaves; i++)
        {
            // user offset value is also added. enables user to scroll through various noise maps.
            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;
        }


        //clamping the scale if scale is zero.(Can't do division by zero)
        if (scale <= 0)
        {
            scale = 0.001f;
        }

        //initializing the max and min.
        float maxNoiseValue = float.MinValue;
        float minNoiseValue = float.MaxValue;


        // cycling through all the points of the map.
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                amplitude   = 1;
                frequency   = 1;
                noiseHeight = 0;
                for (int z = 0; z < octaves; z++)
                {
                    // higher the frequency, further apart the sample points will be. change in heights will be more rapid.
                    //applying the offset to get a different sample location
                    float SampleX = ((x - halfWidth) + Octaveoffsets[z].x) / scale * frequency;
                    float SampleY = ((y - halfHeight) + Octaveoffsets[z].y) / scale * frequency;

                    // PerlinNoise method returns only 0 to 1. to have negative values, *2-1
                    float PerlinValue = Mathf.PerlinNoise(SampleX, SampleY) * 2 - 1;


                    noiseHeight += PerlinValue * amplitude;

                    amplitude *= persistance;
                    frequency *= lacunarity;
                }
                //update the min and max noiseHeight
                //determines the rfange of noiseHeight values.
                if (noiseHeight > maxNoiseValue)
                {
                    maxNoiseValue = noiseHeight;
                }
                else if (noiseHeight < minNoiseValue)
                {
                    minNoiseValue = noiseHeight;
                }
                noiseMap[x, y] = noiseHeight;
            }
        }

        //normalize the noiseMap values (make it range between 0 and 1)
        //process through all values and clamp it between 0 and 1.
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                //InverseLerp returns value between 0 & 1. if noiseMap[x,y] = min, returns 0, if it is equal to max, returns 1

                if (mode == NormalizeMode.local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minNoiseValue, maxNoiseValue, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (2f * (maxPossibleHeight / 1.75f));
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
Beispiel #30
0
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed,
                                            float scale, int octaves, float persistance, float lacunarity,
                                            Vector2 offset, NormalizeMode normalizeMode)
    {
        float[,] noiseMap = new float[mapWidth, mapHeight];

        System.Random rng           = 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 = rng.Next(-100000, 100000) + offset.x;
            float offsetY = rng.Next(-100000, 100000) - offset.y;
            octaveOffsets[i] = new Vector2(offsetX, offsetY);

            maxPossibleHeight += amplitude;
            amplitude         *= persistance;
        }

        if (scale <= 0)
        {
            scale = float.MinValue;
        }

        float maxNoiseHeight = float.MinValue;
        float minNoiseHeight = 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 > maxNoiseHeight)
                {
                    maxNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minNoiseHeight)
                {
                    minNoiseHeight = noiseHeight;
                }

                noiseMap[x, y] = noiseHeight;
            }
        }

        for (int y = 0; y < mapHeight; ++y)
        {
            for (int x = 0; x < mapWidth; ++x)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight / 0.9f);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }
    //The purpose of this method is to create a noise map based off width, height, scale, octaves, persistance, and lacunarity.
    //Octaves are, essentially, how mnany times the map will run through the system, with each octave increasing in frequency according to its square value
    //
    //(In signal processing, this is literally the case - yay, my electrical engineering degree is useful here!)
    //
    //The persistance value is the degree to which higher octaves will affect the overall height map
    //The lacunarity affects where the octaves will be placed according to given frequency
    //
    //The seed also allows for the system to recall the map based off the given seed value
    //An offset is given to more directly affect the sampling within the map as opposed to just the seed
    public static float[,] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset, NormalizeMode normalizeMode)
    {
        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;

        //The seed will offset the sample values according to the RNG given for the seed, providing the octave with an appropriate value to be added or subtracted
        for (int i = 0; i < octaves; i++)
        {
            //The perlin noise generator seems to work best when random values are set between -100,000 and 100,000
            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;
        }

        //A negative scale or a scale equal to zero are simply not mathematically possible here, so if those are given, set it equal to some epsilon value
        if (scale <= 0)
        {
            scale = 0.0001f;
        }

        //Create max and min values to normalize the noise map to [0->1] once it's finished
        float maxLocalNoiseHeight = float.MinValue;
        float minLocalNoiseHeight = float.MaxValue;

        //Force the scale to zoom in and out relative to the center of the noise map as opposed to the top right by subtracting the half-values from x and y
        float halfWidth  = mapWidth / 2f;
        float halfHeight = mapHeight / 2f;

        //The noise map itself will be generated based off width, height, and octaves.  Amplitude scales with persistance, frequency scales with lacunarity
        //Each point is sampled from the perlin noise generator
        //Perlin noise is used to generate the amplitude value within the given signals for each octave.  Negative values are allowed here to create a more interesting map
        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;
                }

                //Define the maximum and minimum height values as they're generated
                if (noiseHeight > maxLocalNoiseHeight)
                {
                    maxLocalNoiseHeight = noiseHeight;
                }
                else if (noiseHeight < minLocalNoiseHeight)
                {
                    minLocalNoiseHeight = noiseHeight;
                }
                noiseMap[x, y] = noiseHeight;
            }
        }

        //Normalize the noise map for each value within the 2D array using an inverse lerp
        for (int y = 0; y < mapHeight; y++)
        {
            for (int x = 0; x < mapWidth; x++)
            {
                if (normalizeMode == NormalizeMode.Local)
                {
                    noiseMap[x, y] = Mathf.InverseLerp(minLocalNoiseHeight, maxLocalNoiseHeight, noiseMap[x, y]);
                }
                else
                {
                    float normalizedHeight = (noiseMap[x, y] + 1) / (maxPossibleHeight);
                    noiseMap[x, y] = Mathf.Clamp(normalizedHeight, 0, int.MaxValue);
                }
            }
        }

        return(noiseMap);
    }