5

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

4

4 回答 4

4

只需像在 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 点,pI2 和 PI2 是按通常方式计算的角点 1 和角点 2 的向量。请注意,在 HLSL 中,标量在混合操作中自动提升为向量,因此例如 1.0f 实际上是 (1.0,1.0,1.0)。我只是想出了这个平铺的东西,但显然它有效。如果你需要为一个大行星或一些狗屎着色,但你的卡上只有单精度,那么还有几个步骤。打我。

编辑:你再想一想就知道了,我认为你不需要改变任何东西。我认为它在实施时会自动平铺 256 个单位。

于 2010-11-27T04:44:56.477 回答
3

It would seem this question has been reasonably solved here, with a detailed description of the idea behind the working solution here. A fantastic answer to a long-standing problem!

于 2012-04-27T16:53:20.043 回答
2

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

在单纯形噪声中,来自直线(正交)网格的 x 和 y 被倾斜以找到点所在的单纯形(2D 中的三角形),因此使用常见的平铺技术(%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;

Unfortunately, it produces a somehow strange-looking effect (that is, it looks a bit skewed :D ), which is not usually a problem, but depends on what you need that noise for.

Since it was a problem for me, I tried applying this "inverse-skewing" only to a couple of octaves, those that weight more in the final output, and instead used interpolation for "lighter" octaves. This solution gave me satisfactory tiling based on simplex Perlin noise, cause interpolation on all octaves would produce too much attenuation on tile borders, and when more octaves are added without artificial skewing the strage-looking effect gets buried under the additional noise.

于 2012-04-27T16:27:15.037 回答
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

于 2010-09-07T20:22:20.553 回答