0

I am trying to generate a procedural terrain using perlin noise. Before, I was just creating a 1000 * 1000 vertice terrain so I just had a simple function that would fill the height map with the noise values.

However now I am trying to generate a terrain that generates chunks as the camera moves around and I don't think this method is suitable since each chunk would be generated with it's own random heightmap and chunks will not look consistant with eachother. Instead I am using this header file to generate noise which just takes and x and y but whatever values I give it does not seem to generate consistant values and I am not sure why

class Noise {    
public:
int seed;

Noise(int seed) {
    this->seed = seed;
}

float noise(int x, int y) {
    int n = x + y * 57 + seed;
    n = ( n << 13 ) ^ n;
    float rand = 1 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f;
    return rand;
}

float noise(int x, int y, int z) {
    int n = x + y + z * 57 + seed;
    n = ( n << 13 ) ^ n;
    float rand = 1 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0f;
    return rand;
}

float smoothNoise(int x, int y) {
    float corners = (noise(x+1, y+1) + noise(x+1, y-1) + noise(x-1, y+1) + noise(x-1, y-1)) / 16.0f;
    float sides = (noise(x, y+1) + noise(x, y-1) + noise(x-1, y) + noise(x+1, y)) / 8.0f;
    float center = noise(x, y) / 4.0f;
    
    return corners + sides + center;
}

float interpolatedNoise(float x, float y) {
    int integerX = (int)x;
    float fractionalX = x - integerX;
    
    int integerY = (int)y;
    float fractionalY = y - integerY;
    
    float v1 = smoothNoise(integerX, integerY);
    float v2 = smoothNoise(integerX + 1, integerY);
    float v3 = smoothNoise(integerX, integerY + 1);
    float v4 = smoothNoise(integerX + 1, integerY + 1);
    
    float i1 = interpolateCosine(v1, v2, fractionalX);
    float i2 = interpolateCosine(v3, v4, fractionalX);
    
    return interpolateCosine(i1, i2, fractionalY);
    
}

// x must be in the range [0,1]
float interpolateLinear(float a, float b, float x) {
    return a * (1 - x) + b * x;
}

float interpolateCosine(float a, float b, float x) {
    float ft = x * (float)glm::pi<float>();
    float f = (1 - ((float)glm::pi<float>())) * 0.5f;
    return a * (1 - f) + b * f;
} 

};`

I am calling interpolatedNoise() like this:

for(int y=x; x < config->width;x++)
{
   for(int y = 0; y < config->height;y++)
   { 
       map[x * config->height + y] = noise.interpolatedNoise((config->width * gridPosX + x) * 0.1f,(config->height * gridPosY + y) * 0.1f)/2.0f + 0.5f; // convert from -1:1 to 0:1
   }  
} 

This is what the terrain looks like using this 
:

but I want the terrain to be smooth. The parameters I pass into the function are divided by some value. The larger I make this value for more random the terrain is with the boxes being smaller and the smaller I make it I just get larger boxes but a more consistant looking terrain.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
fltray10
  • 31
  • 6

1 Answers1

0

I am not quite sure how you are calling your Noise constructor, but one problem I see is in the constructor. It should be this->seed = seed;, otherwise you are assigning the argument seed to the value of itself. The seed variable of Noise then would just be a random number, and I feel like that's causing problems. Again, not sure how your callling Noise constructor, but thats my best guess.

Ty Staszak
  • 115
  • 2
  • 11
  • I just got rid of the 'this->' accidently when trying to neaten up the code in this post. Thank you for pointing it out. – fltray10 Jan 28 '21 at 20:28
  • Yeah, wasn't sure if it was intentionally or not. Would have left a comment, but not enough rep. – Ty Staszak Jan 28 '21 at 21:04