fltray10
fltray10

Reputation: 33

Change Perlin noise algorithm to work with continuous procedural generation

Right now I have a perlin noise function where I pass a buffer of seeds and another buffer which the function fills with the noise values. I am using this to procedurely generate the heights of the vertices in a terrain. The problem is right now the terrain is limited to the size of the buffer but I want to have it continuosly generate chunks with the chunks being consistant with eachother but I don't see how to do that with the current function I am using. Here is the code for the algorithm is there anything I can change to make it work?

inline void perlInNoise2D(int nWidth,int nHeight, float *Seed, int nOctaves, float fBias, float *fOutput)
{
    for(int x = 0; x < nWidth; x++)
    {
        for(int y = 0; y < nHeight; y++)
        {
            float fNoise = 0.0f;
            float fScale = 1.0f;
            float fScaleAccum = 0.0f;
            for(int o = 0; o < nOctaves;o++)
            {                    
                int nPitch = nWidth >> o; 
                
                int sampleX1 = (x / nPitch) * nPitch;
                int sampleY1 = (y / nPitch) * nPitch;

                int sampleX2 = (sampleX1 + nPitch) % nWidth;
                int sampleY2 = (sampleY1 + nPitch) % nWidth;

                float fBlendX = (float)(x - sampleX1) / (float) nPitch;
                float fBlendY = (float)(y - sampleY1) / (float) nPitch;
                
                float fSampleT = (1.0f - fBlendX) * Seed[sampleY1 * nWidth + sampleX1] + fBlendX * Seed[sampleY1 * nWidth + sampleX2];
                float fSampleB = (1.0f - fBlendX) * Seed[sampleY2 * nWidth + sampleX1] + fBlendX * Seed[sampleY2 * nWidth + sampleX2];

                fNoise += (fBlendY * (fSampleB - fSampleT) + fSampleT) * fScale;

                fScaleAccum += fScale;

                fScale = fScale / fBias;
            }
            fOutput[(y * nWidth) + x] = fNoise / fScaleAccum;
        }
    }
}

Upvotes: 0

Views: 607

Answers (1)

MSalters
MSalters

Reputation: 179991

Presumably this is tied in to a "map reveal" mechanism?

A common technique is to generate overlapping chunks and average them together. As a simple example, you generate chunks of 2*nWidth by 2*nHeight. You'd then have 4 overlapping chunks at any XY pos. At the edge of the map, you'll have a strip where not all chunks have been generated. When this part of the map needs to be revealed, you generate those chunks on the fly. This moves the edge outwards.

The averaging process already smooths out the boundary effects. You can make this more effective by smoothing out each individual chunk near its edges. Since the chunk edges do not coincide, the smoothing of different chunks does not coincide either. A simple triangle smooth could be sufficient (i.e. the smooth window is 1 in the middle, 0 at the edge, and linear in between) but you could also use a gaussian or any other function that peaks in the middle and gradually smooths towards the chunk edge.

Upvotes: 1

Related Questions