Home > Software engineering >  How to implement Offset on Perlin noise?
How to implement Offset on Perlin noise?

Time:12-25

I need a little help, I have this Perlin noise function, but I don't know how to properly create offsets.

I am using this to create infinite terrain generation and when I use this script it the noise values of individual chunks don't fit together properly. And they create holes.

Is there a way of fixing this ?

  public  float[,] GenerateNoise(int chunkSize, int octaves, string seed, float noiseScale, float persistence, float lacunarity, Vector2 offset)
    {
        
        if (noiseScale <= 0)
        {
            noiseScale = 0.0001f;
        }


        float halfWidth = chunkSize / 2f;
        float halfHeight = chunkSize / 2f;

        float[,] noiseMap = new float[chunkSize, chunkSize];
        System.Random rand = new System.Random(seed.GetHashCode());

        //Octaves offset
        Vector2[] octavesOffset = new Vector2[octaves];
        for (int i = 0; i < octaves; i  )
        {
            float offset_X = rand.Next(-100000, 100000)   offset.x;
            float offset_Y = rand.Next(-100000, 100000)   offset.y;
            octavesOffset[i] = new Vector2(offset_X / chunkSize , offset_Y / chunkSize);
        }

        for (int x = 0; x < chunkSize; x  )
        {
            for (int y = 0; y < chunkSize; y  )
            {

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

                
                for (int i = 0; i < octaves; i  )
                {


                    float sampleX = (x - halfWidth) / noiseScale * frequency   octavesOffset[i].x * frequency;
                    float sampleY = (y - halfHeight) / noiseScale * frequency   octavesOffset[i].y * frequency;

                    float noiseValue = Mathf.PerlinNoise(sampleX, sampleY);
                    noiseHeight  = noiseValue * amplitude;
                    noiseHeight -= superpositionCompensation;

                    amplitude *= persistence;
                    frequency *= lacunarity;
                    superpositionCompensation = amplitude / 2;

                }

                noiseMap[x, y] = Mathf.Clamp01(noiseHeight); 
                
            }
        }

        return noiseMap;
    }

CodePudding user response:

It is quite simple actually, just add the chunk x,y coordinates to Mathf.PerlinNoise. Taking your code as an example, you can:

  1. Pass chunkPosition as an argument to it:

    public  float[,] GenerateNoise(Vector2 chunkPos, int chunkSize, int octaves, string seed, float noiseScale, float persistence, float lacunarity, Vector2 offset)
    
  2. Add it to Mathf.PerlinNoise invocation:

    float noiseValue = Mathf.PerlinNoise(sampleX   chunkPos.x, sampleY   chunkPos.y);
    

Then make sure to generate each chunk with an appropriate chunkPos, where chunkPos can be its transform.position or whatever coordinates you have. That's it.

  • Related