2009-08-21 48 views
3

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

+1

[这个问题也在这里回答](http://gamedev.stackexchange.com/questions/23625/how-do-you-generate-tileable-perlin-noise),虽然这里的答案也很有趣 – bobobobo 2012-02-11 04:12:36

+0

I浪费了几天的时间来处理Simplex Noise,只是发现它已被授权(美国专利#6867776)!浪费我的时间。不要浪费你的时间,而要使用“经典噪音”。 – 2011-05-24 07:37:28

+0

佩林噪音没有获得专利? http://www.wikipatents.com/US-Patent-6867776/standard-for-perlin-noise,以防万一你不知道,Kenneth Perlin创造了Simplex噪音来代替他的旧Perlin噪音,因为它更快,有较少的文物。 – raRaRa 2011-06-22 13:03:44

回答

2

看来这个问题已经合理解决了here,详细描述了工作解决方案here背后的想法。对于一个长期存在的问题,这是一个梦幻般的答案

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必须是单个图块内的坐标:x in [0,w),y in [0,h)。你可以使用像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

+0

这就是平铺佩林噪音,但不是单纯的噪音。 – fbrereto 2010-09-08 16:06:47

+0

该链接讨论了Perlin噪声,但没有明确说明该方法仅适用于它。我有一个工作的2D实现平铺单工噪声,但选择了一个替代方案,因为振幅朝向平铺中心减小。 Gabor噪声似乎产生了良好的结果和瓦片而不必诉诸于这种方法(http://graphics.cs.kuleuven.be/publications/LLDD09PNSGC/)。 – BenC 2010-09-09 21:36:37

3

只是平铺的噪音,你会在布林只有做到这一点歪斜后以同样的方式。您可以通过修改后得到的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是矢量到角落一个和角2以通常的方式计算出来。请注意,在HLSL中,标量向混合操作中的向量自动提升,例如1.0f实际上是(1.0,1.0,1.0)。我只是想出了这个平铺图片,但实际上它工作正常。如果你需要遮蔽一个大行星或者一些垃圾,但是你的卡片只有一个精度,那么还有几个步骤。打我。

编辑:你知道想着之后多一些,我不认为你有任何改变。我认为它以256个单位自动进行拼贴。

1

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

在从一个直的(ortonormal)网格单纯噪声,x和y得到偏斜找到单纯的点处于(在2D的三角形),所以用普通平铺技术(%255或其他),它确实瓦,但倾斜坐标上的瓷砖,即它“对角地”拼贴,这是无用的。

我找到的一个简单的解决方案是“解决”结果,以便原始的X和Y首先倾斜到“左侧”,然后算法会将它们倾斜到“向右”,并且最终结果将重新对齐到非偏斜网格。

如果,例如,你的单纯实现类似于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噪声给了我满意的平铺,因为所有八度上的插值都会在瓦片边界上产生太多的衰减,并且当添加更多的八度而没有人为偏斜时,看起来效果会被额外的噪声掩盖。