我目前正在尝试在2D中实现HLSL上的perlin噪声。我看了Ken's improved Perlin Noise,但我不明白从permuation-arrays到Vectors的转换是如何工作的。 我知道我可以得到像这样的哈希码
int g00 = p[floorX + p[floorY]],
g10 = p[floorX + 1 + p[floorY]],
g01 = p[floorX + p[floorY + 1]],
g11 = p[floorX + 1 + p[floorY + 1]];
(floorX和floorY是分解为8位的x,y坐标。)
来自here,但我仍然不明白。我也不明白Ken的实现中的“grad(...)”方法是如何工作的。 任何人都可以解释一下它是如何工作的吗?
答案 0 :(得分:1)
Ken Perlin的实际java实现实际上是他的GPU实现的伪代码,这意味着某些部分(特别是你坚持使用的部分)是彻头彻尾的难以理解的(使用一些优化理论)。
为了便于阅读, 尝试Stefan Gustavson的参考java实现,来自Simplex Noise Demystified'(2005)in pdf,它更易读,因为它部分设计为教学工具。
在他的grad()函数中使用一长串位操作和条件(使用三元短手算子)来选择伪随机单位向量。特别是,它应该从围绕单位圆(在2D中)或球体(在立方体的边的中点附近,在3D中)等均匀分布的集合中进行选择,并且以相同的概率进行选择。每一个。 如果最低4位被散列程序充分扰乱,那么这16个选项可以映射到12个最佳3D矢量(长度为sqrt2)快速 - 这就是它正在做的事情(并且,imho,为什么Perlin噪音很少达到他在随附文件中提出的标准。
特别地,他将两个轴单位向量(x,y和z) - 随机选择 - 随机选择,每个都用伪随机确定的符号。
由于你想要2D噪声,我可以建议使用一个查找表来表示渐变本身,但是请将它们设置为相同的长度(它看起来比附录中留下的Perlin左边的快捷方式稍好一些,它被复制了EveryWhere,以及矢量通常是漂浮物)。实际上,您可以选择8个良好的基础渐变(因此按位加扰可以正常工作!)。