Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I've made a Heightmap Generator that creates island heightmaps like in this picture:

enter image description here

I am dividing the grayscale ( 0 - 255 ) into 4 diferent parts ( water, sand, gras and forrest ) and after coloring those layers the heightmap looks like this:

enter image description here

As you can see, the "coast" is pretty noisy ( there are some sand-pixels on the edges, that are not connected to the island itself )

So my question is, How to smooth that noisy coast / beach ?

Is there any quick method that detects those "lonly" pixels and turns them into water ?

can i use the smoothing function below to smooth the final output ?

( I'm working with either a float[][] or a Color[][] array )


UPDATE

here is my smoothing function that i've implemented in my heightmap generation core.

i don't know if i can use this function for this purpose.

    public static float[][] GenerateSmoothNoise( float[][] baseNoise, int octave ) {
        int width = baseNoise.Length;
        int height = baseNoise[ 0 ].Length;

        float[][] smoothNoise = GetEmptyArray<float>( width, height );

        int samplePeriod = 1 << octave; // calculates 2 ^ k
        float sampleFrequency = 1.0f / samplePeriod;

        for( int i = 0; i < width; i++ ) {
            //calculate the horizontal sampling indices
            int sample_i0 = ( i / samplePeriod ) * samplePeriod;
            int sample_i1 = ( sample_i0 + samplePeriod ) % width; //wrap around
            float horizontal_blend = ( i - sample_i0 ) * sampleFrequency;

            for( int j = 0; j < height; j++ ) {
                //calculate the vertical sampling indices
                int sample_j0 = ( j / samplePeriod ) * samplePeriod;
                int sample_j1 = ( sample_j0 + samplePeriod ) % height; //wrap around
                float vertical_blend = ( j - sample_j0 ) * sampleFrequency;

                //blend the top two corners
                float top = Interpolate( baseNoise[ sample_i0 ][ sample_j0 ],
                    baseNoise[ sample_i1 ][ sample_j0 ], horizontal_blend );

                //blend the bottom two corners
                float bottom = Interpolate( baseNoise[ sample_i0 ][ sample_j1 ],
                    baseNoise[ sample_i1 ][ sample_j1 ], horizontal_blend );

                //final blend
                smoothNoise[ i ][ j ] = Interpolate( top, bottom, vertical_blend );
            }
        }

        return smoothNoise;
    }

and for those who are interested, i'm calling GenerateSmoothNoise() in this way ->

    public static float[][] GeneratePerlinNoise( float[][] baseNoise, int octaveCount ) {
        int width = baseNoise.Length;
        int height = baseNoise[ 0 ].Length;

        float[][][] smoothNoise = new float[ octaveCount ][][]; //an array of 2D arrays containing

        float persistance = 0.7f;

        //generate smooth noise
        for( int i = 0; i < octaveCount; i++ ) {
            smoothNoise[ i ] = GenerateSmoothNoise( baseNoise, i );
        }

        float[][] perlinNoise = GetEmptyArray<float>( width, height ); //an array of floats initialised to 0

        float amplitude = 1.0f;
        float totalAmplitude = 0.0f;

        //blend noise together
        for( int octave = octaveCount - 1; octave >= 0; octave-- ) {
            amplitude *= persistance;
            totalAmplitude += amplitude;

            for( int i = 0; i < width; i++ ) {
                for( int j = 0; j < height; j++ ) {
                    perlinNoise[ i ][ j ] += smoothNoise[ octave ][ i ][ j ] * amplitude;
                }
            }
        }

        //normalisation
        for( int i = 0; i < width; i++ ) {
            for( int j = 0; j < height; j++ ) {
                perlinNoise[ i ][ j ] /= totalAmplitude;
            }
        }

        return perlinNoise;
    }
share|improve this question
    
How about applying a gaussian, or another low-pass filter? it should remove those high-frequency noise elements. –  Panda Pajama Apr 23 '13 at 7:16
    
simple idea, i had it too. i thought that bluring the image will give me a not nice looking output, but i'll give it a try –  Ace Apr 23 '13 at 12:21

1 Answer 1

Note: I'm gonna use the term "pixel" here to refer to a unit of land in your height map.

I'll assume your definition of noise are groups of land pixel are that smaller than certain size and you want these removed (turned into water).

In that case, a simple method may be just counting the total number of connected pixels (size) for each group of land pixels(islands) and removing ones with pixel count below a certain threshold. You can do this in O(n) time using flood fill (http://en.wikipedia.org/wiki/Flood_fill) as follows:

  1. For each pixel, start a flood-fill to count number connected land pixels (don't replace any pixels yet). Store this starting pixel in a list if number pixels < threshold. You flag each pixel that you've encountered in the algorithm so that you never look at the same pixel twice.
  2. For each pixel you stored in that list, flood-fill and replace land pixel with water pixel.

Pesudocode:

for each pixel at point p in map
    count = floodFillCount(p, map)
    if(count < threshold)
        remove_list.add(p)
for each point p in remove_list
    floodFillReplace(p, water_height, map)

Note that this method will not remove things like a very long thin lines of land.

share|improve this answer
    
thx for that solution. i also thought of usinf a flood algorythm, but i thought of smoothing the map after the noisemap generating and befor the layer assignment. there are smoe smooth functions like in this example ( scroll down to Smoothed Noise ) -> freespace.virgin.net/hugo.elias/models/m_perlin.htm i understand the smoothing function, and i also have implemented it in my core heightmap generating algorythm ( perlin noise ), but i can't figure out how i can use this function afterwards.. look at my update abow for the code. –  Ace Apr 22 '13 at 23:11
    
Hmm.. I don't know anything about perlin noise. I'm kinda curious how that stuff works though so I might take a look at it later though. Hopefully someone knows that stuff well already and give a better answer. –  XiaoChuan Yu Apr 22 '13 at 23:28
    
yeah thats really interesting stuff, i'm also just new to perlin noise heightmap generating. but i'll try your solution anyway ^^ –  Ace Apr 22 '13 at 23:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.