【问题标题】:Terrain generation - Interpolating between multiple biome height-maps地形生成 - 在多个生物群落高度图之间进行插值
【发布时间】:2019-03-23 12:25:21
【问题描述】:

我最近一直在使用统一引擎和 C# 进行一些地形生成,我能够解决我遇到的大部分问题,但是这个问题让我在没有有效解决方案的情况下陷入困境:

所以在我解释我的问题之前,我先解释一下到目前为止我取得了什么成就;通过使用 perlin 噪声,我能够生成一个网格并通过组合多个高度图将不同的高度应用于其顶点。出于优化目的,我还能够生成和销毁地形块以及根据查看者的位置管理块的 LOD。接下来我研究了生物群落区域分布系统,对于区域分布,我使用了代表温度和湿度水平的 2 个 perlin 噪声函数的组合,使用 voronoi 单元分布,世界被一些模划分为虚拟正方形,另一个 perlin 噪声函数是用于创建一个函数,该函数根据它作为输入接收的虚拟正方形返回一个 voronoi 控制点,到目前为止,这只是我想到的一个 voronoi 控制点分布算法,到目前为止还不错...

接下来,我想让地形更有趣(它是为生存游戏设计的),所以我开始为每个生物群落(每个 voronoi 单元)设置独特的噪声函数组合,但这不会是那样容易......生物群系之间的接缝肯定会开始显示,因此需要一个生物群系插值系统,起初我认为一个简单的权重函数可以完成工作,这意味着对于每个顶点计算它与相邻生物群系细胞的距离并计算权重每个单元格在那个顶点上都有:一个介于 0 和 1 之间的值,0 = 最低效果(生物群落点真的很远,太远了,对顶点没有任何影响); 1 = 最高效果(生物群落点与顶点位于完全相同的位置,因此,它将对顶点的高度产生最大影响,并且将单独由生物群落的独特噪声函数合成)然后计算每个相乘的总和顶点位置处的生物群系噪声函数对顶点的生物群系权重(旁注:所有生物群系点权重的总和应始终为 1)。

相邻点的权重计算示例:

在图片中: 蓝色箭头所指的生物群系的权重约为 0.1f(小值,因为它远离采样点,因此对采样点高度的影响最小)。 绿色箭头所指的生物群系的重量约为 0.45f。 粉红色箭头所指的生物群系的重量约为 0.45f(与绿色尖头的生物群系相同,因为它与采样点的距离相同)。 橙点=根据它计算权重的样本点。

有一种算法使用称为细胞噪声的噪声,它是某种 voronoi 分布,类似于我正在寻找的东西,但它没有考虑其他相邻生物群落对最终值的影响,这意味着一个点距离任何生物群落控制点的最低点,但它不会混合不同的生物群落,这对我来说是必须的,我希望我能很好地解释我对这个算法的问题。无论如何,这是一个例子。

蜂窝噪声高度图示例:

一小段代码来清除最终顶点高度:

float HeightAtPosition(float x, float z)
{
    //Returns an array containing information of all the adjacent biome 
    //control points(mainly their position and their biome type)
    BiomeControlPoint[] adjacentControlPoints = GetAdjacentBiomePoints(x, z);
    //Returns an array containing values between 0 and 1
    //Iputs: An array of all the adjacent biome points, a sample coordinate
    //Output: A float array containing the weight of each biome on the 
    //        coordinate(between 0 and 1)
    float[] weights = CalcWeights(adjacentControlPoints, new Vector2(x, z));
    float finalHeight = 0;
    for (int i = 0; i < adjacentControlPoints.Length; i++)
    {
        finalHeight += adjacentControlPoints[i] * weights[i];
    }
    return finalHeight;
}

如果我可以使这些函数更高效,这将是一个很好的解决方案: GetAdjacentBiomePoints(x, z) 和 CalcWeights(adjacentControlPoints, new Vector2(x, z))

我读到的另一种方法是双线性插值,但我不太了解它的实现,所以我很高兴从另一个来源学习。 这个视频讨论了这个方法:https://www.youtube.com/watch?v=ujGW5y1x7JgCreating Minecraft in C++/ OpenGL - Part Four

我很高兴向您学习任何新信息和/或想法 :) 提前谢谢!

【问题讨论】:

  • 里面是不是有问题,或者你只是在征求意见?
  • 我会使用您已经拥有的 perlin 噪声函数来计算生物群系属性,然后根据其属性找到特定的生物群系。例如,你可以用你的噪声函数来计算降雨和温度,高降雨/高温是丛林,低降雨高温是沙漠等。
  • Leo Bartkus:我对这种方法很熟悉,我正在使用这种方法与生物群落分布的 voronoi 图相结合。 Ron Beyer:是的......有一个问题,如果有人能想出一种更好的方法来在生物群系噪声函数之间进行插值,而不是我指定的方式,这种方式在未来随着玩家流畅生成块的事件中对性能成本的影响很小在世界各地移动,也许是双线性插值,但我不太确定如何实施,或者更确切地说它会如何为这个事业做出贡献,所以我希望有一些更有经验的意见。谢谢
  • 另外我在实现 GetAdjacentBiomePoints() 方法时遇到了一些困难,我只想以有效的方式获取相关点

标签: c# voronoi perlin-noise procedural-generation heightmap


【解决方案1】:

您可以尝试加权 voronoi 图。我的php实现:https://tetramatrix.github.io/awvd/.

【讨论】:

    【解决方案2】:

    你可以走另一条路:

    • 为每个像素生成温度和湿度水平
    • 生成每个生物群系与这些值的匹配程度
      • 将每个生物群系的强度预先计算为二维查找表?
    • 选取 X 个最佳匹配项
    • 标准化强度(总和为 1)
    • 您独特的噪声函数组合是 X 个最佳生物群系的加权和

    我个人使用网格图并将生物群系的值从具有大单元格的小地图插入到具有小单元格的大地图。那里的插值要容易得多:

    对不起,是java。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多