0

I am trying to generate terrain for a simple game I'm making using midpoint displacement, and it's working well so far, but I keep getting weird artifacts that I don't see in most of the examples that I see online and I don't really know what is causing them. They look like this: https://i.stack.imgur.com/HIkb8.png

the mostly smooth generation seems to be littered with random and incredibly sudden changes in height. Is this normal or am I doing something wrong?

The class that I'm using to generate the heightmap looks like this:

package util;

import java.util.Random;

public class HeightmapGen {

private HeightmapGen(){}

//The size of the map will be 2^iterations + 1
public static int[][] genMap(int iterations, double roughness){
    Random rand = new Random();
    return genMap(iterations, roughness, rand.nextLong());
}
public static int[][] genMap(int iterations, double roughness, long seed){
    Random r = new Random(seed);
    double rConstant = Math.pow(2,-roughness);
    double currRoughVal = 1.0;

    int size = (int)Math.pow(2,iterations); //size needs to be a power of 2 + 1 - this size includes 0
    int subSize = size; //the "working" size of the squares
    int stride = subSize/2;
    boolean oddline = false; //not entirely sure what this does either...

    int[][] map = new int[size + 1][size + 1];

    //initalize corners
    //int init = r.nextInt();
    //int init = 0;
    //map[0][0] = map[0][size] = map[size][0] = map[size][size] = init;
    map[0][0] = r.nextInt();
    map[0][size] = r.nextInt();
    map[size][0] = r.nextInt();
    map[size][size] = r.nextInt();

    while(stride != 0){

        //the square part
        for(int x = stride; x < subSize; x += stride){
            for(int y = stride; y < subSize; y += stride){
                map[x][y] = (int)(r.nextInt() * currRoughVal) + avgSquareVals(x, y, stride, map);
                y += stride;
            }
            x += stride;
        }

        //the diamond part
        //not entirely sure what oddline is for, but it seems nessicary
        oddline = false;
        for (int x = 0; x < subSize; x += stride){
            oddline = (oddline == false);
            for (int y = 0; y < subSize; y += stride){
                if (oddline && y == 0){y += stride;}

                map[x][y] = (int)(r.nextInt() * currRoughVal) + avgDiamondVals(x, y, stride, size, subSize, map);

                //this wraps the map - i'm ignoring this for now
                //if(x == 0){}
                //if(y == 0){}

                y += stride;
            }
            //not sure x doesn't need to be incremented, but it doesn't?
        }

        //reduce range and halve stride
        currRoughVal *= rConstant;
        stride /= 2;
    }

    return map;
}

private static int avgSquareVals(int x, int y, int stride, int[][] map){
    return (map[x + stride][y + stride] +
            map[x + stride][y - stride] +
            map[x - stride][y + stride] +
            map[x - stride][y - stride])/4;
}
private static int avgDiamondVals(int x, int y, int stride, int size, int subSize, int[][] map){
    if(x == 0){
        return (map[x + stride][y] +
                map[x][y + stride] +
                map[x][y - stride])/3;
    }
    else if(x == size){
        return (map[x - stride][y] +
                map[x][y + stride] +
                map[x][y - stride])/3;
    }
    else if(y == 0){
        return (map[x + stride][y] +
                map[x - stride][y] +
                map[x][y + stride])/3;
    }
    else if( y == size){
        return (map[x + stride][y] +
                map[x - stride][y] +
                map[x][y - stride])/3;
    }
    else{
        return (map[x + stride][y] +
                map[x - stride][y] +
                map[x][y + stride] +
                map[x][y - stride])/4;
    }
}
}

It's not perfect and parts of it I don't understand - it's based off of the code I found here: http://www.gameprogrammer.com/fractal.html

tshepang
  • 12,111
  • 21
  • 91
  • 136
  • The problem spots appear to be in the vicinity of extreme high or low points. Is it possible you're overflowing the maximum/minimum values of your datatype and wrapping around? – Mark Mar 31 '14 at 05:42
  • Yup, I think that's exactly what happened. I also lowered the initial roughness constant to .25, and that got rid of a lot of the sudden changes in height. Thanks! – user1995906 Mar 31 '14 at 06:07

0 Answers0