【问题标题】:How Do I Generate Procedural Cube Asteroid Formations?如何生成程序立方体小行星结构?
【发布时间】:2021-03-11 12:43:43
【问题描述】:

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

我尝试使用这个 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, targetY, 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 的答案,这完全是用于多个编码项目的概念。

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

干杯。

【问题讨论】:

  • 我同意 Gnollrunner 的观点,即单纯形噪声通常更好。这主要是由于外观而不是显示相同类型的网格对齐。我们应该将术语“Perlin”视为方向变化问题的同义词,而不是平滑值。另外,我不推荐“3D out of 2D”的技巧。首先,它沿剩余轴创建每个 2D 噪声特征的阴影。它看起来也很复杂,因为它结合了 6 个噪声,但它实际上只结合了 3 个。共享相同翻转轴的那些合并为一个噪声。我推荐github.com/Auburn/FastNoiseLite

标签: minecraft noise voxel procedural


【解决方案1】:

我不太确定你在做什么,所以我只会告诉你我通常是怎么做的。我的体素使用了一些变化的行进立方体,所以我将对其进行一些更改以适应您的工作。

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

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

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

【讨论】:

  • 知道了。谢谢您的答复。我实际上已经非常接近你所说的了,我只需要添加一些乘数和常数。我最终将 perlin 噪声值全部保持为 1(持久性、频率、幅度和八度音阶),并以此作为参考来获得我需要的东西:codepen.io/fvalla/pen/KKKNwWg(调整 k 值和一些常数被插入到 3d perlin 噪声中)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多