我想实现一个程序生成的地形。 经过深入研究后,我得出一个结论,它应该采用梯度(相干)噪声生成算法之一,例如Perlin噪声算法。 但是,我不希望这一代完全随机。我想应用一些限制(比如应该是山脉,或者应该是低地等)。
问题:
例如,我有一条代表一些景观元素的曲线。曲线是一系列点。
答案 0 :(得分:11)
如何改进Perlin Noise算法,以便沿着这条曲线,噪声将具有一个优选的值范围(或者,为简单起见,值为0)?
这可以通过简单的p -> f(p)
数学函数转换地图中的每个像素来实现。
考虑一个函数,它将紫色线映射到蓝色曲线 - 它强调较低的位置高度以及非常高的位置高度,但使它们之间的过渡更陡峭(这个例子只是一个余弦函数,使得曲线更少平滑会使转变更加突出)。
你也可以只使用曲线的下半部分,使峰值更锐利,更低的位置区域更平坦(因此更具可玩性)。
曲线的“锐度”可以很容易地用力量调制(使效果更加显着)或平方根(降低效果)。
实现这个实际上非常简单(特别是如果你使用余弦函数) - 只需在地图中的每个像素上应用该函数。如果函数在数学上不是那么简单,那么查找表就可以正常工作(在表值之间使用三次插值,线性插值会产生伪像)。
(从我的aswer复制到another question)
如果您只需将生成的噪声转换为已知值范围(如-1.0 - 1.0),请使用此算法:
function scaleValuesTo(heightMap, newMin, newMax)
{
var min = min(heightMap);
var range = max(heightMap) - min;
var newRange = newMax - newMin;
for each coordinate x, y do:
hrightMap[x, y] = newMin + (heightMap[x, y] - min) * newRange / range;
end for
}
我想应用一些限制(比如应该是山脉,或者应该是低地等)。
这有点复杂,因为您需要指定山脉的位置。最简单的解决方案是创建一个单独的高度图(您可以在程序上执行此操作或从位图加载它,无关紧要),并使用所需地形的粗略形状,然后将其与噪声贴图一起添加。有几点需要注意:
1)确保模板地图上没有锐边(这些边缘在组合地图上非常明显)。盒子模糊通常足以达到此目的,虽然像高斯模糊这样的更复杂的滤镜可以提供更好的效果(在某些情况下,盒子模糊会在地图上保留一些锐利的边缘)。
2)您可能希望优先考虑较高海拔的噪声地图和较低海拔地区的较低优先级。这可以通过以下方式轻松实现:combinedMap[x, y] = templateMap[x, y] + (0.2 + 0.8 * templateMap[x, y]) * noiseMap[x, y]
。
您可以在此图表中看到此方法:
(我为自己的terrain generation project制作了这个)