111 lines
3.2 KiB
C#
111 lines
3.2 KiB
C#
using UnityEngine;
|
|
|
|
namespace NoiseTools
|
|
{
|
|
public class PerlinNoise : NoiseGeneratorBase
|
|
{
|
|
#region Constructor
|
|
|
|
public PerlinNoise(int frequency, int repeat, int seed = 0)
|
|
: base(frequency, repeat, seed)
|
|
{
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private members
|
|
|
|
static float Fade(float t)
|
|
{
|
|
return t * t * t * (t * (t * 6 - 15) + 10);
|
|
}
|
|
|
|
static float Lerp(float t, float a, float b)
|
|
{
|
|
return a + t * (b - a);
|
|
}
|
|
|
|
static float Grad(int hash, float x, float y)
|
|
{
|
|
return ((hash & 1) == 0 ? x : -x) + ((hash & 2) == 0 ? y : -y);
|
|
}
|
|
|
|
static float Grad(int hash, float x, float y, float z)
|
|
{
|
|
var h = hash & 15;
|
|
var u = h < 8 ? x : y;
|
|
var v = h < 4 ? y : (h == 12 || h == 14 ? x : z);
|
|
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 2D noise
|
|
|
|
protected override float Calculate2D(Vector2 point)
|
|
{
|
|
var x = point.x * Frequency;
|
|
var y = point.y * Frequency;
|
|
|
|
var cx = Mathf.FloorToInt(x);
|
|
var cy = Mathf.FloorToInt(y);
|
|
|
|
x -= cx;
|
|
y -= cy;
|
|
|
|
var u = Fade(x);
|
|
var v = Fade(y);
|
|
|
|
var h00 = Hash(CellID(cx , cy ));
|
|
var h01 = Hash(CellID(cx + 1, cy ));
|
|
var h10 = Hash(CellID(cx , cy + 1));
|
|
var h11 = Hash(CellID(cx + 1, cy + 1));
|
|
|
|
var n = Lerp(v, Lerp(u, Grad(h00, x, y ), Grad(h01, x-1, y )),
|
|
Lerp(u, Grad(h10, x, y-1), Grad(h11, x-1, y-1)));
|
|
|
|
return n * 0.5f + 0.5f;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 3D noise
|
|
|
|
protected override float Calculate3D(Vector3 point)
|
|
{
|
|
var x = point.x * Frequency;
|
|
var y = point.y * Frequency;
|
|
var z = point.z * Frequency;
|
|
|
|
var cx = Mathf.FloorToInt(x);
|
|
var cy = Mathf.FloorToInt(y);
|
|
var cz = Mathf.FloorToInt(z);
|
|
|
|
x -= cx;
|
|
y -= cy;
|
|
z -= cz;
|
|
|
|
var u = Fade(x);
|
|
var v = Fade(y);
|
|
var w = Fade(z);
|
|
|
|
var h000 = Hash(CellID(cx , cy , cz ));
|
|
var h001 = Hash(CellID(cx + 1, cy , cz ));
|
|
var h010 = Hash(CellID(cx , cy + 1, cz ));
|
|
var h011 = Hash(CellID(cx + 1, cy + 1, cz ));
|
|
var h100 = Hash(CellID(cx , cy , cz + 1));
|
|
var h101 = Hash(CellID(cx + 1, cy , cz + 1));
|
|
var h110 = Hash(CellID(cx , cy + 1, cz + 1));
|
|
var h111 = Hash(CellID(cx + 1, cy + 1, cz + 1));
|
|
|
|
var n = Lerp(w, Lerp(v, Lerp(u, Grad(h000, x, y , z ), Grad(h001, x-1, y , z )),
|
|
Lerp(u, Grad(h010, x, y-1, z ), Grad(h011, x-1, y-1, z ))),
|
|
Lerp(v, Lerp(u, Grad(h100, x, y , z-1), Grad(h101, x-1, y , z-1)),
|
|
Lerp(u, Grad(h110, x, y-1, z-1), Grad(h111, x-1, y-1, z-1))));
|
|
return n * 0.5f + 0.5f;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|