Je n'ai pas non plus trouvé de solution sur le web aujourd'hui, j'ai donc essayé de la dériver.
Premièrement, les notations d'un bruit Perlin 3D sont définies.
Notation
Supposons que le bruit Perlin 3D est calculée par l'interpolation trilinéaire comme
n = Lerp(
Lerp(
Lerp(dot000, dot100, u),
Lerp(dot010, dot110, u),
v),
Lerp(
Lerp(dot001, dot101, u),
Lerp(dot011, dot111, u),
v),
w)
où u
, v
, w
sont les facteurs d'interpolation par le polynôme quintique de coordonnées de la fraction (par exemple, l'amélioration de Perlin bruit):
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)
et dot___
s d ot produits des vecteurs gradients (gx___, gy___, gz___)
de s aux points en treillis et la fraction coordonnées:
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
Calcul des dérivés
En premier lieu, les dérivés de calcul de u
, v
et w
u' = 30 * x0 * x0 * (x0 - 1) * (x0 - 1)
v' = 30 * y0 * y0 * (y0 - 1) * (y0 - 1)
w' = 30 * z0 * z0 * (z0 - 1) * (z0 - 1)
En étendant n
avec Lerp(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)
ensuite prendre les dérivées partielles de 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)
Puis (nx, ny, nz)
est le vecteur de gradient (dérivés partielle) de la fonction de bruit.
Optimisation
Certains sous-expression commune peut être refactorisée, si le compilateur ne peut pas le manipuler.Par exemple:
uv = u * v
vw = v * w
uw = u * w
uvw = uv * w
Les coefficients du n
élargi sont réutilisés plusieurs fois. Ils peuvent être calculés par:
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
également les dérivés a des coefficients similaires,
gxk0 = gx100 - gx000
gxk1 = gx010 - gx000
...
Le calcul de n
peut utilise la forme développée avec k0
... k6
aussi bien.
Derniers mots
Cette solution a été vérifiée par rapport à la méthode centrale de différence. Bien que cette solution semble maladroite, mon expérience (CPU seulement, SSE) a montré que, le calcul de ces dérivés par cette solution n'engendre que 50% de temps supplémentaire pour calculer un seul échantillon de bruit Perlin 3D.
La différence finie nécessite au moins 300% de temps supplémentaire (3 échantillons supplémentaires) ou 600% (6 échantillons pour la différence centrale). Par conséquent, cette solution est meilleure en performance, et devrait également être plus stable numériquement.
http://www.scratchapixel.com/lessons/procedural-generation-vritual-worlds%20/perlin-noise-part-2/perlin-noise-computing-derivatives – user18490