Exemplo n.º 1
0
        public static float PerlinNoise(float x, float y, float z)
        {
            const float MOD     = 289.0f;
            const float PERMUTE = 34.0f;

            Vector3 P   = new Vector3(x, y, z);
            Vector3 Pi0 = Mathx.Floor(P);    // Integer part for indexing
            Vector3 Pi1 = Pi0 + Vector3.one; // Integer part + 1

            Pi0 = Mathx.Mod(Pi0, MOD);
            Pi1 = Mathx.Mod(Pi1, MOD);
            Vector3 Pf0 = Mathx.Frac(P);     // Fractional part for interpolation
            Vector3 Pf1 = Pf0 - Vector3.one; // Fractional part - 1.0
            Vector4 ix  = new Vector4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);
            Vector4 iy  = new Vector4(Pi0.y, Pi0.y, Pi1.y, Pi1.y);
            Vector4 iz0 = new Vector4(Pi0.z, Pi0.z, Pi0.z, Pi0.z);
            Vector4 iz1 = new Vector4(Pi1.z, Pi1.z, Pi1.z, Pi1.z);

            Vector4 ixy  = Mathx.Permute(Mathx.Permute(ix, PERMUTE, MOD) + iy, PERMUTE, MOD);
            Vector4 ixy0 = Mathx.Permute(ixy + iz0, PERMUTE, MOD);
            Vector4 ixy1 = Mathx.Permute(ixy + iz1, PERMUTE, MOD);

            Vector4 gx0 = ixy0 * (1.0f / 7.0f);
            Vector4 gy0 = Mathx.Sub(Mathx.Frac(Mathx.Mul(Mathx.Floor(gx0), (1.0f / 7.0f))), 0.5f);

            gx0 = Mathx.Frac(gx0);
            Vector4 gz0 = Vector4.one * 0.5f - Mathx.Abs(gx0) - Mathx.Abs(gy0);
            Vector4 sz0 = Mathx.Step(gz0, Vector4.zero);

            gx0 -= Mathx.Mul(sz0, Mathx.Sub(Mathx.Step(Vector4.zero, gx0), 0.5f));
            gy0 -= Mathx.Mul(sz0, Mathx.Sub(Mathx.Step(Vector4.zero, gy0), 0.5f));

            Vector4 gx1 = ixy1 * (1.0f / 7.0f);
            Vector4 gy1 = Mathx.Sub(Mathx.Frac(Mathx.Floor(gx1) * (1.0f / 7.0f)), 0.5f);

            gx1 = Mathx.Frac(gx1);
            Vector4 gz1 = Vector4.one * 0.5f - Mathx.Abs(gx1) - Mathx.Abs(gy1);
            Vector4 sz1 = Mathx.Step(gz1, Vector4.zero);

            gx1 -= Mathx.Mul(sz1, Mathx.Sub(Mathx.Step(Vector4.zero, gx1), 0.5f));
            gy1 -= Mathx.Mul(sz1, Mathx.Sub(Mathx.Step(Vector4.zero, gy1), 0.5f));

            Vector3 g000 = new Vector3(gx0.x, gy0.x, gz0.x);
            Vector3 g100 = new Vector3(gx0.y, gy0.y, gz0.y);
            Vector3 g010 = new Vector3(gx0.z, gy0.z, gz0.z);
            Vector3 g110 = new Vector3(gx0.w, gy0.w, gz0.w);
            Vector3 g001 = new Vector3(gx1.x, gy1.x, gz1.x);
            Vector3 g101 = new Vector3(gx1.y, gy1.y, gz1.y);
            Vector3 g011 = new Vector3(gx1.z, gy1.z, gz1.z);
            Vector3 g111 = new Vector3(gx1.w, gy1.w, gz1.w);

            Vector4 TaylorInvSqrt(Vector4 v)
            {
                return(Mathx.Sub(1.79284291400159f, Mathx.Mul(0.85373472095314f, v)));
            }

            Vector4 norm0 = TaylorInvSqrt(new Vector4(
                                              Vector3.Dot(g000, g000),
                                              Vector3.Dot(g010, g010),
                                              Vector3.Dot(g100, g100),
                                              Vector3.Dot(g110, g110)
                                              ));

            g000 *= norm0.x;
            g010 *= norm0.y;
            g100 *= norm0.z;
            g110 *= norm0.w;

            Vector4 norm1 = TaylorInvSqrt(new Vector4(
                                              Vector3.Dot(g001, g001),
                                              Vector3.Dot(g011, g011),
                                              Vector3.Dot(g101, g101),
                                              Vector3.Dot(g111, g111)
                                              ));

            g001 *= norm1.x;
            g011 *= norm1.y;
            g101 *= norm1.z;
            g111 *= norm1.w;

            float n000 = Vector3.Dot(g000, Pf0);
            float n100 = Vector3.Dot(g100, new Vector3(Pf1.x, Pf0.y, Pf0.z));
            float n010 = Vector3.Dot(g010, new Vector3(Pf0.x, Pf1.y, Pf0.z));
            float n110 = Vector3.Dot(g110, new Vector3(Pf1.x, Pf1.y, Pf0.z));
            float n001 = Vector3.Dot(g001, new Vector3(Pf0.x, Pf0.y, Pf1.z));
            float n101 = Vector3.Dot(g101, new Vector3(Pf1.x, Pf0.y, Pf1.z));
            float n011 = Vector3.Dot(g011, new Vector3(Pf0.x, Pf1.y, Pf1.z));
            float n111 = Vector3.Dot(g111, Pf1);

            Vector3 fade_xyz = Mathx.SmootherStep(Pf0);
            Vector4 n_z      = Vector4.Lerp(new Vector4(n000, n100, n010, n110), new Vector4(n001, n101, n011, n111), fade_xyz.z);
            Vector2 n_yz     = Vector2.Lerp(new Vector2(n_z.x, n_z.y), new Vector2(n_z.z, n_z.w), fade_xyz.y);
            float   n_xyz    = Mathf.Lerp(n_yz.x, n_yz.y, fade_xyz.x);

            return(2.2f * n_xyz);
        }