3D Perlin 噪声解析导数
我目前正在使用 Shader Model 4 (DirectX 10 HLSL) 实现 3D Perlin 噪声凹凸贴图。生成噪声本身并不是一个大问题(周围有大量的教程和代码),但我还没有找到 3D Perlin 噪声的分析导数。
唯一考虑衍生品的网站是 Ińigo Quilez 网站 和相关的GameDev.net 讨论。问题是,在第一个链接中,噪声是基于值的,而不是基于梯度的(这是我的要求),在第二个链接中,只有二维梯度噪声导数。
请注意,我并不是在寻找数值导数,因为它们需要生成 4 个相邻噪声样本,而且开销太大。
有人计算过这些导数吗?是否有使用它们的参考实现?
I am currently implementing a 3D Perlin noise bump mapping using Shader Model 4 (DirectX 10 HLSL). Generating the noise itself is not a big problem (there are tons of tutorials and codes around) but what I have not found are analytical derivatives of 3D Perlin noise.
The only sites taking the derivatives into account are Ińigo Quilez's site and a related GameDev.net discussion. The problem is that in the first link the noise is value based, not gradient based (which is a requirement for me), in the second link, there's only 2D gradient noise derivative.
Note that I'm not looking for numerical derivatives as those require 4 neighboring noise samples to be generated and that's way too much overhead.
Has anyone calculated these derivatives? Is there a reference implementation that is using them?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我今天在网上也找不到解决方案,所以我尝试推导它。
首先定义 3D Perlin 噪声的符号。
符号
假设 3D Perlin 噪声是通过三线性插值计算的,其中
u
、v
、w
是分数五次多项式的插值因子坐标(即改进的 Perlin 噪声):和
dot___
s 是格点处梯度向量(gx___, gy___, gz___)
s 与分数坐标的点积:计算导数
首先,计算
u
、v
和w
的导数通过用
Lerp(a , b, t) = a + (b - a) * t
,然后对
n
求偏导数,,
,
然后
(nx, ny, nz)
> 是噪声函数的梯度向量(偏导数)。优化
如果编译器无法处理某些常见的子表达式,则可以将其分解。例如:
扩展
n
中的系数被重复使用多次。它们可以通过以下方式计算:导数也具有相似的系数,
n
的计算可以使用k0
的扩展形式,...k6
以及。结束语
该解决方案已经通过中心差分法进行了验证。
尽管这个解决方案看起来很笨拙,但我的实验(仅 CPU,SSE)表明,通过该解决方案计算这些导数仅需要计算单个 3D Perlin 噪声样本50% 的额外时间。
有限差分至少需要 300% 的额外时间(额外做 3 个样本)或 600%(做 6 个样本以获得中心差)。
因此,该解在性能上更好,并且在数值上也应该更稳定。
I also could not found a solution on the web today, so I tried to derive it.
Firstly the notations of a 3D Perlin noise is defined.
Notation
Assume the 3D Perlin noise is computed by the trilinear interpolation as
where
u
,v
,w
are the interpolation factors by the quintic polynomial of fraction coordinates (i.e., improved Perlin noise):and
dot___
s are dot products of the gradient vectors(gx___, gy___, gz___)
s at lattice points and the fraction coordinates:Computing the derivatives
First, compute derivatives of
u
,v
andw
By expanding
n
withLerp(a, b, t) = a + (b - a) * t
,Then take partial derivatives of
n
,,
,
Then
(nx, ny, nz)
is the gradient vector (partial derivatives) of the noise function.Optimization
Some common sub-expression can be factored out, if the compiler cannot handle it. For example:
The coefficients in the expanded
n
are reused multiple times. They can be computed by:Also the derivatives has similar coefficients,
The computation of
n
can uses the expanded form withk0
, ...k6
as well.Final words
This solution has been verified against central difference method.
Although this solution looks clumsy, my experiment (CPU only, SSE) showed that, computing these derivatives by this solution only incurs about 50% extra time to computing a single 3D Perlin noise sample.
Finite difference will at least need 300% extra time (doing extra 3 samples) or 600% (doing 6 samples for central difference).
Therefore, this solution is better in performance, and should also be more numerically stable.