C# 如何将比例因子添加到我的";柏林;噪声发生器?
我有一个柏林噪声发生器,我正试图用它来创建滚动地形 我有一个中心地形,周围有八个相同侧面的地形(这些地形工作得很好)和第二个三倍大的环形地形。对于这些,我需要我的噪声发生器输出三倍“密度”的噪声,这样我就可以在较小的地形上放置较大的地形,除了三倍大的瓷砖(和地图大小),它们会匹配 我不想只生成一张更大的地图;这很快就会让人望而却步 我不知道该怎么办;显而易见的解决方案都以这样或那样的方式失败了C# 如何将比例因子添加到我的";柏林;噪声发生器?,c#,terrain,perlin-noise,C#,Terrain,Perlin Noise,我有一个柏林噪声发生器,我正试图用它来创建滚动地形 我有一个中心地形,周围有八个相同侧面的地形(这些地形工作得很好)和第二个三倍大的环形地形。对于这些,我需要我的噪声发生器输出三倍“密度”的噪声,这样我就可以在较小的地形上放置较大的地形,除了三倍大的瓷砖(和地图大小),它们会匹配 我不想只生成一张更大的地图;这很快就会让人望而却步 我不知道该怎么办;显而易见的解决方案都以这样或那样的方式失败了 /// <summary> /// Generates a new per
/// <summary>
/// Generates a new perlin map.
/// </summary>
/// <param name="xStart">The left coordinate (using 0, 0 as top-left and +, + as down and to the right).</param>
/// <param name="yStart">The top coordinate (using 0, 0 as top-left and +, + as down and to the right).</param>
/// <param name="width">The width of the map.</param>
/// <param name="length">The length of the map.</param>
/// <param name="persistance">If set, values lower than 1 make the map less noisey; values greater than 1 make the map more noisy.</param>
/// <param name="fromShift">Low values here provide for a broader "base".</param>
/// <param name="toShift">High values here provide for more speckled "highlights".</param>
/// <param name="interpolate">If set to false, the algorithm will not smooth values.</param>
public double[,] Generate(
int xStart, int yStart,
int width, int length,
double? persistance,
uint fromShift, uint toShift,
bool interpolate = true,
)
{
_noiseMap = new double[width, length];
_workingMap = new double[width + 6, length + 6];
_smoothedNoise = new double[width + 6, length + 6];
int ifromShift = -(int)(toShift),
itoShift = -(int)(fromShift);
int idiv = 1 + (itoShift - ifromShift);
double ddiv = 0;
double amplitude = 0.0;
if (persistance.HasValue)
for (int i = ifromShift; i <= itoShift; ++i)
ddiv += Math.Pow(persistance.Value, i);
for (int i = ifromShift; i <= itoShift; ++i)
{
_frequency = Math.Pow(2, i);
if (persistance.HasValue) amplitude = Math.Pow(persistance.Value, i);
int useWidth = (int)(width * _frequency) + 1,
useLength = (int)(length * _frequency) + 1;
int useXStart = (int)(xStart * _frequency),
useYStart = (int)(yStart * _frequency);
double frequencyXStart = xStart * _frequency - useXStart,
frequencyYStart = yStart * _frequency - useYStart;
for (int y = 0; y < useLength + 5; ++y)
for (int x = 0; x < useWidth + 5; ++x)
{
int genX = ((int)(useXStart) + (int)((x) + 0.5));
int genY = ((int)(useYStart) + (int)((y) + 0.5));
_workingMap[x, y] = GenerateNoise(genX, genY);
}
if (interpolate)
{
for (int y = 1; y < length + 4; ++y)
for (int x = 1; x < width + 4; ++x)
{
_smoothedNoise[x, y] = SmoothedNoise(x, y);
}
if (persistance.HasValue)
for (int y = 0; y < length; ++y)
for (int x = 0; x < width; ++x)
{
_noiseMap[x, y] += InterpolatedNoise((x * _frequency) + 2 + frequencyXStart, (y * _frequency) + 2 + frequencyYStart) * amplitude;
// _noiseMap[x, y] += _workingMap[x, y] * amplitude;
}
else
for (int y = 0; y < length; ++y)
for (int x = 0; x < width; ++x)
{
_noiseMap[x, y] += InterpolatedNoise((x * _frequency) + 2 + frequencyXStart, (y * _frequency) + 2 + frequencyYStart) / idiv;
// _noiseMap[x, y] += _workingMap[x, y] / idiv;
}
}
else
if (persistance.HasValue)
for (int y = 0; y < length; ++y)
for (int x = 0; x < width; ++x)
{
_noiseMap[x, y] +=
_workingMap[(int)((x * _frequency) + 2 + frequencyXStart), (int)((y * _frequency) + 2 + frequencyYStart)] * amplitude;
}
else
for (int y = 0; y < length; ++y)
for (int x = 0; x < width; ++x)
{
_noiseMap[x, y] +=
_workingMap[(int)((x * _frequency) + 2 + frequencyXStart), (int)((y * _frequency) + 2 + frequencyYStart)] / idiv;
}
}
if (persistance.HasValue)
for (int y = 0; y < length; ++y)
for (int x = 0; x < width; ++x)
{
_noiseMap[x, y] = _noiseMap[x, y] / ddiv;
}
return _noiseMap;
}
//
///生成一个新的柏林地图。
///
///左坐标(使用0,0作为左上角,使用+,+作为右下角)。
///顶部坐标(使用0,0作为左上角,使用+,+作为右下角)。
///地图的宽度。
///地图的长度。
///如果设置,则小于1的值会降低贴图的噪声;大于1的值会使贴图更加嘈杂。
///这里的低值提供了更广泛的“基础”。
///此处的高值提供更多斑点“高光”。
///如果设置为false,算法将不会平滑值。
公共双[,]生成(
int xStart,int yStart,
整数宽度,整数长度,
双重坚持,
从移位到移位,从移位到移位,
布尔插值=真,
)
{
_noiseMap=新的双精度[宽度、长度];
_工作图=新双精度[宽度+6,长度+6];
_平滑噪声=新的双精度[宽度+6,长度+6];
int-ifromShift=-(int)(toShift),
itoShift=-(int)(fromShift);
int idiv=1+(itoShift-ifromShift);
双ddiv=0;
双振幅=0.0;
if(persistence.HasValue)
for(int i=ifromShift;i只是为了澄清(检查我对您的问题的理解)
生成一个边大小为X的贴图。
这张地图被另外九张地图B1…B9包围着,每一张地图的侧面尺寸都是X。
现在,您需要地图C1…C2,它将从外部包围地图B1…B9。这些地图的每一面的大小为3X,但只有X^2个数据点(每个数据点的大小为3x3)
对吧?
你试过用最近邻算法插值数据吗?当任何代码要求从坐标X获取数据时,只需将坐标四舍五入到三的倍数并使用它。我认为这应该行得通
另一种选择是使用,除非在每个递归步骤中将平铺分成三部分,而不是两部分。这将允许您提前停止一轮,这将向您展示您正在寻找的结果:仅在3x3网格的交点上生成数据点的高度图。无需触摸剩余的点。柏林噪波比你的样本密度大得多,因此一个算法的形状对于所有网格都是密集的。如果你想要额外的细节,你必须添加一个倍频程或第二遍噪波,在这种情况下网格将无法正确覆盖。因此,选择一个形状并使用不同的网格密度对其进行采样是一个问题ITES.更密集的数据=相同空间的更多数据。生成“更大”映射并缩放它们听起来是唯一可行的方法。完全正确。但是这些想法有一些问题。第一个想法的问题是我最终会访问数组之外的值。第二个想法的问题是,第一,使位移一致,第二,不会以更大的数组结束,而我仍然不理解这个问题,如果你把数据保存在低分辨率的版本中,然后只需采样更多的点,在每一个低分辨率点之间的2,那么你将拥有3倍的稠密数据。延迟每一个。