My problem is I dont know how to insert the simplex noise/perlin noise values to my world generator to produce a better looking landscape, is there anyone can show simple code showing how to implement it.
BTW, im new at programming, so any answers will be appreciated and it will greatly helps me.
Heres the code:
noise.h
#pragma once
class PerlinNoise
{
public:
// Constructor
PerlinNoise();
PerlinNoise(double _persistence, double _frequency, double _amplitude, int _octaves, int _randomseed);
// Get Height
double GetHeight(double x, double y) const;
// Get
double Persistence() const { return persistence; }
double Frequency() const { return frequency; }
double Amplitude() const { return amplitude; }
int Octaves() const { return octaves; }
int RandomSeed() const { return randomseed; }
// Set
void Set(double _persistence, double _frequency, double _amplitude, int _octaves, int _randomseed);
void SetPersistence(double _persistence) { persistence = _persistence; }
void SetFrequency( double _frequency) { frequency = _frequency; }
void SetAmplitude( double _amplitude) { amplitude = _amplitude; }
void SetOctaves( int _octaves) { octaves = _octaves; }
void SetRandomSeed( int _randomseed) { randomseed = _randomseed; }
double Total(double i, double j) const;
double GetValue(double x, double y) const;
double Interpolate(double x, double y, double a) const;
double Noise(int x, int y) const;
double persistence, frequency, amplitude;
int octaves, randomseed;
};
noise.cpp:
#include "noise.h"
PerlinNoise::PerlinNoise()
{
persistence = 0;
frequency = 0;
amplitude = 0;
octaves = 0;
randomseed = 0;
}
PerlinNoise::PerlinNoise(double _persistence, double _frequency, double _amplitude, int _octaves, int _randomseed)
{
persistence = _persistence;
frequency = _frequency;
amplitude = _amplitude;
octaves = _octaves;
randomseed = 2 + _randomseed * _randomseed;
}
void PerlinNoise::Set(double _persistence, double _frequency, double _amplitude, int _octaves, int _randomseed)
{
persistence = _persistence;
frequency = _frequency;
amplitude = _amplitude;
octaves = _octaves;
randomseed = 2 + _randomseed * _randomseed;
}
double PerlinNoise::GetHeight(double x, double y) const
{
return amplitude * Total(x, y);
}
double PerlinNoise::Total(double i, double j) const
{
//properties of one octave (changing each loop)
double t = 0.0f;
double _amplitude = 1;
double freq = frequency;
for(int k = 0; k < octaves; k++)
{
t += GetValue(j * freq + randomseed, i * freq + randomseed) * _amplitude;
_amplitude *= persistence;
freq *= 2;
}
return t;
}
double PerlinNoise::GetValue(double x, double y) const
{
int Xint = (int)x;
int Yint = (int)y;
double Xfrac = x - Xint;
double Yfrac = y - Yint;
//noise values
double n01 = Noise(Xint-1, Yint-1);
double n02 = Noise(Xint+1, Yint-1);
double n03 = Noise(Xint-1, Yint+1);
double n04 = Noise(Xint+1, Yint+1);
double n05 = Noise(Xint-1, Yint);
double n06 = Noise(Xint+1, Yint);
double n07 = Noise(Xint, Yint-1);
double n08 = Noise(Xint, Yint+1);
double n09 = Noise(Xint, Yint);
double n12 = Noise(Xint+2, Yint-1);
double n14 = Noise(Xint+2, Yint+1);
double n16 = Noise(Xint+2, Yint);
double n23 = Noise(Xint-1, Yint+2);
double n24 = Noise(Xint+1, Yint+2);
double n28 = Noise(Xint, Yint+2);
double n34 = Noise(Xint+2, Yint+2);
//find the noise values of the four corners
double x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09);
double x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06);
double x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08);
double x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04);
//interpolate between those values according to the x and y fractions
double v1 = Interpolate(x0y0, x1y0, Xfrac); //interpolate in x direction (y)
double v2 = Interpolate(x0y1, x1y1, Xfrac); //interpolate in x direction (y+1)
double fin = Interpolate(v1, v2, Yfrac); //interpolate in y direction
return fin;
}
double PerlinNoise::Interpolate(double x, double y, double a) const
{
double negA = 1.0 - a;
double negASqr = negA * negA;
double fac1 = 3.0 * (negASqr) - 2.0 * (negASqr * negA);
double aSqr = a * a;
double fac2 = 3.0 * aSqr - 2.0 * (aSqr * a);
return x * fac1 + y * fac2; //add the weighted factors
}
double PerlinNoise::Noise(int x, int y) const
{
int n = x + y * 57;
n = (n << 13) ^ n;
int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff;
return 1.0 - double(t) * 0.931322574615478515625e-9;/// 1073741824.0);
}
main.cpp
#include "noise.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
int main(){
PerlinNoise pn;
srand(time(NULL)); // Random
for(int c = 1;c<=100;c++){
int x = rand() % 10000;
int y = rand() & 10000;
double t = pn.Noise(x, y);
if(t >= -1 && t <= -0.5){ // For Soil
cout << "=";
}else if(t >= -0.5 && t <= 0){ // For Stone
cout << "+";
}else if(t >= 0 && t <= 0.5){ // For Sand
cout << "*";
}else if(t >= 0.5 && t <= 1){ // For Lava
cout << "#";
}
if(c%10 == 0){
cout << '\n';
}
}
}
Output:
https://i.stack.imgur.com/A3tap.jpg
But I want this kind of output
https://i.stack.imgur.com/FXHpc.jpg
But I want the the soil will be in the topmost layer and generate terrain.