【问题标题】:Procedural generated terrain not lining up with neighboring terrain程序生成的地形与相邻地形不对齐
【发布时间】:2015-11-12 21:29:21
【问题描述】:

我使用 CoherentNoise 库在 Unity 中创建了程序地形。生成本身工作得很好,添加到场景中的每个地形对象都会正确生成高度图并应用它们。问题是我生成的噪声在地形对象之间不是连续的,如下图所示。

下面列出了为每个地形对象生成噪声的函数

public void GenerateHeightMap() {
    for (int z = 0; z < zRes; z++) {
        for (int x = 0; x < xRes; x++) {
            var xCoord = (float)((size.x * position.x) + x) / (xRes - 1);
            var zCoord = (float)((size.z * position.z) + z) / (zRes - 1);

            var value = settings.GetModule().GetValue(xCoord, zCoord, 0);
            heights[x, z] = (float)(value / 2f) + 0.5f;
        }
    }
}

快速解释xCoordzCoord

首先这些 x 和 z 坐标找到它们的起始生成位置(大小 * 位置)。然后他们添加循环偏移(x 或 z)并除以地形的分辨率。理论上,这应该允许噪声生成器抓取相邻地形对象的 x、z 坐标并返回对齐的高度图。

关于为什么这些地形游戏对象不排列的任何想法?

如果有人想看一下整个项目,我已将项目上传到Github,在那里可以查看和下载。

【问题讨论】:

  • 其实你确定你没有遇到纹理坐标系的问题吗?
  • 我不相信,CoherentNoise 库在使用 GetValue 函数时确实使用了纹理坐标空间,但是.. 我确保在 GetValue 函数中将 Unity 的坐标空间输入到正确的参数中.

标签: c# unity3d procedural-generation


【解决方案1】:

有一些问题,因为你的前提不成立

理论上,这应该允许噪声发生器...

如果你的前提是正确的,那么如果你计算一个坐标,比如说两个相邻的瓷砖zCoord,它应该是相等的。

所以,假设 position=(0,0), z=zRes(循环的最后一个 z 元素之后的理论索引) 并与 position(0, 1), z=0 进行比较。

在一种情况下,您最终得到zCoord=zRes / (zRes-1),而在另一种情况下得到zCoord=size.z / (zRes-1)。因此存在差异。

试试这样的(对不起,我在旅行,没有团结尝试一下):

public void GenerateHeightMap() {
    for (int z = 0; z < zRes; z++) {
        for (int x = 0; x < xRes; x++) {
            var xCoord = (float)((size.x * position.x) + x * size.x/xRes) / (xRes - 1);
            var zCoord = (float)((size.z * position.z) + z * size.z/zRes) / (zRes - 1);

            var value = settings.GetModule().GetValue(xCoord, zCoord, 0);
            heights[x, z] = (float)(value / 2f) + 0.5f;
        }
    }
}

【讨论】:

  • 嗯,我尝试了你的建议,它创造了一些看起来很时髦的地形i.imgur.com/r7KXjz8.png
  • 哎呀。从好的方面来说,它看起来更加连续。从该屏幕截图中很难判断到底发生了什么。我提出的一件事是(x,z)的比例发生了变化,所以这可能是导致噪声函数异常的原因。我从未使用过 CoherentNoise,但如果它是基于 Perlin 的,那可能就是问题所在。只是为了测试,尝试通过乘以 0.05 或类似的值来缩小 xCoord 和 zCoord。同时,我会重新考虑这一点,以保持相同的规模。
  • 感谢您帮助我解决这个问题,我会继续按照您的建议工作。至于 CoherentNoise,它是基于 Perlin 的。他们还使用 X、Y、Z,其中 Y 是水平的,Z 是垂直的,转换为 Unity 的坐标系很烦人。 CoherentNoise 实际上只是 .NET 的 libNoise(我相信您以前听说过)的一个实现
  • 哦,呵呵。我敢打赌这是因为 (x,z) 用于索引数组。把最后一行改成heights[x*xRes/size.x, z*zRes/size.z] = ...
  • 再次出现同样的尖刺结果,i.imgur.com/jlpec5E.png 但这绝对是连续的。我认为 xStep 和 zStep 没有通过 for 循环触及所有地形是一个问题。
【解决方案2】:

我的程序地形生成代码最近遇到了类似的问题,这就是它解决我不连续问题的方法:

public void GenerateHeightMap() 
{
  for (int z = 0; z < zRes; z++) 
  {
    //         ratio                    annotation1          annotation2
    var zCoord=((float)z/(float)zRes) + (position.z/size.z)*((zRes-1)/zRes); // place the zCoord here so the calculation won't be repeated (zRes-1) times
    for (int x = 0; x < xRes; x++) 
    {
      var xCoord=((float)x/(float)xRes) + (position.x/size.x)*((xRes-1)/xRes);
      var value = settings.GetModule().GetValue(xCoord, zCoord, 0);
      heights[x, z] = (float)(value / 2f) + 0.5f;
    }
  }
}

注释1: 将位置除以大小以标准化坐标 (如:pos(200,50) size(50,50) 表示此地形与原点之间沿x轴有4个地形,沿z轴有1个地形)

注释2: 地形的相对坐标不会从 0 变为 1, 但从 0 到几乎 1(因为 z 只到 (zRes-1))。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-18
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多