问题描述
现在我有一个柏林噪声函数,我传递一个种子缓冲区和另一个缓冲区,该函数用噪声值填充。我正在使用它来按程序生成地形中顶点的高度。现在的问题是地形仅限于缓冲区的大小,但我想让它连续生成块,块彼此一致,但我不知道如何使用我正在使用的当前函数来做到这一点。这是算法的代码,我可以更改什么以使其工作吗?
inline void perlInNoise2D(int nWidth,int nHeight,float *Seed,int nOctaves,float fBias,float *fOutput)
{
for(int x = 0; x < nWidth; x++)
{
for(int y = 0; y < nHeight; y++)
{
float fNoise = 0.0f;
float fScale = 1.0f;
float fScaleAccum = 0.0f;
for(int o = 0; o < nOctaves;o++)
{
int nPitch = nWidth >> o;
int sampleX1 = (x / nPitch) * nPitch;
int sampleY1 = (y / nPitch) * nPitch;
int sampleX2 = (sampleX1 + nPitch) % nWidth;
int sampleY2 = (sampleY1 + nPitch) % nWidth;
float fBlendX = (float)(x - sampleX1) / (float) nPitch;
float fBlendY = (float)(y - sampleY1) / (float) nPitch;
float fSampleT = (1.0f - fBlendX) * Seed[sampleY1 * nWidth + sampleX1] + fBlendX * Seed[sampleY1 * nWidth + sampleX2];
float fSampleB = (1.0f - fBlendX) * Seed[sampleY2 * nWidth + sampleX1] + fBlendX * Seed[sampleY2 * nWidth + sampleX2];
fNoise += (fBlendY * (fSampleB - fSampleT) + fSampleT) * fScale;
fScaleAccum += fScale;
fScale = fScale / fBias;
}
fOutput[(y * nWidth) + x] = fNoise / fScaleAccum;
}
}
}
解决方法
大概这与“地图显示”机制有关?
一种常见的技术是生成重叠的块并将它们平均在一起。作为一个简单的例子,您通过 2*nWidth
生成 2*nHeight
块。然后,您将在任何 XY 位置上有 4 个重叠的块。在地图的边缘,您将有一个带,其中并非所有块都已生成。当需要显示地图的这一部分时,您可以即时生成这些块。这会将边缘向外移动。
平均过程已经消除了边界效应。您可以通过平滑其边缘附近的每个单独的块来使其更有效。由于块边缘不重合,不同块的平滑也不重合。一个简单的三角形平滑就足够了(即平滑窗口中间为 1,边缘为 0,中间为线性),但您也可以使用高斯或任何其他函数,在中间达到峰值并逐渐向块平滑边缘。