如何生成程序性立方体小行星地层?

问题描述

我正在尝试寻找生成基于柏林噪声的立方体素小行星的最佳方法,但似乎无法找到一致的方法

我尝试使用这个 perlin 噪声库:https://github.com/warmwaffles/Noise/blob/master/src/prime/PerlinNoise.java

使用这种静态方法来消除 3D 噪声:


    public static double Perlin3D(PerlinNoise noise,double x,double y,double z)
        {
            double AB = noise.getHeight(x,y);
            double BC = noise.getHeight(y,z);
            double AC = noise.getHeight(x,z);

            double BA = noise.getHeight(y,x);
            double CB = noise.getHeight(z,y);
            double CA = noise.getHeight(z,x);

            double ABC = AB + BC + AC + BA + CB + CA;
            return ABC / 6;
        }

还有这种制作实际小行星的方法

    public void Generate()
        {
            PerlinNoise p = new PerlinNoise(seed,persistence,frequency,amplitude,octaves);

            GameObject newUnit = Instantiate(unit,genPoint,Quaternion.identity);
            newUnit.transform.SetParent(transform);

            for (int x = 0; x < maxdistanceFromCenter * 2; x++)
            {
                for (int y = 0; y < maxdistanceFromCenter * 2; y++)
                {
                    for (int z = 0; z < maxdistanceFromCenter * 2; z++)
                    {
                        int targetX = genPoint.x - maxdistanceFromCenter + x;
                        int targetY = genPoint.y - maxdistanceFromCenter + y;
                        int targetZ = genPoint.z - maxdistanceFromCenter + z;

                        Vector3Int targetPos = new Vector3Int(targetX,targetY,targetZ);
                        Vector3 targetVector3d = new Vector3(targetX,targetZ).normalized;

                        double distFromCenter = Vector3.distance(genPoint,targetPos);

                        double maxdistFromCenter = (NoiseHelper.Perlin3D(p,targetVector3d.x,targetVector3d.y,targetVector3d.z));

                        print(maxdistFromCenter);

                        if (distFromCenter < maxdistFromCenter)
                        {
                            GameObject newUnit2 = Instantiate(unit,targetPos,Quaternion.identity);
                            newUnit2.transform.SetParent(transform);
                        }
                    }
                }
            }
        }

不幸的是,我得到的结果看起来 like this.

当我真的在寻找这样的结果时 Blender mock-up I made.

通过它的外观,您可以看到我正在使用 Unity 来执行此操作,以查看我的代码输出内容。我绝不是在寻找 Unity 对此的回答,这完全是用于多个编码项目的概念。

我希望得到一些指导、答案或建议,以实现我的目标。感谢您在高级方面的所有帮助,我非常感谢您抽出时间帮助我,

干杯。

解决方法

我不太确定你在做什么,所以我会告诉你我通常是怎么做的。我的体素使用了行进立方体的一些变体,所以我会稍微改变一下以适合您的工作。

首先,您可以遍历所有体素并取中心点。然后将其标准化。我假设你的小行星在中间有 (0.0,0.0,0),如果不只是抵消一切。在任何情况下,它都会为您提供单位球体周围的点。然后,您可以将这些点乘以某个常数以获得更大的点范围,例如 5 或 10。数字越大,噪声频率越高。玩它,直到它看起来不错。接下来将这些点插入 3D 鼻子、Perlin 或单纯形中。单工通常更好。这将为每个体素提供一个从 -1 到 1 的值。

然后你只需要为你的小行星设置一个基本半径。例如,如果您的体素在所有维度上都从 -10 到 +10,您可以使用 8 的基本半径。如果您将其添加到您的噪声中,您将获得大约 7 到 9 的值,用于围绕球体的每个体素。如果体素中心到原点的距离小于它的计算数字,则它是实心的。如果它更大,则它是非固体的。宾果游戏大功告成。

您还可以上下调整噪声,以提供更高的峰值和更低的谷值。然后有多种方法可以结合噪声来获得许多不同类型的地形。 Ridged Multi-Fractal 是我的最爱之一。然而,在低分辨率下这并不重要,因为无论如何你都看不到细节。