我目前正在尝试在二维HLSL上实现柏林噪声。我看了肯改进的柏林噪声,但我不明白如何从排列数组转换为矢量工作。我知道我可以得到像这样的哈希码
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是底层x,y坐标分解为8位)
从这里,但我仍然不明白它。我也不明白为什么"毕业生……"——方法来自Ken的实现作品。有人能解释一下这是怎么回事吗?
Ken Perlin的实际java实现实际上是他的GPU实现的伪代码,这意味着某些部分(特别是您所坚持的部分)是完全不可理解的(使用一些优化理论)。
可读性,试试Stefan Gustavson在《Simplex Noise Demystified》(2005)中的参考java实现(pdf),它更清晰,因为它部分是作为教学工具设计的。
他的grad()函数中的一长组位操作和条件(使用三元简写运算符)用于选择伪随机的单位向量。特别是,它应该从单位圆(在2D中)或球体(在3D中,由立方体各边的中点近似)等周围均匀分布的集合中进行选择,并且每个选择的概率相等。如果最低的4位被哈希例程充分打乱,那么这16个选择可以被映射到12个最佳3D向量(长度为sqrt2) 快速 -这就是它所做的(并且,我想,为什么柏林噪声很少实现达到他在随文中提出的标准)。
特别地,他将两个轴单位向量(x, y和z)相加——伪随机选择,每个符号都是伪随机确定的。
既然你想要2D噪声,我可以建议使用一个查找表的梯度本身,但请使它们都是相同的长度(它看起来比在附录中被复制的快捷Perlin留下的要好一点,并且向量通常已经是浮点数了)。实际上,您可以选择8个良好的基梯度(因此按位打乱工作没有变形!)。