如何将多个高度图缝合在一起以消除接缝? [英] How can you stitch multiple heightmaps together to remove seams?

查看:219
本文介绍了如何将多个高度图缝合在一起以消除接缝?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一种算法(用C#语言),该算法会将两个或多个不相关的高度图缝合在一起,以便在两个图之间没有可见的接缝.基本上,我想模仿此页面上找到的功能: http://www.bundysoft.com/wiki/doku.php ?id = tutorials:l3dt:stitching_heightmaps

I am trying to write an algorithm (in c#) that will stitch two or more unrelated heightmaps together so there is no visible seam between the maps. Basically I want to mimic the functionality found on this page : http://www.bundysoft.com/wiki/doku.php?id=tutorials:l3dt:stitching_heightmaps

(您可以只看图片来了解我在说什么)

(You can just look at the pictures to get the gist of what I'm talking about)

我还希望能够获取一个高度图并对其进行更改,以便可以对其进行平铺,以创建一个无尽的世界(所有这些都用于Unity3d).但是,如果我可以将多个高度图缝合在一起,那么我应该能够轻松地修改算法以对单个高度图起作用,因此我不必担心这部分.

I also want to be able to take a single heightmap and alter it so it can be tiled, in order to create an endless world (All of this is for use in Unity3d). However, if I can stitch multiple heightmaps together, I should be able to easily modify the algorithm to act on a single heightmap, so I am not worried about this part.

任何一种指导都将不胜感激,因为我一直在寻找解决方案,但没有成功.只需朝正确方向轻推一下,我们将不胜感激!我知道许多图像处理技术都可以应用于高度图,但是一直找不到能够产生所需结果的图像处理算法.例如,图像拼接似乎仅适用于视野重叠的图像,而不适用于高度图不相关的情况.

Any kind of guidance would be appreciated, as I have searched and searched for a solution without success. Just a simple nudge in the right direction would be greatly appreciated! I understand that many image manipulation techniques can be applied to heightmaps, but have been unable to find a image processing algorithm that produces the results I'm looking for. For instance, image stitching appears to only work for images that have overlapping fields of view, which is not the case with unrelated heightmaps.

利用FFT低通滤波器以某种方式工作还是仅在生成单个图素高度图时有用?

Would utilizing a FFT low pass filter in some way work, or would that only be useful in generating a single tileable heightmap?

由于该算法将在Unit3d中使用,因此任何c#代码都必须限于.Net 3.5,因为我认为这是Unity使用的最新版本. 感谢您的帮助!

Because the algorithm is to be used in Unit3d, any c# code will have to be confined to .Net 3.5, as I believe that's the latest version Unity uses. Thanks for any help!

推荐答案

好吧,似乎我以前尝试解决此问题的方法是正确的.我最初尝试将高度图缝合在一起涉及到高度图上每个点的以下步骤:

Okay, seems I was on the right track with my previous attempts at solving this problem. My initial attemp at stitching the heightmaps together involved the following steps for each point on the heightmap:

1)找到高度图上一个点与其相对点之间的平均值.相反的点只是在x轴(如果缝合水平边缘)或z轴(对于垂直边缘)上反射的第一个点.

1) Find the average between a point on the heightmap and its opposite point. The opposite point is simply the first point reflected across either the x axis (if stitching horizontal edges) or the z axis (for the vertical edges).

2)使用以下公式找到该点的新高度:

2) Find the new height for the point using the following formula:

newHeight = oldHeight + (average - oldHeight)*((maxDistance-distance)/maxDistance);

其中的距离是从高度图上的点到最近的水平或垂直边缘的距离(取决于要缝合的边缘).距离小于maxDistance(该距离是影响地形变化的可调值)的任何点都可以根据此公式进行调整.

Where distance is the distance from the point on the heightmap to the nearest horizontal or vertical edge (depending on which edge you want to stitch). Any point with a distance less than maxDistance (which is an adjustable value that effects how much of the terrain is altered) is adjusted based on this formula.

这是一个旧公式,尽管它在大多数地形上都产生了非常不错的效果,但它在高度图点更改的区域和高度图点未更改的区域之间的区域中创建了明显的线条.我几乎立即意识到,这是因为更改后的区域的斜率与未更改的区域相比过于陡峭,因此在两者之间形成了明显的对比.不幸的是,我以错误的方式解决了这个问题,寻找有关如何使对比区域模糊或平滑以消除线条的解决方案.

That was the old formula, and while it produced really nice results for most of the terrain, it was creating noticeable lines in the areas between the region of altered heightmap points and the region of unaltered heightmap points. I realized almost immediately that this was occurring because the slope of the altered regions was too steep in comparison to the unaltered regions, thus creating a noticeable contrast between the two. Unfortunately, I went about solving this issue the wrong way, looking for solutions on how to blur or smooth the contrasting regions together to remove the line.

在使用平滑技术取得很少成功之后,我决定尝试减小更改区域的斜率,希望它可以更好地与未更改区域的斜率融合.我很高兴地报告,这大大改善了我的拼接算法,删除了上面报告的99%的行.

After very little success with smoothing techniques, I decided to try and reduce the slope of the altered region, in the hope that it would better blend with the slope of the unaltered region. I am happy to report that this has improved my stitching algorithm greatly, removing 99% of the lines reported above.

旧公式的主要罪魁祸首是这部分:

The main culprit from the old formula was this part:

(maxDistance-distance)/maxDistance

,它根据点到最近边缘的距离线性生成一个介于0和1之间的值.随着高度图点和边缘之间的距离增加,高度图点将利用越来越少的平均值(如上定义),并越来越多地向其原始值移动.这种线性插值是导致步长斜率过高的原因,但是幸运的是,我在Unity API的Mathf类中找到了一种内置方法,该方法可以进行二次(我相信是三次)插值.这是 SmoothStep方法.

which was producing a value between 0 and 1 linearly based on the distance of the point to the nearest edge. As the distance between the heightmap points and the edge increased, the heightmap points would utilize less and less of the average (as defined above), and shift more and more towards their original values. This linear interpolation was the cause of the too step slope, but luckily I found a built in method in the Mathf class of Unity's API that allows for quadratic (I believe cubic) interpolation. This is the SmoothStep Method.

使用此方法(我相信可以在Xa框架中找到类似的方法,该框架

Using this method (I believe a similar method can be found in the Xna framework found here), the change in how much of the average is used in determining a heightmap value becomes very severe in middle distances, but that severity lessens exponentially the closer the distance gets to maxDistance, creating a less severe slope that better blends with the slope of the unaltered region. The new forumla looks something like this:

//Using Mathf - Unity only?
float weight = Mathf.SmoothStep(1f, 0f, distance/maxDistance);

//Using XNA
float weight = MathHelper.SmoothStep(1f, 0f, distance/maxDistance);

//If you can't use either of the two methods above
float input = distance/maxDistance;
float weight = 1f + (-1f)*(3f*(float)Math.Pow(input, 2f) - 2f*(float)Math.Pow(input, 3f));

//Then calculate the new height using this weight
newHeight = oldHeight + (average - oldHeight)*weight;

可能会有更好的插值方法可以产生更好的拼接效果.如果找到这样的方法,我肯定会更新这个问题,以便其他希望进行高度图拼接的人都能找到他们需要的信息.用线性插值法在正确的轨道上对rincewound表示敬意!

There may be even better interpolation methods that produce better stitching. I will certainly update this question if I find such a method, so anyone else looking to do heightmap stitching can find the information they need. Kudos to rincewound for being on the right track with linear interpolation!

这篇关于如何将多个高度图缝合在一起以消除接缝?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆