0
\$\begingroup\$

I'm writing a Perlin noise generator in C++ for terrain generation but the generator produces weird JPEG-like artifacts instead of proper noise.

I've tried doing it using C# in Unity and confirmed the results are the same. When I swap the generator for Unity's, it generates correctly. The FBM function is working properly with the Unity implementation. It must be the Perlin noise itself then. This is the code:

public class Perlin
{
    private static float Grad(int hash, float x, float y)
    {
        return ((hash & 1) == 0 ? x : -x) + ((hash & 2) == 0 ? y : -y);
    }
    private static float Fade(float v)
    {
        return v * v * v * (v * (v * 6.0f - 15.0f) + 10.0f);
    }
    public static float ImprovedPerlin(float x, float y)
    {
        int X = (int)Mathf.Floor(x) & 255;
        int Y = (int)Mathf.Floor(y) & 255;

        x -= Mathf.Floor(x);
        y -= Mathf.Floor(y);

        float U = Fade(x);
        float V = Fade(y);

        int A = (Perms[X] + Y) & 255;
        int B = (Perms[X + 1] + Y) & 255;

        return Mathf.Lerp(V,
                Mathf.Lerp(U,
                    Grad(Perms[A], x, y),
                    Grad(Perms[B], x - 1.0f, y)
                ),
                Mathf.Lerp(U,
                    Grad(Perms[A + 1], x, y - 1.0f),
                    Grad(Perms[B + 1], x - 1.0f, y - 1.0f)
                )
            );
    }

    private static int[] Perms = new int[257] {
        151, 160, 137,  91,  90,  15, 131,  13, 201,  95,  96,  53, 194, 233,   7, 225,
        140,  36, 103,  30,  69, 142,   8,  99,  37, 240,  21,  10,  23, 190,   6, 148,
        247, 120, 234,  75,   0,  26, 197,  62,  94, 252, 219, 203, 117,  35,  11,  32,
        57, 177,  33,  88, 237, 149,  56,  87, 174,  20, 125, 136, 171, 168,  68, 175,
        74, 165,  71, 134, 139,  48,  27, 166,  77, 146, 158, 231,  83, 111, 229, 122,
        60, 211, 133, 230, 220, 105,  92,  41,  55,  46, 245,  40, 244, 102, 143,  54,
        65,  25,  63, 161,   1, 216,  80,  73, 209,  76, 132, 187, 208,  89,  18, 169,
        200, 196, 135, 130, 116, 188, 159,  86, 164, 100, 109, 198, 173, 186,   3,  64,
        52, 217, 226, 250, 124, 123,   5, 202,  38, 147, 118, 126, 255,  82,  85, 212,
        207, 206,  59, 227,  47,  16,  58,  17, 182, 189,  28,  42, 223, 183, 170, 213,
        119, 248, 152,   2,  44, 154, 163,  70, 221, 153, 101, 155, 167,  43, 172,   9,
        129,  22,  39, 253,  19,  98, 108, 110,  79, 113, 224, 232, 178, 185, 112, 104,
        218, 246,  97, 228, 251,  34, 242, 193, 238, 210, 144,  12, 191, 179, 162, 241,
        81,  51, 145, 235, 249,  14, 239, 107,  49, 192, 214,  31, 181, 199, 106, 157,
        184,  84, 204, 176, 115, 121,  50,  45, 127,   4, 150, 254, 138, 236, 205,  93,
        222, 114,  67,  29,  24,  72, 243, 141, 128, 195,  78,  66, 215,  61, 156, 180,
        151
    };
}

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ Did you mean to use U & V as the third parameter of your lerps (the blend factor), rather than as one of the endpoints of the interpolation? \$\endgroup\$
    – DMGregory
    Commented Dec 25, 2022 at 5:38
  • \$\begingroup\$ Thank you so much! I didn't even think about the wrong order because in my mind lerp had the alpha value as the first parameter. \$\endgroup\$
    – truepaddii
    Commented Dec 25, 2022 at 5:55
  • \$\begingroup\$ Oh! If that's all it was, could I ask you to write up the solution as an answer below? \$\endgroup\$
    – DMGregory
    Commented Dec 25, 2022 at 12:09
  • \$\begingroup\$ I was asking you to write your own answer. I'm on vacation and just checking the comments atm. 😉 \$\endgroup\$
    – DMGregory
    Commented Dec 25, 2022 at 20:41

2 Answers 2

1
\$\begingroup\$

The comment provided by DMGregory solved the issue here:

Did you mean to use U & V as the third parameter of your lerps (the blend factor), rather than as one of the endpoints of the interpolation?

The corrected blending of the ImprovedPerlin function would look like this:

// ...
return Mathf.Lerp(Mathf.Lerp(
                    Grad(Perms[A], x, y),
                    Grad(Perms[B], x - 1.0f, y)
                    U,
                ),
                Mathf.Lerp(
                    Grad(Perms[A + 1], x, y - 1.0f),
                    Grad(Perms[B + 1], x - 1.0f, y - 1.0f),
                    U,
                ),
                V
            );
// ...
\$\endgroup\$
0
\$\begingroup\$

The comment provided by DMGregory solved the issue here:

Did you mean to use U & V as the third parameter of your lerps (the blend factor), rather than as one of the endpoints of the interpolation?

\$\endgroup\$
2
  • 2
    \$\begingroup\$ This answer would be better if it showed the corrected code. \$\endgroup\$
    – DMGregory
    Commented Dec 27, 2022 at 15:51
  • 1
    \$\begingroup\$ @DMGregory I've posted the answer below with the corrected code attached. \$\endgroup\$
    – truepaddii
    Commented Dec 28, 2022 at 16:24

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.