作为业余爱好者,我对伪随机噪声生成算法,特别是Perlin和Simplex算法很感兴趣。 Simplex算法的优点在于速度(尤其是在高维情况下),但是Perlin可以相对容易地进行平铺。 我想知道是否有人知道一种可平铺的Simplex算法? 固定维数也可以,通用性更好; 伪代码可以,c / c ++更好。
作为业余爱好者,我对伪随机噪声生成算法,特别是Perlin和Simplex算法很感兴趣。 Simplex算法的优点在于速度(尤其是在高维情况下),但是Perlin可以相对容易地进行平铺。 我想知道是否有人知道一种可平铺的Simplex算法? 固定维数也可以,通用性更好; 伪代码可以,c / c ++更好。
只需像在Perlin中一样对噪声进行平铺,只是在偏移后进行。您可以通过修改获取排列的部分来执行mod 256(或& 255,无论您使用哪个)在添加到基角落的偏移量之后(而不是之前)以获得其他角落。以下是HLSL中修改后的代码片段:
uint3 iIdx0 = p0SI % 256;
uint3 iIdx1 = (p0SI + pI1) % 256;
uint3 iIdx2 = (p0SI + pI2) % 256;
uint3 iIdx3 = (p0SI + 1.0f) % 256;
uint iGI0 = gPerm[ iIdx0.x + gPerm[ iIdx0.y + gPerm[ iIdx0.z ] ] ] % 12;
uint iGI1 = gPerm[ iIdx1.x + gPerm[ iIdx1.y + gPerm[ iIdx1.z ] ] ] % 12;
uint iGI2 = gPerm[ iIdx2.x + gPerm[ iIdx2.y + gPerm[ iIdx2.z ] ] ] % 12;
uint iGI3 = gPerm[ iIdx3.x + gPerm[ iIdx3.y + gPerm[ iIdx3.z ] ] ] % 12;
p0SI是第0个角点,p12和pI2是到角点1和角点2的向量,按照通常的方式计算。请注意,在HLSL中,标量在混合操作中自动转换为向量,因此例如1.0f实际上是(1.0,1.0,1.0)。我刚刚想出了这个平铺的东西,但显然它有效。如果您需要对大行星或某些东西进行着色,但只有单精度卡,请告诉我。
编辑:想一想后,我认为您不需要更改任何内容。我认为它在256个单位时已经自动平铺了。
var F2 = 0.5*(Math.sqrt(3.0)-1.0);
var s = (xin+yin)*F2; // Hairy factor for 2D
var i = Math.floor(xin+s);
var j = Math.floor(yin+s);
var G2 = (3.0-Math.sqrt(3.0))/6.0;
var t = (xin+yin)*G2;
xin-=t;
yin-=t;
很不幸,它产生了一种看起来有些奇怪的效果(也就是,它看起来有点倾斜 :D),这通常不是问题,但取决于你需要这个噪音做什么。
由于这对我来说是个问题,我尝试将这种“反倾斜”仅应用于几个八度音阶,那些在最终输出中权重更大的八度音阶,并使用插值来处理“轻”八度音阶。 这种解决方案为我提供了基于Simplex Perlin噪声的令人满意的平铺效果,因为对所有八度音阶进行插值会在平铺边界上产生太多衰减,并且在添加更多八度音阶而没有人工倾斜时,奇怪的效果会被额外的噪声掩盖。
我最近需要使用平铺的Simplex噪声,并在这个问题中找到了答案。
对于使用任何噪声函数进行平铺噪声,您可以线性插值额外的平铺样本:
Ftileable(x, y) = (
F(x, y) * (w - x) * (h - y) +
F(x - w, y) * (x) * (h - y) +
F(x - w, y - h) * (x) * (y) +
F(x, y - h) * (w - x) * (y)
) / (wh)
其中F()是您的噪声函数。请注意,x、y必须是单个瓷砖内的坐标:x在[0,w)范围内,y在[0,h)范围内。您可以使用类似tileX = x - Math.Floor(x / w) * w或fmod()的东西。
如果性能至关重要或者对于更高维度,这可能不是正确的方法,因为它需要2^D次查找,其中D是维度。对我来说,它还会在瓷砖中心产生较低的值。
摘自: http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html