2 years ago

3D Perlin and curl noise generator that I implemented myself in Unity a long time ago.

#Unity #PerlinNoise #CurlNoise #Programming


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

Loading...

Next up

My Pokémon Baking Book arrived today

#MyPokemonBakingBook #InsightEditions #Giveaway

Lord Vader decides to delete his Minecraft world

Made in Blender.

#StarWarsArt #FanArtFriday #ArtWeeklies #Minecraft #Blender #Animation #3D #3DArt #DeathStar #Space

What's Your Most Feared Minecraft Mob?

My first thought was this green guy who appears out of nowhere and erases all your efforts in one second

#MostFearedMob #ArtWeeklies #Blender #Animation #Minecraft #Cave #Creeper #3D #3DArt

Our 2024 Advent Calendar has opened! Day 18: @Otis_Le_PoOtis is the Creator of Bondee’s Barnyard and posts updates about their dev journey and their work on the sequel!) Accept the quest and give them a follow to get Coins and a seasonal sticker!

Comparison of view transforms in Blender using Christmas candles as an example

#Blender #3D #3DArt #ViewTransform #Christmas #Candles

Happy #WIPWednesday!

Are you working on a game?

Making some art?

Practicing a song?

Something else?

Tell us in the comments!

Spirit of the snowy forest

Made in Blender.

Anime girl model made in VRoid Studio (last image).

#Blender #3D #3DArt #Modeling #Animation #Anime #Girl #VRoid #VRoidStudio #Snow #Forest #Winter #Night #Blobcat

Chibi drawing by Aikeji, modeled and animated in 3D.

Made in Blender.

#Blender #3D #3DArt #Modeling #Animation #Chibi #Aikeji

Our 2024 Advent Calendar has opened! Day 17: @VuVuuInc is a great Creator who is a solo game dev and shares their progress on their various projects! Accept the quest and give them a follow to get Coins and a seasonal sticker!

Diglett as chocolate cake

Made in Blender.

#MyPokeCake #Pokemon #Diglett #Cake #Blender #3D #3DArt #Modeling