So I am creating procedural terrain using perlin noise and it’s going fairly well so far. I can create shorelines and mountain ranges. I can’t attach more than one photo apparently, so if you can imagine the image at the bottom without the rivers then that’s what I have at the moment.
At the moment my shoreline and mountain ranges work by generating a width x height (eg 200 x 200) map and setting each value through a function:
coastline::
float coastGen(int x, int y, float fB, float fS, float fG, Vector2 fO)
{
float retValue;
float mapDiagonal = Mathf.Sqrt((mapWidth * mapWidth) + (mapHeight * mapHeight));
Vector2 shorePoint;
shorePoint.x = Mathf.Sin(fB) * fS;
shorePoint.y = Mathf.Cos(fB) * fS;
float X = x - fO.x;
float Y = y - fO.y;
float A = Mathf.Sqrt(((X - shorePoint.x) * (X - shorePoint.x)) + ((Y - shorePoint.y) * (Y - shorePoint.y)));
float C = Mathf.Sqrt((X * X) + (Y * Y));
float B = fS;
float angFromOrigin = Mathf.Acos((C * C - A * A - B * B) / (-2 * A * B));
float angFromShore = angFromOrigin - 90 * Mathf.Deg2Rad;
float distFromShore = Mathf.Sin(angFromShore) * A;
if (distFromShore >= 0)
{
retValue = 1 - (distFromShore / (mapDiagonal - fS)) * fG;
if (retValue < 0.2f)
{
retValue = 0.2f;
}
}
else
{
retValue = 1;
}
return retValue;
}
mountain range::
float mountGen(int x, int y, float fS, float fG, Vector2 fO)
{
float X = x - fO.x;
float Y = y - fO.y;
float dist = (fS - Mathf.Sqrt((X * X) + (Y * Y))) * fG/100;
if (dist < 1)
{
dist = 1;
}
return dist;
}
map generation::
for (int y = 0; y < mapHeight; y++)
{
for (int x = 0; x < mapWidth; x++)
{
featureMap[x, y] = 1;
for (int i = 0; i < terrainFeatures.Length; i++)
{
float fG = 1;
if (terrainFeatures[i].featureType == featureOptions.Coast)
{
fG = coastGen(x, y, terrainFeatures[i].featureBearing, terrainFeatures[i].featureShore, terrainFeatures[i].featureGradient, terrainFeatures[i].featureOffset);
}
else if (terrainFeatures[i].featureType == featureOptions.Mountains)
{
fG = mountGen(x, y, terrainFeatures[i].featureShore, terrainFeatures[i].featureGradient, terrainFeatures[i].featureOffset);
}
else if (terrainFeatures[i].featureType == featureOptions.River)
{
fG = riverGen(x, y, riverMap);
}
if (fG != 1)
{
featureMap[x, y] = featureMap[x, y] * fG;
}
}
}
}
Sorry for the long chunks of code!
Anyway, my question is : how can I create a river feature, ideally using “spaghetti” perlin noise? I’d like it to follow similar methods to the other ones (i.e. I can apply it to the general feature map).
So far what I have creates a kind of river system, but I can’t isolate one strand or control it at all.
float riverGen(int x, int y, float[,] riverMap)
{
float height = riverMap[x,y];
float lowBound = 0.45f;
float topBound = 0.55f;
if (height >= lowBound && height <= topBound)
{
return 0;
}
else
{
return 1;
}
}
Again, sorry for code dumps!
Any help is appreciated