unity 2d perlin noise
public static float[] GenerateNoiseMap(int mapWidth, int mapHeight, int seed, float scale, int octaves, float persistance, float lacunarity, Vector2 offset)
{
float[] noiseMap = new float[mapWidth * mapHeight];
var random = new System.Random(seed);
// We need atleast one octave
if (octaves < 1)
{
octaves = 1;
}
Vector2[] octaveOffsets = new Vector2[octaves];
for (int i = 0; i < octaves; i++)
{
float offsetX = random.Next(-100000, 100000) + offset.x;
float offsetY = random.Next(-100000, 100000) + offset.y;
octaveOffsets[i] = new Vector2(offsetX, offsetY);
}
if (scale <= 0f)
{
scale = 0.0001f;
}
float maxNoiseHeight = float.MinValue;
float minNoiseHeight = float.MaxValue;
// When changing noise scale, it zooms from top-right corner
// This will make it zoom from the center
float halfWidth = mapWidth / 2f;
float halfHeight = mapHeight / 2f;
for (int x = 0, y; x < mapWidth; x++)
{
for (y = 0; y < mapHeight; y++)
{
float amplitude = 1;
float frequency = 1;
float noiseHeight = 0;
for (int i = 0; i < octaves; i++)
{
float sampleX = (x - halfWidth) / scale * frequency + octaveOffsets[i].x;
float sampleY = (y - halfHeight) / scale * frequency + octaveOffsets[i].y;
// Use unity's implementation of perlin noise
float perlinValue = Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1;
noiseHeight += perlinValue * amplitude;
amplitude *= persistance;
frequency *= lacunarity;
}
if (noiseHeight > maxNoiseHeight)
maxNoiseHeight = noiseHeight;
else if (noiseHeight < minNoiseHeight)
minNoiseHeight = noiseHeight;
noiseMap[y * mapWidth + x] = noiseHeight;
}
}
for (int x = 0, y; x < mapWidth; x++)
{
for (y = 0; y < mapHeight; y++)
{
// Returns a value between 0f and 1f based on noiseMap value
// minNoiseHeight being 0f, and maxNoiseHeight being 1f
noiseMap[y * mapWidth + x] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[y * mapWidth + x]);
}
}
return noiseMap;
}