Image 1: Animated 2D and 1D Perlin noise
Image 2 & 3: 3D curl noise field
Image 4: Animated 2D curl noise
public class PerlinNoise
{
Vector3[,,] matrix;
public readonly Vector3 Size;
public PerlinNoise(uint width,uint lenght=1,uint deepth=1)
{
width++;
lenght++;
deepth++;
matrix = new Vector3[width, lenght, deepth];
Size = new Vector3(width - 1, lenght - 1, deepth - 1);
for(uint x=0;x<width;x++)
{
for(uint y=0;y<lenght;y++)
{
for(uint z=0;z<deepth;z++)
{
matrix[x, y, z] = new Vector3(Random.value * 2 - 1, Random.value * 2 - 1, Random.value * 2 - 1).normalized;
}
}
}
}
static float fade(float t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
public float Get(float X,float Y,float Z)
{
Vector3 V = new Vector3(X, Y, Z), cell = new Vector3(Mathf.Floor(V.x), Mathf.Floor(V.y), Mathf.Floor(V.z));
float[,,] dot = new float[2, 2, 2];
float[] lerp = new float[4];
float u = fade(V.x - cell.x), v = fade(V.y - cell.y), w = fade(V.z - cell.z);
for(uint x=0;x<2;x++)
{
for(uint y=0;y<2;y++)
{
for(uint z=0;z<2;z++)
{
dot[x, y, z] = Vector3.Dot(V - new Vector3(cell.x + x, cell.y + y, cell.z + z), matrix[(int)cell.x + x, (int)cell.y + y, (int)cell.z + z]);
}
}
}
//X Lerp
lerp[0] = Mathf.Lerp(dot[0, 0, 0], dot[1, 0, 0], u);
lerp[1] = Mathf.Lerp(dot[0, 1, 0], dot[1, 1, 0], u);
lerp[2] = Mathf.Lerp(dot[0, 0, 1], dot[1, 0, 1], u);
lerp[3] = Mathf.Lerp(dot[0, 1, 1], dot[1, 1, 1], u);
//Y Lerp
lerp[0] = Mathf.Lerp(lerp[0], lerp[1], v);
lerp[2] = Mathf.Lerp(lerp[2], lerp[3], v);
//Z Lerp
return Mathf.Lerp(lerp[0], lerp[2], w);
}
}
public class FractalNoise
{
PerlinNoise[] noises;
readonly float summ = 0;
public FractalNoise(uint width,uint lenght=1,uint deepth=1,uint iterations=4)
{
noises = new PerlinNoise[iterations];
uint freq;
float freqf;
for(uint i=0;i<iterations;i++)
{
freq = (uint)Mathf.RoundToInt(Mathf.Pow(2, i));
freqf = 1 / Mathf.Pow(2, i);
summ += freqf;
noises[i] = new PerlinNoise(width * freq, lenght * freq, deepth * freq);
}
}
public float Get(float X,float Y,float Z)
{
float Out = 0, pow;
for(uint i=0;i<noises.Length;i++)
{
pow = Mathf.Pow(2, i);
Out += noises[i].Get(X * pow, Y * pow, Z * pow) * (1 / pow);
}
return Out / summ;
}
}
public class CurlNoise
{
private FractalNoise P1, P2;
public static float quality = 0.001f;
public CurlNoise(uint width, uint lenght, uint deepth,uint iterations)
{
P1 = new FractalNoise(width + 1, lenght + 1, deepth + 1, iterations);
P2 = new FractalNoise(width + 1, lenght + 1, deepth + 1, iterations);
}
private Vector3 derivative(float X, float Y, float Z, FractalNoise N)
{
return new Vector3
(
(N.Get(X + quality, Y, Z) - N.Get(X - quality, Y, Z)) / (2 * quality),
(N.Get(X, Y + quality, Z) - N.Get(X, Y - quality, Z)) / (2 * quality),
(N.Get(X, Y, Z + quality) - N.Get(X, Y, Z - quality)) / (2 * quality)
);
}
public Vector3 Get(float X,float Y,float Z)
{
return Vector3.Cross(derivative(X + 0.5f, Y + 0.5f, Z + 0.5f, P1), derivative(X + 0.5f, Y + 0.5f, Z + 0.5f, P2));
}
}
There is also a second version of Fractal Noise but I don't remember why
public class FractalNoise
{
PerlinNoise[] noises;
readonly float summ = 0;
public FractalNoise(uint width,uint lenght=1,uint deepth=1,uint iterations=4)
{
noises = new PerlinNoise[iterations];
uint freq;
float freqf;
for(uint i=0;i<iterations;i++)
{
freq = (uint)Mathf.RoundToInt(Mathf.Pow(2, i));
freqf = 1 / Mathf.Pow(2, i + 1);
summ += freqf;
noises[i] = new PerlinNoise(width * freq, lenght * freq, deepth * freq);
}
summ = 1 / summ;
}
public float Get(float X,float Y,float Z)
{
float Out = 0, pow;
for(uint i=0;i<noises.Length;i++)
{
pow = Mathf.Pow(2, i);
Out += noises[i].Get(X * pow, Y * pow, Z * pow) * (1 / Mathf.Pow(2, i + 1));
}
return Out / summ;
}
}
5 comments