3D Perlin杂分析导 [英] 3D Perlin noise analytical derivative
问题描述
我目前正在实施一个3D培林利用Shader Model 4(的DirectX 10 HLSL)噪音凹凸贴图。产生噪声本身不是一个很大的问题(还有吨教程和codeS左右),但我还没有发现有3D Perlin杂分析衍生物。
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.
的唯一网站走的是衍生品在内的伊尼戈Quilez的网站和相关的<一个HREF =http://www.gamedev.net/community/forums/topic.asp?topic_id=479101> GameDev.net讨论。的问题是,在所述第一连杆的噪声是基于值,而不是基于梯度(这是我的要求),在第二连杆,还有只有2D梯度噪声衍生物
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.
请注意,我不是在寻找数值衍生工具的要求要产生4相邻的噪声样本,这就是太多的开销。
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?
推荐答案
我也无法找到今天在网络上的解决方案,所以我试图得到它。
I also could not found a solution on the web today, so I tried to derive it.
三维Perlin杂的首先的符号定义。
Firstly the notations of a 3D Perlin noise is defined.
假设3D Perlin的噪声由三线性插值计算为
Assume the 3D Perlin noise is computed by the trilinear interpolation as
n = Lerp(
Lerp(
Lerp(dot000, dot100, u),
Lerp(dot010, dot110, u),
v),
Lerp(
Lerp(dot001, dot101, u),
Lerp(dot011, dot111, u),
v),
w)
其中, U
, v
,是W
是插因素进行分数坐标的五次多项式(即提高Perlin杂):
where u
, v
, w
are the interpolation factors by the quintic polynomial of fraction coordinates (i.e., improved Perlin noise):
x0 = frac(x)
y0 = frac(y)
z0 = frac(z)
x1 = x0 - 1
y1 = y0 - 1
z1 = z0 - 1
u = x0 * x0 * x0 * (x0 * (6 * x0 - 15) + 10)
v = y0 * y0 * y0 * (y0 * (6 * y0 - 15) + 10)
w = z0 * z0 * z0 * (z0 * (6 * z0 - 15) + 10)
和点___
是梯度矢量(GX ___,gy___,GZ ___)
s的格点的点积和分数坐标:
and dot___
s are dot products of the gradient vectors (gx___, gy___, gz___)
s at lattice points and the fraction coordinates:
dot000 = gx000 * x0 + gy000 * y0 + gz000 * z0
dot100 = gx100 * x1 + gy100 * y0 + gz100 * z0
dot010 = gx010 * x0 + gy010 * y1 + gz010 * z0
dot110 = gx110 * x1 + gy110 * y1 + gz110 * z0
dot001 = gx001 * x0 + gy001 * y0 + gz001 * z1
dot101 = gx101 * x1 + gy101 * y0 + gz101 * z1
dot011 = gx011 * x0 + gy011 * y1 + gz011 * z1
dot111 = gx111 * x1 + gy111 * y1 + gz111 * z1
计算的衍生品
首先, U
, v
和是W $ C $计算衍生物C>
u' = 30 * x0 * x0 * (x0 - 1) * (x0 - 1)
v' = 30 * y0 * y0 * (y0 - 1) * (y0 - 1)
w' = 30 * z0 * z0 * (z0 - 1) * (z0 - 1)
通过扩大 N
与线性插值(A,B,T)= A +(B - A)* T
,
n = dot000
+ u(dot100 - dot000)
+ v(dot010 - dot000)
+ w(dot001 - dot000)
+ uv(dot110 - dot010 - dot100 + dot000)
+ uw(dot101 - dot001 - dot100 + dot000)
+ vw(dot011 - dot001 - dot010 + dot000)
+ uvw(dot111 - dot011 - dot101 + dot001 - dot110 + dot010 + dot100 - dot000)
再取偏导数 N
,
nx = gx000
+ u' (dot100 - dot000)
+ u (gx100 - gx000)
+ v (gx010 - gx000)
+ w (gx001 - gx000)
+ u'v (dot110 - dot010 - dot100 + dot000)
+ uv (gx110 - gx010 - gx100 + gx000)
+ u'w (dot101 - dot001 - dot100 + dot000)
+ uw (gx101 - gx001 - gx100 - gx000)
+ vw (gx011 - gx001 - gx010 + gx000)
+ u'vw(dot111 - dot011 - dot101 + dot001 - dot110 + dot010 + dot100 - dot000)
+ uvw (gx111 - gx011 - gx101 + gx001 - gx110 + gx010 + gx100 - gx000)
ny = gy000
+ u (gy100 - gy000)
+ v' (dot010 - dot000)
+ v (gy010 - gy000)
+ w (gy001 - gy000)
+ uv' (dot110 - dot010 - dot100 + dot000)
+ uv (gy110 - gy010 - gy100 + gy000)
+ uw (gy101 - gy001 - gy100 + gy000)
+ v'w (dot011 - dot001 - dot010 + dot000)
+ vw (gy011 - gy001 - gy010 + gy000)
+ uv'w(dot111 - dot011 - dot101 + dot001 - dot110 + dot010 + dot100 - dot000)
+ uvw (gy111 - gy011 - gy101 + gy001 - gy110 + gy010 + gy100 - gy000)
nz = gz000
+ u (gz100 - gz000)
+ v (gz010 - gz000)
+ w' (dot001 - dot000)
+ w (gz001 - gz000)
+ uv (gz110 - gz010 - gz100 + gz000)
+ uw' (dot101 - dot001 - dot100 + dot000)
+ uw (gz101 - gz001 - gz100 + gz000)
+ vw' (dot011 - dot001 - dot010 + dot000)
+ vw (gz011 - gz001 - gz010 + gz000)
+ uvw'(dot111 - dot011 - dot101 + dot001 - dot110 + dot010 + dot100 - dot000)
+ uvw (gz111 - gz011 - gz101 + gz001 - gz110 + gz010 + gz100 - gz000)
然后(NX,NY,NZ)
是噪声功能梯度向量(偏导数)。
Then (nx, ny, nz)
is the gradient vector (partial derivatives) of the noise function.
一些常见子前pression可以分解出来,如果编译器不能处理它。例如:
Some common sub-expression can be factored out, if the compiler cannot handle it. For example:
uv = u * v
vw = v * w
uw = u * w
uvw = uv * w
在扩展 N
被多次重复使用的系数。它们可以通过计算:
The coefficients in the expanded n
are reused multiple times. They can be computed by:
k0 = dot100 - dot000
k1 = dot010 - dot000
k2 = dot001 - dot000
k3 = dot110 - dot010 - k0
k4 = dot101 - dot001 - k0
k5 = dot011 - dot001 - k1
k6 = (dot111 - dot011) - (dot101 - dot001) - k3
另外,衍生品也有类似的系数,</ P>
Also the derivatives has similar coefficients,
gxk0 = gx100 - gx000
gxk1 = gx010 - gx000
...
的计算 N
可以使用的扩展形式 K0
... K6
和
The computation of n
can uses the expanded form with k0
, ... k6
as well.
该解决方案已被证实对中心差分法。
This solution has been verified against central difference method.
虽然这种解决方案看起来笨拙,我的实验(仅CPU,SSE)表明,该解决方案计算这些衍生品只招约 50%的额外时间可以计算单个3D Perlin杂样。
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.
有限差分将至少需要300%额外的时间(做额外的3个样本)或600%(做6个样品的中央差)。
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.
这篇关于3D Perlin杂分析导的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!