📜  3d perlin 噪声统一 - C# (1)

📅  最后修改于: 2023-12-03 15:13:08.273000             🧑  作者: Mango

3D Perlin Noise in C#

What is Perlin Noise?

Perlin Noise is a type of procedural noise used in computer graphics and animation to create natural-looking textures and patterns. It is named after its creator, Ken Perlin, and was developed in the 1980s for the movie "Tron".

Perlin Noise is a type of gradient noise that creates smooth, continuous noise by interpolating between randomly generated values. This random data is generated using a hash function, which maps input values to output values in a way that appears random.

Perlin Noise is used in a variety of applications, including computer games, movie special effects, and scientific simulations.

3D Perlin Noise

3D Perlin Noise is an extension of Perlin Noise to 3 dimensions. It creates a 3D grid of values, where each point in the grid represents a value that varies smoothly in 3 dimensions.

In order to generate 3D Perlin Noise, we generate random gradient vectors at the corners of a cube, and then interpolate between these vectors to obtain the gradient vectors at other points within the cube. We can then take the dot product of our interpolated gradient vectors with the distance vectors between the points and the corners of the cube, which gives us our final noise value.

Implementing 3D Perlin Noise in C#

To implement 3D Perlin Noise in C#, we can use a combination of Simplex Noise and interpolation techniques. Here is an example implementation:

public class PerlinNoise
{
    private readonly int[] p;
    private readonly int permutationSize;

    public PerlinNoise(int seed, int permutationSize)
    {
        this.permutationSize = permutationSize;
        p = new int[permutationSize * 2];
        var r = new Random(seed);

        for (var i = 0; i < permutationSize; i++)
        {
            p[i] = i;
        }

        for (var i = 0; i < permutationSize; i++)
        {
            var j = r.Next(permutationSize);
            var temp = p[i];
            p[i] = p[j];
            p[j] = temp;
            p[i + permutationSize] = p[i];
        }
    }

    public double Perlin(double x, double y, double z)
    {
        var xi = (int) Math.Floor(x) & (permutationSize - 1);
        var yi = (int) Math.Floor(y) & (permutationSize - 1);
        var zi = (int) Math.Floor(z) & (permutationSize - 1);

        var xf = x - Math.Floor(x);
        var yf = y - Math.Floor(y);
        var zf = z - Math.Floor(z);

        var u = Fade(xf);
        var v = Fade(yf);
        var w = Fade(zf);

        var aaa = p[p[p[xi] + yi] + zi];
        var aba = p[p[p[xi] + Inc(yi)] + zi];
        var aab = p[p[p[xi] + yi] + Inc(zi)];
        var abb = p[p[p[xi] + Inc(yi)] + Inc(zi)];
        var baa = p[p[p[Inc(xi)] + yi] + zi];
        var bba = p[p[p[Inc(xi)] + Inc(yi)] + zi];
        var bab = p[p[p[Inc(xi)] + yi] + Inc(zi)];
        var bbb = p[p[p[Inc(xi)] + Inc(yi)] + Inc(zi)];

        var x1 = Lerp(Grad(aaa, xf, yf, zf), Grad(baa, xf - 1, yf, zf), u);
        var x2 = Lerp(Grad(aba, xf, yf - 1, zf), Grad(bba, xf - 1, yf - 1, zf), u);
        var y1 = Lerp(x1, x2, v);

        x1 = Lerp(Grad(aab, xf, yf, zf - 1), Grad(bab, xf - 1, yf, zf - 1), u);
        x2 = Lerp(Grad(abb, xf, yf - 1, zf - 1), Grad(bbb, xf - 1, yf - 1, zf - 1), u);
        var y2 = Lerp(x1, x2, v);

        return (Lerp(y1, y2, w) + 1) / 2;
    }

    private static double Fade(double t) => t * t * t * (t * (t * 6 - 15) + 10);

    private static double Lerp(double a, double b, double x) => a + x * (b - a);

    private static double Grad(int hash, double x, double y, double 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);
    }

    private static int Inc(int num) => num + 1;
}

We can then use the PerlinNoise class to generate 3D Perlin Noise values like this:

var perlinNoise = new PerlinNoise(1234, 256);
var noiseValue = perlinNoise.Perlin(x, y, z);
Conclusion

Now that you understand what Perlin Noise is, how 3D Perlin Noise works, and how to implement it in C#, you can use this powerful tool to create natural-looking textures and patterns in your programming projects. Enjoy experimenting with the various parameters and possibilities of Perlin Noise!