平铺单面噪音?

时间:2009-08-21 17:32:15

标签: c++ c algorithm textures procedural

我一直对伪随机噪声生成感兴趣(作为业余爱好者),特别是Perlin和Simplex算法。 Simplex的优点是速度(特别是在更高的尺寸),但Perlin可以相对容易地平铺。我想知道是否有人知道平铺单纯形算法?固定尺寸很好,通用性更好;伪代码很好,c / c ++更好。

4 个答案:

答案 0 :(得分:3)

按照与Perlin相同的方式平铺你的噪音,只能在歪斜后进行。您可以通过修改获取permutaions的部分来执行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点,pI2和PI2是以通常方式计算的拐角1和拐角2的向量。请注意,在HLSL中,标量会在混合操作中自动提升为向量,因此例如1.0f实际上是(1.0,1.0,1.0)。我只是认为这个平铺stuf,但显然它的工作原理。如果你需要遮挡一个大行星或一些狗屎,但只需要在你的卡上有一个精度,还有几个步骤。打我

编辑:你知道在考虑之后我不认为你必须改变任何东西。我认为它实现了256个单位的自动切片。

答案 1 :(得分:2)

即使过了几年,这个问题仍然是谷歌的最佳结果。

在单纯形噪声中,来自直(正规)网格的x和y得到偏斜以找到该点所处的单形(二维中的三角形),因此使用常见的平铺技术(%255或其他),它就是平铺,但是在倾斜坐标上的瓷砖,就是它“对角线”,这是非常无用的。

我发现一个简单的解决方案是“取消”结果,使原始的X和Y首先“向左”倾斜,然后算法将它们“向右”倾斜,最后结果将重新对齐到非倾斜网格。

例如,如果您的Simplex实现类似于SimplexNoise.java,您可以在网络上的任何地方找到它,它会使用以下方式偏斜网格:

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),这通常不是问题,但取决于你需要的噪音。

由于这对我来说是一个问题,我尝试将这种“反向偏移”仅应用于几个八度音阶,即在最终输出中重量更大的八度音程,而是使用插值来表示“更轻”的八度音阶。这个解决方案给了我基于单纯Perlin噪声的令人满意的平铺,导致所有八度音程上的插值会在拼贴边界上产生太多的衰减,并且当添加更多的八度音阶而没有人为倾斜时,看起来很难看的效果被掩埋在额外的噪声之下。

答案 2 :(得分:2)

似乎这个问题已得到合理解决here,并详细描述了工作解决方案here背后的想法。一个长期存在的问题的绝佳答案!

答案 3 :(得分:1)

我最近需要平铺单纯噪音,并遇到了这个问题。

对于使用任何噪声函数的平铺噪声,您可以线性插值其他平铺样本:

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必须是单个图块中的坐标:[0,w)中的x,[0,h]中的y。你可以使用像tileX = x - Math.Floor(x / w)* w或fmod()这样的东西。

如果性能至关重要或者尺寸较高,这可能不是一种可行的方法,因为它需要对D维进行2 ^ D查找。对于我来说,它也会向瓷砖中心产生较低的值。

取自: http://webstaff.itn.liu.se/~stegu/TNM022-2005/perlinnoiselinks/perlin-noise-math-faq.html