You are on page 1of 37

Introduction au bruit de Perlin

Jrmy Cochoy
10 fvrier 2011
Rsum
Ken Perlin, dans le cadre de la ralisation du lm Tron (1982) comportant des scnes
en image de synthse, se retrouva confront la limitation de la mmoire des machines de
lpoque, ne permettant pas de stocker dimportantes et nombreuses textures.
Il chercha alors gnrer ces textures par le calcul, que lon nome textures paramtriques.
Ceci lamena concevoir son algorithme homonyme qui sera le l directeur de ce document.
Nous dcouvrirons en trois tapes son fonctionnement tout en construisant une impl-
mentation.
Ce document sadresse aux tudiants ayant assimil le programme de terminale et exp-
riment un premier contact avec la programmation. Quelques informations supplmentaires
gurent toutefois pour les plus expriments ainsi que deux chapitres additionnels la n
de ce document, o sont vaguement utilises quelques notions de premire anne de licence.
Elles ne sont toute fois pas ncessaires la comprhension gnrale de ce document et des
algorithmes prsents.
1
TABLE DES MATIRES 2
Table des matires
1 Introduction 3
2 Gnration dun bruit 4
2.1 Fonctions pseudo-alatoires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Les fonctions de bruit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3 Interpolations de valeurs 7
3.1 Linterpolation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.2 Linterpolation linaire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.3 Linterpolation cosinusodale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.4 Linterpolation cubique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.5 Interpolation du bruit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.6 Vers une autre dimension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.7 Splines cubiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4 Le bruit de Perlin 18
4.1 Comprhension et implmentation . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2 Pixelisation aux coordonnes ngatives . . . . . . . . . . . . . . . . . . . . . . . . 20
4.3 Motif fractal vident au centre dhomothtie . . . . . . . . . . . . . . . . . . . . . 21
5 Lalgorithme original 23
5.1 Champs vectoriels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.2 Tables de hachage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.3 Une implmentation du cas tridimensionnel . . . . . . . . . . . . . . . . . . . . . 26
6 Simplex Noise 30
6.1 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
6.2 Changement de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
6.3 Implmentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
7 Conclusion 36
7.1 Remerciements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Rfrences 36
Index 37
1 INTRODUCTION 3
1 Introduction
Lalgorithme de Perlin est lorigine de nombreuses textures paramtriques, comme le marbre,
le bois, leet de nuages, de brume, et de nombreux autres. Mais il est aussi utilis pour la
gnration de reliefs et de terrains, la gnration dirrgularits dans la surface de solides (bump
mapping) et de nombreuses autres applications.
Nous nous contenterons de discuter de son application la gnration de textures param-
triques, comme le prsente la gure 1 base sur un bruit bidimensionnel.
Fig. 1 Bruit de Perlin 2D
Dans ces premires parties, nous tudierons une version simplie de cet algorithme. Il se
dcompose en trois grandes parties :
Une fonction de bruit qui permet dassocier des valeurs alatoires chaque point de lespace
N
dim
Une fonction de bruit liss par interpolation
Une combinaison linaire de fonctions de bruit liss
2 GNRATION DUN BRUIT 4
2 Gnration dun bruit
2.1 Fonctions pseudo-alatoires
La premire tape de lalgorithme consiste former une fonction de bruit, cest--dire une
fonction f : N R qui, une valeur donne, associe une valeur qui semble alatoire. Il est
important de remarquer que ce bruit pourra donc tre reproduit, pour une mme valeur. Cest
trs important, car si lon souhaite par exemple lutiliser pour gnrer une image, celle ci ne doit
pas systmatiquement changer, chaque gnration moins que ce paramtre ne soit voulu et
contrl, ce dont nous reparlerons dans la partie suivante.
Vous avez un aperu de bruit unidimensionnel et bidimensionnel avec la gure 2.
Fig. 2 Bruit 1D et 2D
Il est dicilement possible de produire de relles valeurs alatoires, et dicile pour un obser-
vateur de discerner un motif, une fois une certaine complexit ateinte. On se contentera donc de
fonctions dterministes, priodiques, mais au rendu dsordonn.
Il nous faudra donc obtenir un jeu de valeurs alatoires, dont le cycle cest--dire lintervale
ncessaire pour obtenir nouveau le mme jeu de valeurs est assez important pour quun
observateur ne puisse sen rendre compte.
Vous pouvez utiliser une fonction de gnration alatoire fournie par le language que vous
utilisez, comme la fonction rand du language C, et gnrer un tableau de valeurs, ou encore
utiliser votre propre fonction pseudo-alatoire.
Voici donc une fonction pseudo-alatoire particulire, tire dun article (ref [4]), et dont je
serait bien incapable de vous dcrire le fonctionnement. Sachez que vous pouvez la modier en
remplaant les nombres premiers de cette formule par dautres, relativement proches.
Je ne vous guarantis pas que cela soit sans eet sur la rpartition des probabilits, ni mme
la longueur des cycles. Lexprience montre simplement queectivement, substituer dautres
2 GNRATION DUN BRUIT 5
nombres premiers du mme ordre de grandeur ore un rsultat tout aussi satisfaisant. Pour plus
dinformations ce sujet, je vous renvoie aux thories mathmatiques correspondantes.
Listing 1 Fonction pseudo-alatoire
1 // Fourni t une v al e ur a l a t o i r e ent r e 1 et 1
double rand_noi se ( i nt t )
{
t = ( t <<13) ^ t ;
t = ( t ( t t 15731 + 789221) + 1376312589) ;
6 return 1. 0 ( t & 0 x 7 f f f f f f f ) / 1073741824. 0;
}
//On pourra ob t e ni r une val eur ent r e 0 et 1 en u t i l i s a n t
// l a f ormul e : ( rand_noise ( t ) + 1. ) / 2.
2.2 Les fonctions de bruit
Suivant votre choix quant lobtention de votre jeu de valeurs alatoires, limplmentation
de la fonction de bruit dire.
Dans le cadre o vous travaillez sur une seul dimension cest le cas des courbes votre
fonction bruit se limitera un simple accs la valeur correspondant votre coordonne que
lon notera x ou encore lappel de la fonction rand_noise.
Dans les autres cas, o vous travaillez sur un espace de dimension deux ou suprieure, et
que vous avez fait le choix dutiliser un jeu de valeurs prcalcules, il vous faudra gnrer un
tableau bidimensionnel, ou bien encore un simple vecteur que vous utiliserez comme un tableau
bidimensionnel.
Listing 2 Bruit tridimensionnel partir dun jeu de valeurs
1 double rand_set [W H K] ;
// I n i t i a l i s a t i o n du t abl eau , e t c . . .
double noi se_3d ( i nt x , i nt y , i nt z )
6 {
return rand_set [ x + yw + zwh ] ;
}
Dans le cas contraire, il vous faudra raliser une fonction de bruit plusieurs variables. Si
vous tentez direntes expressions polynmiales, vous nobtiendrez rien de bien concluant et des
motifs ou dformations se proleront, entranant la perte du caractre pseudo-alatoire que vous
recherchez. Une bonne solution est la composition de la fonction de bruit. Il est ncessaire de
multiplier le rsultat de notre fonction de bruit par un scalaire quelconque, mais de valeur
susamment grande de faon rendre une faible variation de la fonction de bruit signicative
avant chaque composition, puisque nous avons 1 <= rand_noise <= 1. Observez lexemple
suivant :
Listing 3 Bruit bidimensionnel
double noi se_2d ( i nt x , i nt y)
2 GNRATION DUN BRUIT 6
2 {
i nt tmp = rand_noi se ( x) 850000;
return rand_noi se (tmp + y ) ;
}
Do nous dduisons facilement la formule de calcul dun bruit quadridimensionnel :
Listing 4 Bruit quadridimensionnel
double noi se_4d ( i nt x , i nt y , i nt z , i nt t )
{
i nt tmp_x = rand_noi se ( x) 850000;
i nt tmp_y = rand_noi se (tmp_x + y) 850000;
5 i nt tmp_z = rand_noi se (tmp_y + z ) 850000;
return rand_noi se (tmp_z + t ) ;
}
Et, pour conclure, une formule utilisable pour toute dimension :
Listing 5 Bruit n dimensions
double noise_nd ( i nt data_set , i nt dim)
{
3 i nt i ;
double r = 0 . ;
for ( i = 0; i < dim; i ++)
r = rand_noi se ( data_set [ i ] + ( i nt ) ( r 850000) ) ;
8 return r ;
}
3 INTERPOLATIONS DE VALEURS 7
3 Interpolations de valeurs
3.1 Linterpolation
Linterpolation est une opration mathmatique permettant de construire une courbe partir
des donnes dun nombre ni de points. En dautres mots, cest un processus qui consiste dnir
une fonction continue prenant certaines valeurs en certains points, et ce selon certains critres
que lon choisit de simposer.
La deuxime phase de lalgorithme de Perlin consiste en linterpolation de valeurs interm-
diaires dnies rgulirement en certains points de lespace par une fonction de bruit. Concrte-
ment, imaginons que lon reprenne notre bruit unidimensionnel de la gure 2 o lon a associ
chaque entier une valeur pseudo-alatoire comprise entre -1 et 1, et que lon souhaite tracer une
courbe continue passant par ces points. On souhaite donc dnir une fonction g : R R dont la
restriction N est f.
Il existe une innit de fonctions qui respectent ces conditions. Toutefois, nous ntudierons
que trois cas particuliers. Nous ne dtaillerons pas les aspects mathmatiques et nous nous
contenteront dapprhender, avec les mains, le fonctionnement de celles ci.
3.2 Linterpolation linaire
Il sagit de la solution la plus simple que lon puisse trouver ce problme. Puisque nous
avont un ensemble de points, pourquoi ne pas se contenter de les relier en traant des segments
qui joignent chaque point ses deux voisins? On constate alors immdiatement que la fonction
est continue et bien dnie.
On peut obtenir tous les points du segment AB de faon paramtrique cest--dire selon une
variable t que lon contrle en prenant t [0, 1] auquel on associe le point M de coordonnes
(x
A
(1 t) + t x
B
, y
A
(1 t) + t y
B
). Intuitivement, pour t = 0 on se trouve en A, et
lon glisse jusquen B de faon linaire une autre faon de voir ceci est de constater que lon se
dplace proportionnellement la progression de t dans lintervale [0, 1].
Dans notre cas, nous souhaitons obtenir lordonne en fonction de labscisse. Or, si lon dnit
les points dont la valeur issue de notre bruit est impose parmi les entiers, alors la partie
dcimale de chaque coordonne correspond notre paramtre.
On prendra donc la partie fractionnaire de x comme valeur de t.
Ce qui nous amne nalement la fonction dinterpolation suivante :
Listing 6 Interpolation linaire
1 double l i ne a r _i nt e r po l a t e ( double a , double b , double t )
{
return ( 1 . t ) a + t b ;
}
3 INTERPOLATIONS DE VALEURS 8
3.3 Linterpolation cosinusodale
Lun des problmes de linterpolation linaire est son aspect irrgulier, ce qui se traduit
mathmatiquement par labscence dune drive premire. La condition que lon va alors imposer
est que la fonction obtenue soit continue et drivable, drive continue. On dira quelle est de
classe C
1
, alors que linterpolation linaire est de classe C
0
.
Puisque le problme de linterpolation linaire se situe aux jonctions des segments, nous allons
leur substituer une courbe dont la drive sannule chaque extrmit, nous assurant ainsi la
drivabilit.
Une fonction qui se prte bien ceci est bien sr la fonction cosinus, dont la drive en
0 et en

2
sannule. En appliquant une lgre transformation, nous pouvons dnir la fonction
c : [0, 1] [0, 1]x
1cos(x)
2
1
.
Vous trouvez les courbes de ces deux fonctions la gure 3.
Fig. 3 La fonction cosinus et notre fonction particulire
Se pose alors la question de dformer cette fonction pour que chacune de ses extrmites
correspondent aux deux points que lon souhaite joindre. En fait, plutt que de chercher d-
former notre fonction, cherchons plutot comment transformer notre interpolation linaire. On
observe que si lon substitue t par c(t) on obtient bien une fonction dont la drive est nulle en
0 et 1, ce que nous recherchons.
Concrtement, cela se traduit par une contraction des distances au voisinage des extrmits,
et linverse par une longation de celles-ci vers le centre de notre arc de courbe.
Une autre faon, plus cinmatique, de se reprsenter la chose est de percevoir que le dpla-
cement selon t est faible aux extrmits des segments et extrmement rapide au voisinage de
1
2
.
Ce que conrme le graphe de la drive de c (cf gure 4).
Ce qui nous donne, nalement lextrait 7
1
Il existe des fonctions polynmiales qui ont une courbe et des proprits de drivabilit similaires, par exemple
la fonction polynmiale dHermite. Nous en parlons dans la partie avance de ce document.
3 INTERPOLATIONS DE VALEURS 9
Listing 7 Interpolation cosinusodale
1 double c os i ne _i nt e r pol at e ( double a , double b , double t )
{
double c = (1 cos ( t 3. 1415927) ) . 5 ;
return ( 1 . c ) a + c b ;
6 }
Le rendu est particulirement plus doux, comme le montre la gure 5. Persistent toutefois
quelques aberrations des exemples se trouvent aux centres des cercles qui ne correspondent
pas vraiment lide que lon se ferait de cette fonction, ce qui justiera lintroduction dune
troisime mthode, plus lourde et plus complexe, mais au rsultat visuellement plus agrable.
Fig. 4 La drive de notre fonction c
Fig. 5 Interpolation cosinusodale
3 INTERPOLATIONS DE VALEURS 10
3.4 Linterpolation cubique
Linterpolation cubique apporte une solution aux problmes que nous avons dcels alors
que nous nous intressions linterpolation cosinusodale. Nous allons utiliser des polynmes du
troisime degr pour obtenir une approximation de la fonction en deux points.
En eectuant un recollement par morceaux, tout comme nous lavons fait avec linterpolation
cosinusodale, nous obtiendrons une fonction de classe C
2
, cest--dire deux fois drivable
drive continue. Cela traduit un critre de rgularit plus important.
Non seulement la courbe doit tre lisse, mais les tangentes cette courbe doivent varier de
faon continue. Cest cependant une mthode coteuse puisquelle ne ncessitera non pas deux
mais quatre points.
Si nous voulons ajouter la continuit de la drive seconde en chacun des points, il devient
ncessaire de faire intervenir les points situs avant et aprs la portion de courbe que nous
souhaitons interpoler.
Nous nous retrouvons alors avec quatre quations vous pouvez obtenir plus de dtails en
consultant la bibliographie. Pour respecter ces quatre contraintes, il faut disposer de quatre
variables que nous pouvons contrler, ce qui nous amne choisir un polynme de degr trois.
Bien que lide soit de calculer la drive seconde en fonction des points prcdents, il existe
diverses faons de rgler nos coecients.
Nous allons utiliser un cas particulier (extrait 8). Il nous permettra dobtenir une fonction
polynmiale qui, dnie sur lintervale [1, 1] a pour avantage de ne prendre que rarement ses
valeurs hors de celui-ci.
Listing 8 Inteprolation cubique
// I nt e r p o l a t i o n des v al e ur s s i t u e s ent r e p0 et p1
// Nces s i t e deux poi nt s qui prcdent ( resp . succdent )
// p1 ( rep . p2 ) .
4 double c ubi c _i nt e r pol at e ( double before_p0 , double p0 ,
double p1 , double af ter_p1 )
{
// Cal cul des c o e f f i c i e n t s de not re polynme
double a3 = 0.5 bef ore_p0 + 1. 5 p0 1. 5 p1 + 0. 5 af ter_p1 ;
9 double a2 = bef ore_p0 2. 5 p0 + 2p1 0. 5 af ter_p1 ;
double a1 = 0.5 bef ore_p0 + 0. 5 p1 ;
double a0 = p0 ;
// Cal cul de l a val eur de ce polynme en t
14 return ( c3 t t t ) + ( c2 t t ) + ( c1 t ) + c0 ;
}
La dirence est tout de suite perceptible, comme le montre la gure 6.
3.5 Interpolation du bruit
Nous disposons maintenant de fonctions qui nous permettent dinterpoler entre deux valeurs
de notre bruit. Nous pouvons donc crire une fonction de bruit liss. Elle prend donc en para-
3 INTERPOLATIONS DE VALEURS 11
mtre la coordonne x, dont elle spare la partie entire et la partie fractionnaire, pour ensuite
interpoler entre le point de coordonne (x) et celui de coordonne (x + 1).
Dans un premier temps, le cas linaire :
Listing 9 Bruit liss
double smooth_noi se ( double x)
{
// Par t i e e nt i r e : E( x )
i nt i nteger_x = ( i nt ) x ;
5 // Par t i e f r a c t i o nna i r e : x E( x )
double f r ac t i onal _x = x i nteger_x ;
// Brui t du poi nt prcdent :
10 double a = noi s e ( i nteger_x ) ;
// Brui t du poi nt s ui vant :
double b = noi s e ( i nteger_x + 1 ) ;
// I nt e r p o l a t i o n :
15 return l i ne a r _i nt e r po l a t e ( a , b , f r ac t i onal _x ) ;
}
Pour une interpolation cosinusodale nous avons la mme chose, la fonction dinterpolation
prs. Le cas de linterpolation cubique est lgrement plus complexe puisquil ncessite quatre
points.
Fig. 6 Interpolation cosinusodale <-> Interpolation cubique
3 INTERPOLATIONS DE VALEURS 12
Listing 10 Bruit liss
double smooth_noi se ( double x)
{
// Par t i e e nt i r e : E( x )
4 i nt i nteger_x = ( i nt ) x ;
// Par t i e f r a c t i o nna i r e : x E( x )
double f r ac t i onal _x = x i nteger_x ;
9 // Brui t des quat r e poi nt s
double c = noi s e ( i nteger_x 1 ) ;
double a = noi s e ( i nteger_x ) ;
double b = noi s e ( i nteger_x + 1 ) ;
double d = noi s e ( i nteger_x + 2 ) ;
14
// I nt e r p o l a t i o n :
return c ubi c _i nt e r pol at e ( c , a , b , d , f r ac t i onal _x ) ;
}
3 INTERPOLATIONS DE VALEURS 13
3.6 Vers une autre dimension
Nous avons dcouvert trois mthodes, dans un ordre de cot, en temps de calcul, croissant.
Malheureusement, toutes ces mthodes se sont limites une interpolation monodimensionnelle.
Quen est-il du cas, plus probable, o nous nous retrouvons avec deux, trois, ou mme quatre
dimensions ce qui est plus courant que lon pourrait le penser ; si lon souhaite appliquer une
texture de bruit de Perlin un objet tridimensionnel, et ceci tout en animant la texture, on
aurait alors besoin dune quatrime dimension qui serait ici le temps.
Il existe une mthode qui permet de gnraliser chacune de celles-ci une dimension n, et
cest celle que nous allons dcrire.
Supposons, dans un premier temps, que nous souhaitons interpoler un bruit bidimensionnel.
Nous raisonnons donc dans le plan. Si lon conserve notre habitude de placer nos points aux
coordonnes entires, nous souhaitons donc interpoler la valeur dun point M qui se trouve
environn de quatre autres points, et sa valeur sera donc dpendante de chacun de ces points. Si
lon note (X, Y ) les coordonnes de M, et que E(z) reprsente la partie entire de z, les 4 points
ont pour coordonnes : A = (E(X), E(Y )), B = (E(X) + 1, E(Y )), C = (E(X), E(Y ) + 1),
D = (E(X) + 1, E(Y ) + 1)
Fig. 7 Un point dans notre plan
Cherchons subdiviser le problme pour le rendre plus simple. Nos quatre points forment
deux deux, le long de laxe Ox, des segments. Nous pouvons donc chercher interpoler le
long du segment [AB] en prenant la partie fractionnaire de X comme troisime paramtre de
notre fonction dinterpolation. Nous pouvons faire de mme pour le segment [CD]. Nous nous
retrouvons alors avec les deux valeurs des points F et G de la gure 8.
Fig. 8 Etape intermdiaire de linterpolation linaire dans le plan
3 INTERPOLATIONS DE VALEURS 14
Nous pouvons, une troisime fois, interpoler le long du segment [FG] an dobtenir la valeur
en M. Pour cela, nous prendrons les deux valeurs calcules prcdemment ainsi que la partie
fractionnaire de la coordonne Y de M.
Si lon rsume le code correspondant, nous obtenons :
Listing 11 Interpolation linaire 2D
// . . .
3 double f = l i ne a r _i nt e r po l a t e ( a , b , f r ac t i onal _x ) ;
double g = l i ne a r _i nt e r po l a t e ( c , d , f r ac t i onal _x ) ;
double r e s ul t = l i ne a r _i nt e r po l a t e ( f , g , f r ac t i onal _y ) ;
Nous pouvons gnraliser ceci trois ou quatres dimensions. Pour n dimensions, il sut
dinterpoler les n-1 dimensions deux fois, avant dinterpoler les deux valeurs rsultantes.
Un exemple en dimension trois:
Listing 12 Inteprolation linaire 3D
double smooth_noi se ( double x , double y , double z )
{
// Par t i e e nt i r e : E( x )
4 i nt i nteger_x = ( i nt ) x ;
i nt i nteger_y = ( i nt ) y ;
i nt i nt eger _z = ( i nt ) z ;
// Par t i e f r a c t i o nna i r e : x E( x )
double f r ac t i onal _x = x i nteger_x ;
9 double f r ac t i onal _y = y i nteger_y ;
double f r ac t i onal _z = z i nt eger _z ;
// Brui t des quat r e poi nt s d un cube
double a0 = noi s e ( i nteger_x , i nteger_y , i nt eger _z ) ;
14 double a1 = noi s e ( i nteger_x + 1 , i nteger_y , i nt eger _z ) ;
double b0 = noi s e ( i nteger_x , i nteger_y + 1 , i nt eger _z ) ;
double b1 = noi s e ( i nteger_x + 1 , i nteger_y + 1 , i nt eger _z ) ;
19 double c0 = noi s e ( i nteger_x , i nteger_y , i nt eger _z + 1 ) ;
double c1 = noi s e ( i nteger_x + 1 , i nteger_y , i nt eger _z + 1 ) ;
double d0 = noi s e ( i nteger_x , i nteger_y + 1 , i nt eger _z + 1 ) ;
double d1 = noi s e ( i nteger_x + 1 , i nteger_y + 1 , i nt eger _z + 1 ) ;
24
// I nt e r p o l a t i o n sur l a f ace i nf r i e ur e du cube :
double a = l i ne a r _i nt e r po l a t e ( a0 , a1 , f r ac t i onal _x ) ;
double b = l i ne a r _i nt e r po l a t e ( b0 , b1 , f r ac t i onal _x ) ;
double v = l i ne a r _i nt e r po l a t e ( a , b , f r ac t i onal _y ) ;
29 // I nt e r p o l a t i o n sur l a f ace s upr i eur e du cube :
double c = l i ne a r _i nt e r po l a t e ( c0 , c1 , f r ac t i onal _x ) ;
3 INTERPOLATIONS DE VALEURS 15
double d = l i ne a r _i nt e r po l a t e ( d0 , d1 , f r ac t i onal _x ) ;
double w = l i ne a r _i nt e r po l a t e ( c , d , f r ac t i onal _y ) ;
34 // I nt e r p o l a t i o n ent r e l e s poi nt s
// s i t u s sur chacune des deux f ac e s :
return l i ne a r _i nt e r po l a t e ( v , w, f r ac t i onal _z ) ;
}
Il est vident que pour des dimensions plus leves, nous nallons pas expliciter le calcul
pour chacun de nos points. Nous prfrerons une mthode rcursive. Lextrait 13 est un exemple
valable pour toute dimension. Il reste toutefois dlicat pour une premire lecture.
Listing 13 Inteprolation cosinusodale nD
double smooth_noi se ( double data [ ] , i nt dim)
{
3 return _smooth_noise ( data , dim , dim ) ;
}
double _smooth_noise ( double data [ ] , i nt dim , i nt dim_work)
{
8 // Condi t i on d ar r t de l a boucl e r c ur s i v e
//Nous permet d ob t e ni r l e s poi nt s
i f ( dim_work <= 0)
// Fonct i on de b r ui t mul t i di mens i onnel
return noi s e ( data , dim ) ;
13
//Rcupre l a der ni r e di mensi on sur
// l a q u e l l e nous t r a v a i l l o n s
double x = data [ dim_work 1 ] ;
i nt i nteger_x = ( i nt ) x ;
18 double f r ac t i onal _x = x i nteger_x ;
// I nt e r p o l a t i o n de l a di mensi on dim_work 1 ,
// avec x = i nt eger_x
data [ dim_work 1] = i nteger_x ;
23 double a = _smooth_noise ( data , dim , dim_work 1 ) ;
// I nt e r p o l a t i o n de l a di mensi on dim_work 1 ,
// avec x = i nt eger_x + 1
data [ dim_work 1] = i nteger_x + 1;
28 double b = _smooth_noise ( data , dim , dim_work 1 ) ;
// Rest aurat i on du t abl eau , pour ne pas
// perdre l a val e ur en s or t ant de l a f onc t i on
data [ dim_work 1] = x ;
33
// I nt e r p o l a t i o n de l a di mensi on dim_work
return c os i ne _i nt e r pol at e ( a , b , f r ac t i onal _x ) ;
}
3 INTERPOLATIONS DE VALEURS 16
3.7 Splines cubiques
Nous avons pu gnraliser les interpolations linaires et cosinusodales plusieurs dimensions.
Ceci peut aussi sappliquer notre interpolation cubique. Vous pourrez en entendre parler sous
le nom de spline cubique. Cette fois, nous ne nous contenterons pas de deux points, mais de
quatres points. Le plus simple reste encore un schma (gure 9), pour la dimension deux.
Fig. 9 Splines cubiques
Le mcanisme est identique aux exemples prcdent, ceci prs que nous ncessiterons quatre
points par inteprolation. Nous nous contenterons dun exemple en dimension deux.
Listing 14 Inteprolation cubique 2D
//Nous i nt e r pol ons sur une l i gne , pour un y f i x
double smooth_noi se_f i rstdi m ( i nt i nteger_x ,
i nt i nteger_y , double f r ac t i onal _x )
4 {
double v0 = noi s e ( i nteger_x 1 , i nteger_y ) ;
double v1 = noi s e ( i nteger_x , i nteger_y ) ;
double v2 = noi s e ( i nteger_x + 1 , i nteger_y ) ;
double v3 = noi s e ( i nteger_x + 2 , i nteger_y ) ;
9
return c ubi c _i nt e r pol at e ( v0 , v1 , v2 , v3 , f r ac t i onal _x ) ;
}
//Nous i nt e r pol ons sur l e s y , en u t i l i s a n t l a f onc t i on prcdent e
14 double smooth_noi se ( double x , double y)
{
i nt i nteger_x = ( i nt ) x ;
double f r ac t i onal _x = x i nteger_x ;
i nt i nteger_y = ( i nt ) y ;
19 double f r ac t i onal _y = y i nteger_y ;
double t0 = smooth_noi se_f i rstdi m ( i nteger_x ,
i nteger_y 1 , f r ac t i onal _x ) ;
double t1 = smooth_noi se_f i rstdi m ( i nteger_x ,
24 i nteger_y , f r ac t i onal _x ) ;
double t2 = smooth_noi se_f i rstdi m ( i nteger_x ,
3 INTERPOLATIONS DE VALEURS 17
i nteger_y + 1 , f r ac t i onal _x ) ;
double t3 = smooth_noi se_f i rstdi m ( i nteger_x ,
i nteger_y + 2 , f r ac t i onal _x ) ;
29
return c ubi c _i nt e r pol at e ( t0 , t1 , t2 , t3 , f r ac t i onal _y ) ) ;
}
4 LE BRUIT DE PERLIN 18
4 Le bruit de Perlin
4.1 Comprhension et implmentation
Nous diposons maintenant de tous les outils ncessaires la ralisation de notre bruit de
Perlin.
Le bruit de Perlin est form dune somme de fonctions de bruit, dont la frquence et lamplitude
varie. Ici, nous appellerons frquence linverse du pas, et nous appellerons pas lintervale entre
deux points dnis par notre bruit. Jusqu prsent, deux de nos points taient spars par une
distance de 1, mais nous aurions trs bien pu choisir 10, ou bien 0.5.
Nous allons donc chercher faire varier le pas. Pour ce faire, nul besoin de modier notre
fonction smooth_noise ; si nous multiplions nos coordonnes par 2, avant dappeler cette fonction,
nous divisons lintervale entre deux points par deux. Si, linverse, nous les multiplions par "0.5",
alors nous multiplions lintervale entre deux points par deux.
Si nous cherchons donc multiplier notre pas par k, nous multiplions nos coordonnes par la
frquence
1
k
.
La gure 10 reprsente dirents appels notre fonction, o le paramtre x de notre fonction
de bruit liss est la coordonne x du pixel de limage.
Fig. 10 Eet de quelques frquences sur smooth_noise
Nous allons donc sommer des courbes damplitude de plus en plus faible, le contrle de la
variation damplitude de chacune de ces courbes et donc, leur part dans la courbe nale lors
4 LE BRUIT DE PERLIN 19
de cette somme se fera par un paramtre que lon nommera la persistance. Ceci, adjoint des
courbes de variation de plus en plus rapide, va crer leet nuageux du bruit de Perlin. Pour
tre exacts, nous approximons une fractale o si lon observe de plus prs une zone particulire,
nous retrouvons le mme motif qu lchelle prcdente.
Si nous reprenons nos courbes de lexemple prcdent et que nous les sommons, en pondrant
lamplitude de chacune de ces fonctions, nous obtenons la gure 11.
Fig. 11 Somme des frquences 1, 0.1, 0.05 et 0.01 avec une persistance de 0.5
Nous allons donc raliser une fonction qui prendra en argument :
Le nombre doctaves n : le nombre dappels la fonction de bruit liss
La frquence f: la frquence de la premire fonction de bruit liss
La persistance p: correspond au facteur qui vient modier lamplitude de chaque fonction
de bruit liss
Concrtement, nous allons faire la somme de n appelles smooth_noise en multipliant
chaque fois la frquence par deux, et lamplitude (qui vaut initialement 1) par la persistance. On
obtiendra donc la fonction : f : x
n1
i=0
p
i
smooth_noise(f 2
i
x).
Attention, pour conserver nos valeurs dans lintervalle [1, 1], nous devons diviser le rsultat
total par la somme des amplitudes. Pour simplier nos calculs et viter de sommer chacune delle,
on peut utiliser la formule de la somme des termes dune srie gomtrique

n1
i=0
p
i
=
1p
n
1p

condition que p = 1. On divisera donc par cette valeur.
Nous parvenons donc, en termes de code C, lextrait 15.
Listing 15 Bruit de Perlin 1D
double pe r l i n ( i nt octaves , double f requency ,
double pe r s i s t e nc e , double x)
{
4 double r = 0 . ;
double f = f r equency ;
4 LE BRUIT DE PERLIN 20
double ampl i tude = 1 . ;
for ( i nt i = 0; i < oct aves ; i ++)
9 {
r += smooth_noi se ( x f ) ampl i tude ;
ampl i tude = pe r s i s t e nc e ;
f = 2;
}
14
double geo_lim = (1 pe r s i s t e nc e ) / (1 ampl i tude ) ;
return r geo_lim ;
}
4.2 Pixelisation aux coordonnes ngatives
Si vous vous contentez de la version propose, et que vous souhaitez utiliser lune des fonctions
de bruit liss avec des coordonnes ngatives, vous vous apercevrez alors que nos valeurs sont
incorrectes. Vous obtiendrez probablement quelque chose de comparable la gure 12.
Fig. 12 Apparition derreurs pour des coordonns ngatives
Le problme vient de notre faon de rcuprer la partie dcimale pour des valeurs ngatives.
En eet, convertir 0.5 en entier nous donne 0 l o nous attendrions 1.
Il faut donc corriger avec un bloc conditionnel similaire lextrait 16.
Listing 16 Correction de lerreur pour la partie entire
i f ( x >= 0)
2 i nteger_x = ( i nt ) x ;
4 LE BRUIT DE PERLIN 21
el se
i nteger_x = ( i nt ) x 1;
f r ac t i onal _x = x i nteger_x ;
4.3 Motif fractal vident au centre dhomothtie
Ce premier problme corrig, intressons-nous au bruit de Perlin, toujours au centre de notre
repre. Un regard attentif saura discerner la redondance du mme motif, dont seule la taille varie.
Vous pourrez mme, avec un peu de chance, compter combien dexemplaires du mme nuage vous
retrouvez, tous aligns sur une droite passant par lorigine (cf : gure 13). Vous remarquerez alors
que cela correspond exactement loctave de votre fonction de bruit de Perlin.
Fig. 13 Apparition de droites passant par lorigine
Ce problme est d au simple fait que chacune de vos fonctions de bruit ont pour centre
4 LE BRUIT DE PERLIN 22
dhomothtie lorigine. Ceci peut facilement se rgler en ajoutant une translation du centre de
cette homothtie qui est fonction de lindice de la fonction de bruit.
Plutt que de longs discours, un exemple concret sera bien plus parlant.
Listing 17 Ajout dune translation fonction de loctave au bruit de Perlin 1D
double pe r l i n ( i nt octaves , double f requency ,
double pe r s i s t e nc e , double x)
{
double r = 0 . ;
5 double f = f r equency ;
double ampl i tude = 1 . ;
for ( i nt i = 0; i < oct aves ; i ++)
{
10 // Trans l at i on du cent r e de s ymt ri e en i 4096
i nt t = i 4096;
// Cal cul du b r ui t t r a ns l a t
r += smooth_noi se ( x f + t ) ampl i tude ;
15
ampl i tude = pe r s i s t e nc e ;
f = 2;
}
20 double geo_lim = (1 pe r s i s t e nc e ) / (1 ampl i tude ) ;
return r geo_lim ;
}
5 LALGORITHME ORIGINAL 23
5 Lalgorithme original
5.1 Champs vectoriels
Lalgorithme que je vous ai prsent jusquici est le plus simple, mais de loin le moins ecace,
et dire du bruit de Perlin original, tel que K. Perlin limplmenta. Jusquici nous avons consi-
dr un champ scalaire, cest--dire qu chaque point de notre espace, nous avons associ une
valeur scalaire comprise dans lintervale [1, 1]. Lapproche de lalrithme original est lgrement
dirente. En eet, plutot que dassocier chaque point entier de notre espace une valeur, nous
allons lui associer un vecteur, qui dnira un gradient de couleur. Ce gradient, reprsente une
variation de la valeur -1 la valeur 1.
Fig. 14 Champ de gradient
Par la suite, nous eectuerons le produit scalaire de chacun de ces vecteurs de gradient,
avec le vecteur allant du point auquel est associ ce gradient vers le point de lespace que nous
considrons. Nous obtiendrons ainsi des valeurs scalaires 4 pour un plan que nous combinerons
en utilisant une interpolation similaire linterpolation cosinusodale.
lorigine, K. Perlin utilisa la fonction polynmiale dHermite, savoir f(t) = 3t
2
2t
3
qui
prsente une courbe tout fait adapte ce que nous cherchons (Cf: Interpolation cosinusoidal)
et qui vrie bien la condition dannulation de ses drives premires en 0 et 1. Toutefois, il est
plus que souhaitable que les drives secondes sannulent aussi en ces points, assurant ainsi une
meilleure continuit
2
. Ceci peut tre obtenu grce la fonction polynmiale f(t) = 6t
5
15t
4
+
10t
3
.
5.2 Tables de hachage
An daccrote de faon considrable la vitesse de calcul du bruit (sans perte de qualit
notable) nous utiliserons des tables de hachage pour les deux oprations essentielles de notre
calcul.
2
Les eets sont visible lorsque lon utilise le bruit de Perlin pour du bump mapping, ou encore de la gnration
de terrain. En eet, ce sont ici les drives premires et secondes qui entrent en jeu. La non utilisation de ce
polynme provoque des discontinuits, parfois trs visibles. Je vous renvoie au document [12].
5 LALGORITHME ORIGINAL 24
Dans un premier temps, nous nutiliserons plus notre fonction de bruit alatoire, mais une
permutation (n) sur lensemble des 256 premiers entiers. Cela signie qu chaque nombre
compris entre 0 et 255, nous lui associons une nouvelle valeur entire (n) comprise 0 255.
Cette table de permutation remplacera notre fonction pseudo-allatoire. Il va de soi quelle doit
tre, elle-mme, pseudo-allatoire. Nous prendrons la table propose dans un des documents de
rfrence, qui convient parfaitement.
Puisque nos valeurs sont thoriquements innies, nous devrons ramener la partie entire de
chacune des coordonnes lintervale [0, 255]. Comme ces valeurs sont judicieusement choisies,
pour calculer le modulo il nous sura de conserver les 8 premiers bits de chacune des coordon-
nes
3
, ce qui est une opration lmentaire des plus rapides.
Nous composerons nos permutations sur le mme modle que la gnration de bruit multidi-
mensionnel. Nous aurons donc (((((X%256) +Y )%256) +Z)%256).
An, toujours, de rduire le nombre doprations, nous utiliserons une table qui fait corres-
3
Pour rappel, un calcul de modulo possde un cot identique celui dune division. Aussi, puisquune division
par une puissance de deux est un simple dcalage binaire, le calcul dun modulo par une puissance de deux est
une simple conservation de bits.
Fig. 15 Vecteurs considrer
Fig. 16 Fonctions polynmiales
5 LALGORITHME ORIGINAL 25
pondre les 512 premiers entiers aux 256 premiers. Nous la construirons partir de la premire,
et poserons perm[i] = sigma[i & 0xFF] pour tout i de 0 511.
Dans un second temps, nous formerons une table de hachage qui fera correspondre notre
valeur alatoire un vecteur. Nous choisirons ces vecteurs de faon ce que leur norme soit du
mme ordre de grandeur, et quils soient approximativement galement rpartis dans lespace.
Concrtement, pour un bruit 2D nous prendrons des points rpartis un cercle, et pour un bruit
3D le milieu des artes dun cube.
Il nest pas ncessaire de possder 255 vecteurs, et loutil mathmatique quest le modulo nous
sera trs utile. Seuls 12 vecteurs sursent pour un bruit 3D. Mais an de faciliter le calcul du
modulo, nous pourons prendre 16 vecteurs, en ajoutant simplement le ttradre rgulier form
des points (1, 1, 0), (1, 1, 0), (0, 1, 1), (0, 1, 1).
5 LALGORITHME ORIGINAL 26
5.3 Une implmentation du cas tridimensionnel
Pour dcrire cette algorithme de faon ecace, je vous propose un code comment (extrait
18), reprenant ce dont nous avons parl prcdemment, correspondant a limplmentation dun
bruit de Perlin tridimensionnel. Vous pourrez facilement ladapter en une version bidimensionnel,
ou bien ajouter quelques vecteurs pour former un hypercube et obtenir un bruit 4D
4
.
Listing 18 Implmentation dun bruit de Perlin tridimensionnel
//////
//La t a b l e de permut at i on :
//////
// El l e as s oc i e chaque v al eur compri se ent r e 0 et 256 une uni que
5 // val eur e l l e aus s i compri se ent r e 0 et 256. C e s t une permut at i on .
// Af i n d v i t e r des opr at i ons de modulo , dans l e s ouci d a c c r o t r e
// l a v i t e s s e de c al c ul , e l l e e s t d f i ni e de 0 512.
unsigned char perm[ 5 1 2 ] = {
//0 256
10 151 , 160 , 137 , 91 , 90 , 15 , 131 , 13 , 201 , 95 , 96 , 53 , 194 , 233 , 7 , 225 , 140 ,
36 , 103 , 30 , 69 , 142 , 8 , 99 , 37 , 240 , 21 , 10 , 23 , 190 , 6 , 148 , 247 , 120 , 234 ,
75 , 0 , 26 , 197 , 62 , 94 , 252 , 219 , 203 , 117 , 35 , 11 , 32 , 57 , 177 , 33 , 88 , 237 ,
149 , 56 , 87 , 174 , 20 , 125 , 136 , 171 , 168 , 68 , 175 , 74 , 165 , 71 , 134 , 139 ,
48 , 27 , 166 , 77 , 146 , 158 , 231 , 83 , 111 , 229 , 122 , 60 , 211 , 133 , 230 , 220 ,
15 105 , 92 , 41 , 55 , 46 , 245 , 40 , 244 , 102 , 143 , 54 , 65 , 25 , 63 , 161 , 1 , 216 , 80 ,
73 , 209 , 76 , 132 , 187 , 208 , 89 , 18 , 169 , 200 , 196 , 135 , 130 , 116 , 188 , 159 ,
86 , 164 , 100 , 109 , 198 , 173 , 186 , 3 , 64 , 52 , 217 , 226 , 250 , 124 , 123 , 5 ,
202 , 38 , 147 , 118 , 126 , 255 , 82 , 85 , 212 , 207 , 206 , 59 , 227 , 47 , 16 , 58 , 17 ,
182 , 189 , 28 , 42 , 223 , 183 , 170 , 213 , 119 , 248 , 152 , 2 , 44 , 154 , 163 , 70 ,
20 221 , 153 , 101 , 155 , 167 , 43 , 172 , 9 , 129 , 22 , 39 , 253 , 19 , 98 , 108 , 110 , 79 ,
113 , 224 , 232 , 178 , 185 , 112 , 104 , 218 , 246 , 97 , 228 , 251 , 34 , 242 , 193 ,
238 , 210 , 144 , 12 , 191 , 179 , 162 , 241 , 81 , 51 , 145 , 235 , 249 , 14 , 239 , 107 ,
49 , 192 , 214 , 31 , 181 , 199 , 106 , 157 , 184 , 84 , 204 , 176 , 115 , 121 , 50 , 45 ,
127 , 4 , 150 , 254 , 138 , 236 , 205 , 93 , 222 , 114 , 67 , 29 , 24 , 72 , 243 , 141 ,
25 128 , 195 , 78 , 66 , 215 , 61 , 156 , 180 ,
//257 512
151 , 160 , 137 , 91 , 90 , 15 , 131 , 13 , 201 , 95 , 96 , 53 , 194 , 233 , 7 , 225 , 140 ,
// . . .
127 , 4 , 150 , 254 , 138 , 236 , 205 , 93 , 222 , 114 , 67 , 29 , 24 , 72 , 243 , 141 ,
30 128 , 195 , 78 , 66 , 215 , 61 , 156 , 180};
//////
//La t a b l e des v e c t e ur s :
//////
35 // El l e c ont i e nt l e s g r adi e nt s de coul eur
// que nous a l l o ns as s oc i e r chaque poi nt de l espace .
stati c i nt _grad3 [ 1 6 ] [ 3 ] = {
//Le cube
4
K. Perlin conseil, ds que lon a aaire plus de trois dimensions, dutiliser le simplex noise, dont il est
question dans le chapitre suivant. Si lon compare la complexite logarithmique du bruit de Perlin et du simplex
noise relativement la dimension, le premier est en O(2
n
) contre n
2
pour le second.
5 LALGORITHME ORIGINAL 27
{1 , 1 , 0} , { 1 , 1 , 0} , {1 , 1 , 0} , { 1 , 1 , 0} ,
40 {1 , 0 , 1} , { 1 , 0 , 1} , {1 , 0 , 1} , { 1 , 0 , 1} ,
{0 , 1 , 1} , {0 , 1 , 1} , {0 , 1 , 1} , {0 , 1 , 1} ,
// Ai nsi qu un t t r a dr e s uppl ment ai re
{1 , 1 , 0} , { 1 , 1 , 0} , {0 , 1 , 1} , {0 , 1 , 1}};
45 ////
// Fonct i on : Produi t s c a l a i r e
////
// Ef f e c t ue l e pr odui t s c a l a i r e du vect eur V( v [ 0 ] , v [ 1 ] , v [ 2 ] )
// avec U( x , y , z ) .
50 // Cet t e f onc t i on nous s e r v i r a c a l c ul e r l e pr odui t s c a l a i r e
// ent r e nos g r adi e nt s de coul eur et nos v e c t e ur s d i r i g s
// ver s not re poi nt .
double f ast_dot ( const i nt v , const double x ,
const double y , const double z )
55 {
return v [ 0 ] x + v [ 1 ] y + v [ 2 ] z ;
}
////
60 // Fonct i on : Obt ent i on du g r adi e nt pour un poi nt P( x , y , z )
// de l espace
////
i nt get_grad ( i nt x , i nt y , i nt z )
{
65 // Cal cul un b r ui t a l a t o i r e de 3 v ar i ab l e s , vi a l a t a b l e
// de permut at i on .
i nt rand_val ue = perm[ z + perm[ y + perm[ x ] ] ] ;
// Appl i que un modulo 16 c e t t e val e ur pour ob t e ni r un
// g r adi e nt de coul eur , pui s r envoi e un poi nt eur sur
70 // c e t t e l ment .
return _grad3 [ rand_val ue & 1 5 ] ;
}
////
75 // Fonct i on : Fonct i on pol ynmi al e d r i v e s premi re
// et seconde nul l e s
////
// Cal cul e si mpl ement l a v al eur de ce polynme en x=t
double qui nt i c_pol y ( const double t )
80 {
const double t3 = t t t ;
return t3 ( t ( t 6. 15. ) + 1 0 . ) ;
}
85 ////
// Fonct i on : Spare l a par t i e e nt i r e et f r a c t i o nna i r e
////
5 LALGORITHME ORIGINAL 28
void i nt_and_frac ( double val ue , i nt i nteger_part ,
double f r ac t i onal _par t )
90 {
i nt eger _par t = ( i nt ) val ue ;
i f ( val ue < 0)
i nt eger _par t = 1;
f r ac t i onal _par t = val ue i nt eger _par t ;
95 }
//La f onc t i on pr i nc i pal e , permet t ant d ob t e ni r l e b r ui t l i s s
double smooth_noise_3d ( double x_pos , double y_pos , double z_pos )
{
100 //Les p a r t i e s e nt i r e s
i nt X, Y, Z;
//Les p a r t i e s f r a c t i o nna i r e s
// x , y , z ;
105 //Comme pour l e prcdent al gori t hme , nous sparons p a r t i e s
// e nt i r e et f r a c t i o nna i r e .
i nt_and_frac ( x_pos , &X, &x ) ;
i nt_and_frac ( y_pos , &Y, &y ) ;
i nt_and_frac ( z_pos , &Z, &z ) ;
110
//Nous appl i quons un modulo 256 , de f aon ce que ces
// v al e ur s s oi e nt compri ses dans not re t a b l e de permut at i on ,
// et que nous pui s s i ons u t i l i s e r l a f onc t i on d ob t ent i on
// de g r adi e nt .
115 X &= 255;
Y &= 255;
Z &= 255;
//Nous rcuprons l e s g r adi e nt en chacun des sommets du cube
120 // cont enant not re poi nt .
//Nous f ai s ons al or s l e pr odui t de chacun de ces g r adi e nt s
// obt enu en un sommet S par l e vect eur i s s u de S et d i r i g
// ver s not re poi nt M( x_pos , y_pos , z_pos ) .
//On r et r ouve f ac i l e me nt ces v al e ur s
125 // en des s i nant un schma de not re cube .
//Chacune de ces v a r i a b l e s ( r s u l t a t de ce pr odui t s c a l a i r e )
// por t e un nom c ons t i t u de l a l e t t r e g s u i v i e des
// coordonnes x , y , et z du poi nt du cube dont i l e s t i s s u .
const double g000 = f ast_dot ( get_grad (X, Y, Z) ,
130 x , y , z ) ;
const double g001 = f ast_dot ( get_grad (X, Y, Z + 1) ,
x , y , z 1 . ) ;
const double g010 = f ast_dot ( get_grad (X, Y + 1 , Z) ,
x , y 1 . , z ) ;
135 const double g011 = f ast_dot ( get_grad (X, Y + 1 , Z + 1) ,
x , y 1 . , z 1 . ) ;
5 LALGORITHME ORIGINAL 29
const double g100 = f ast_dot ( get_grad (X + 1 , Y, Z) ,
x 1 . , y , z ) ;
const double g101 = f ast_dot ( get_grad (X + 1 , Y, Z + 1) ,
140 x 1 . , y , z 1 . ) ;
const double g110 = f ast_dot ( get_grad (X + 1 , Y + 1 , Z) ,
x 1 . , y 1 . , z ) ;
const double g111 = f ast_dot ( get_grad (X + 1 , Y + 1 , Z + 1) ,
x 1 . , y 1 . , z 1 . ) ;
145
//Comme pour l i nt e r p o l a t i o n c os i nus o dal e , nous c al c ul ons
// l e polynme pour chacune de nos v al e ur s d i nt e r p o l a t i o n :
// u pour l i nt e r p o l a t i o n l e l ong de l axe des x
// v pour l i nt e r p o l a t i o n l e l ong de l axe des y
150 // w pour l i nt e r p o l a t i o n l e l ong de l axe des z
const double u = qui nt i c_pol y ( x ) ;
const double v = qui nt i c_pol y ( y ) ;
const double w = qui nt i c_pol y ( z ) ;
//Comme nous l avons f a i t avec l i nt e p r o l a t i o n cubi que ,
155 // nous composerons :
// l i nt e r p o l a t i o n l e l ong de l axe x par
// l i nt e p r o l a t i o n l e l ong de l axe y .
//Nous i nt e r pol ons l e l ong de l axe des x sur chacune
160 // des ar t e s p a r a l l l e s c e t axe de not re cube .
const double x00 = Math : : l i ne a r _i nt e r po l a t e ( g000 , g100 , u ) ;
const double x10 = Math : : l i ne a r _i nt e r po l a t e ( g010 , g110 , u ) ;
const double x01 = Math : : l i ne a r _i nt e r po l a t e ( g001 , g101 , u ) ;
const double x11 = Math : : l i ne a r _i nt e r po l a t e ( g011 , g111 , u ) ;
165
//Nous i nt e r pol ons l e s ar t e s deux deux p a r a l l l e s
// se t r ouvant sur l a mme f ace de not re cube .
const double xy0 = Math : : l i ne a r _i nt e r po l a t e ( x00 , x10 , v ) ;
const double xy1 = Math : : l i ne a r _i nt e r po l a t e ( x01 , x11 , v ) ;
170
//Enfin , nous i nt e r pol ons ent r e l e s f ac e s i nf r i e u r et
// l a f ace s upr i eur de not re cube .
const double xyz = Math : : l i ne a r _i nt e r po l a t e ( xy0 , xy1 , w) ;
175 return xyz ;
}
//La somme des d i v e r s e s oct aves pour ob t e ni r l e mot i f nuageux
// e s t i de nt i q ue au prcdent al gor i t hme .
6 SIMPLEX NOISE 30
6 Simplex Noise
Si lon souhaite disposer dun bruit de perlin quadrimensionel, ou de dimension suprieure, on
se retrouve face un temps de calcul consquent que lon souhaiterait rduire. Pour parer cette
dicult, Ken Perlin proposa le Simplex noise. Le terme Simplex fait rfrences aux simplexes
rguliers, les solides rguliers que lon peut construire avec un nombre minimal de points
dimension n x. En dimension deux, nous trouvons le triangle quilatral, et en dimension
trois, le thtradre.
6.1 Principe
Lide essentielle est de paver lespace de dimension n avec des simplexes rguliers de cot 1.
chaque sommet s issu de ce pavage, on associe un vecteur gradient

G
s
, tout comme nous lavions
fait dans le cas du bruit de Perlin. On donne alors les coordonnes dun point P(x
1
, . . . , x
n
) et
lon cherche les trois sommets les plus proches, cest--dire quel n-simplexe ce point appartient.
Si lon note A
1
, . . . , A
n+1
les n + 1 sommets de ce simplexe, on dtermine alors les vecteurs

A
1
P,

A
2
P, . . . ,

A
n+1
P. Enn, on choisit une fonction radiale f(r) qui sannule et change de
signe si la distance r = |

A
i
P| de P lun des sommets A
i
est suprieure
5

1
2
. La valeur du bruit
en P est alors la somme, sur chacun des sommets ;
n+1

i=0
f(r
i
)

A
i
P.

G
A
i
o r
i
= |

A
i
P|
Cest--dire la somme des produits scalaire des vecteurs gradient par les vecteurs sommetpoint,
pondre par les fonctions radiales. La gure 17 prsente lapplication de cette formule un
unique sommet, ce qui correspond f(|

AP|)

AP.

G
A
. Le vecteur gradient est

G
A
=
_
(1
0)
_
.
Fig. 17 Fonction radiale et gradient de couleur
La fonction propose par Perlin est f(r) = (
1
2
d)
4
K o K est une constante qui compense
les faibles valeurs obtenues suite lutilisation dune puissance 4
ime
.
Il est relativement facile, connaissant les coordonnes des points du simplexe auquel appartient
P de calculer la valeur du bruit en ce point. Lobtention de ces coordonnes nest pas si vidente,
comme nous allons le voir.
6.2 Changement de base
Les coordonns des points que nous manipulons sont de la forme
_
(x
y)
_
et sont crits dans
la base canonique (orthonorme directe) (x, y). Mais on peut tout fait concevoir une base
5
De cette faon on sassure, quen un point P, deux fonctions radiales ne peuvent sadditionner.
6 SIMPLEX NOISE 31
construite sur le pavage par des simplexes rguliers (en dimensions 2, ce sont des triangles qui-
lateraux), de prfrence compose de deux vecteurs unitaires
6
. La gure 18 prsente la base dans
laquelle nous souhaitons trouver les coordonnes du point P observ. En eet, si nous disposons
de ses coordonnes dans cette base, il nous sut de conserver la partie entire pour obtenir le
sommet le plus proche de lorigine. Puisque chacun des vecteurs de notre base est une arrte,
nous pouvons, avec ce point, en dduire tous les autres sommets constituant le simplexe.
Fig. 18 Pavage par des 2-simplexes rguliers de cot 1
Le changement de base exact fait intervenir des calculs correspondant un produit matriciel.
Dans le cas plan, les coecients de la matrice sont des sinus et cosinus, et le calcul ne se sim-
plie pas lgamment. Nous allons donc utiliser une approximation de la vritable application
changement de base. Nous cherchons une application linaire dont la matrice est de la forme
_
_
_
_
K + 1 . . . K
.
.
.
.
.
.
.
.
.
K . . . K + 1
_
_
_
_
ceci an que le calcul des nouvelles coordonnes se ramne au systme
_

_
x

= x +K(x +y + +z)
y

= y +K(x +y + +z)
.
.
.
z

= x +K(x +y + +z)
o x

, y

, . . . , z

sont les nouvelles coordonnes de P. Lavantage de ces equations est quil


sut de calculer un unique produit, pour obtenir par la suite chaque coordonn par une simple
somme. De plus, une magnique proprit de cette matrice est que son inverse (cest--dire la
matrice de lapplication rciproque, qui permet de retourner de la nouvelle base lancienne
6
Ils nont, bien entendu, aucune raison dtre orthogonaux.
6 SIMPLEX NOISE 32
base, an de calculer les coordonnes de nos vecteurs dans la base canonique) est de la forme
_
_
_
_
1 C . . . C
.
.
.
.
.
.
.
.
.
C . . . 1 C
_
_
_
_
o C =
K
1+2K
.
Lide est que, si lon pave notre premier repre, celui qui utilise la base canonique, avec des
carrs, on peut alors constater lexistence de couples de triangles quilatraux dans chacun deux.
Alors chercher une application qui les transforme en triangles quilatraux revient chercher
notre changement de coordonnes. Ken Perlin propose quelques valeurs pour K, prsentes dans
le tableau 19. Elles sont utilises dans de nombreuses implmentations.
Fig. 19 Valeurs possible pour K
Dimension Coecient
2

31
2
3
1
3
. . .
.
.
.
n

n+11
n
6.3 Implmentation
Nous allons, une dernire fois, prsenter une implmentation qui permettra certainement de
poser les ides et peut-tre dclaircir certains concepts. Nous nous appliquerons au cas bidimen-
sionnel, qui constitue lexemple le plus simple permettant dillustrer le principe.
Listing 19 Implmentation du simplex noise
1 ////
// Fonct i on : Produi t s c a l a i r e
////
double f ast_dot ( const i nt v , const double x ,
const double y)
6 {
return v [ 0 ] x + v [ 1 ] y ;
}
////
11 // Fonct i on : Obt ent i on du g r adi e nt pour un poi nt P( x , y )
// du pl an
////
i nt get_grad ( i nt x , i nt y)
{
16 i nt rand_val ue = perm[ z + perm[ y + perm[ x ] ] ] ;
6 SIMPLEX NOISE 33
return _grad3 [ rand_val ue & 1 5 ] ;
}
////
21 // Fonct i on : Tronque l a val eur x
// et ne conserve que sa par t i e e nt i r e
i n l i n e i nt f a s t f l o o r ( double x)
{
return ( x > 0) ? ( i nt ) x : ( i nt ) x 1;
26 }
//La f onc t i on p r i nc i p a l e
double smooth_noise_3d ( double x , double y)
{
31 // D f i ni t i on des cons t ant es K et C u t i l i s e s
//dans l e s c a l c u l s de changement de base .
const double K = ( s qr t ( 3 . ) 1 . ) / 2 . ;
const double C = K / ( 1 . + 2. K) ;
36 //On appl i q ue l a t rans f or mat i on qui permet ,
// p a r t i r des coordonnes ( x , y ) ,
// d ob t e ni r l e s coordonnes ( i , j )
// dans l a base des s i mpl exes .
double s = ( x + y) K;
41 double i = x + s ;
double j = y + s ;
//On t ronque l e s coordonnes de f aon ob t e ni r l e poi nt
// l e pl us proche de l or i g i ne du s i mpl exe cont enant P
46 i = f a s t f l o o r ( i ) ;
j = f a s t f l o o r ( j ) ;
//Nous e f f e c t uons l e changement de base i nvers e ,
// c est di r e qu p a r t i r des coordonnes ( i , j )
51 // d un des sommets de not re si mpl exe , nous
// cherchons l e s coordonnes (X0, Y0) dans
// l a base canoni que .
double t = ( i + j ) C;
double X0 = i t ;
56 double Y0 = j t ;
//Nous pouvons al or s dt ermi ner l e premi er vect eur
// AP. I l r e s t e dt ermi ner BP et CP.
double x0 = x X0;
61 double y0 = y Y0;
//Nous devons dt ermi ner s i l e poi nt P se t rouve
// dans l e t r i a ng l e i s o c l e supri eur , ou bi en
// l e t r i a ng l e i nf r i e u r .
6 SIMPLEX NOISE 34
66 //Une f o i s e l a dt ermi ner , et en cons i dr ant
// que l e premi er sommet e s t ( 0 , 0) , nous savons
// s i l e second sommet e s t (1 , 0) ou bi en ( 0 , 1) .
// Nous s t ockons s es coordonnes dans ( i 1 , j 1 )
i nt i 1 = 0 , j 1 = 0;
71 i f ( x0 > y0 )
i 1 = 1;
el se
j 1 = 1;
76 //Nous pouvons al or s dt ermi ner l e s v e c t e ur s BP et CP
//En e f f e t , s i nous appl i quons not re f ormul e
// aux v e c t e ur s ( 0 , 1) et ( 1 , 0) , nous
// cons t at ons que l e s coordonnes dans
// l a base caconi que sont al or s ,
81 // res pect i vement , (C, 1C) et (1C, C) .
// Vecteur AP = ( x1 , y1 )
double x1 = x0 i 1 + C;
double y1 = y0 j 1 + C;
//Le t r oi s i me poi nt e s t ncessai rement l e poi nt ( 1 , 1)
86 // dont l e s coordonnes sont (12C, 12C) .
// Vecteur CP = ( x2 , y2 )
double x2 = x0 1 + 2. C;
double y2 = y0 1 + 2. C;
91 //Nous c al c ul ons al or s l a norme de chacun de ces v e c t e ur s :
// |AP|
double d0 = 0. 5 x0x0 y0y0 ;
// |BP|
double d1 = 0. 5 x1x1 y1y1 ;
96 // |CP|
double d2 = 0. 5 x2x2 y2y2 ;
//Nous s t ockons l e r s u l t a t du c a l c u l dans l a v a r i a b l e r es
double r e s = 0;
101
//On appl i q ue un modulo 255 aux coordonnes i et j
// af i n de pouvoi r dt ermi ner l e ur g r adi e nt .
i nt i i = ( i nt ) i & 255;
i nt j j = ( i nt ) j & 255;
106
//On ne c a l c ul e l e pr odui t s c a l a i r e que s i l e s
// f onc t i ons r a d i a l e s sont p o s i t i v e s .
//Dans ce cas , on e f f e c t u e l e pr odui t s c al ai r e ,
// exact ement de l a mme f aon qu avec
111 // l e b r ui t de Per l i n .
i f ( d0 > 0)
{
d0 = d0 ;
6 SIMPLEX NOISE 35
r e s += d0 d0
116 dot ( __get_grad( i i , j j ) , x0 , y0 ) ;
}
i f ( d1 > 0)
{
d1 = d1 ;
121 r e s += d1 d1
dot ( __get_grad( i i +i 1 , j j +j 1 ) , x1 , y1 ) ;
}
i f ( d2 > 0)
{
126 d2 = d2 ;
r e s += d2 d2
dot ( __get_grad( i i + 1 , j j + 1) , x2 , y2 ) ;
}
131 //On appl i q ue l e f ac t e ur K permetant de ramener
// l ampl i t ude de l a val eur proche de [ 1, 1 ] .
return 60 r e s ;
}
7 CONCLUSION 36
7 Conclusion
Vous disposez maintenant de toutes les connaissances ncessaires limplmentation dun
bruit de Perlin N dimensions. Vous trouverez sur internet nombre de documents expliquant
comment composer un bruit de Perlin avec dautres fonctions an dobtenir des textures sem-
blables du bois, du marbre, du feu, et de nombreuses autres matires.
Si vous souhaitez en apprendre plus sur les alternatives au bruit de Perlin, je vous recommande
chaudement de vous renseigner au sujet du bruit de Gabor (cf:[1]).
7.1 Remerciements
Je tiens remercier Mael Minot et Antoine Pinochet-Lobos pour leur relecture orthogra-
phique.
Rfrences
[1] G. Drettakis P. Dutr A. Lagae, S. Lefebvre. Procedural noise using sparse gabor convo-
lution. http://graphics.cs.kuleuven.be/publications/LLDD09PNSGC/LLDD09PNSGC_
paper.pdf.
[2] Paul Bourke. Interpolation methods. Decembre 1999. http://local.wasp.uwa.edu.au/
~pbourke/miscellaneous/interpolation/.
[3] Paul Bourke. Perlin noise and turbulence. Janvier 2000. http://local.wasp.uwa.edu.
au/~pbourke/texture_colour/perlin/.
[4] Hugo Elias. Perlin noise. Decembre 1998. http://freespace.virgin.net/hugo.elias/
models/m_perlin.htm.
[5] Wikipedia EN. Interpolation bicubique. http://en.wikipedia.org/wiki/Bicubic_
interpolation.
[6] Wikipedia EN. Interpolation tricubique. http://en.wikipedia.org/wiki/Tricubic_
interpolation.
[7] Wikipedia EN. Perlin noise. http://en.wikipedia.org/wiki/Perlin_noise.
[8] Franois Faure. Interpolation de positions-clefs. http://www-evasion.imag.fr/
~Francois.Faure/enseignement/maitrise/interpolation/interpolation.pdf.
[9] Stefan Gustavson. Simplex noise demystied. Mars 2005. http://staffwww.itn.liu.se/
~stegu/simplexnoise/simplexnoise.pdf.
[10] Ken Perlin. Improving noise. http://mrl.nyu.edu/~perlin/paper445.pdf.
[11] Ken Perlin. Making noise. December 1999. http://www.noisemachine.com/talk1/index.
html.
[12] Iigo Quilez. Advanced perlin noise. 2008. http://iquilezles.org/www/articles/
morenoise/morenoise.htm.
[13] Pierre Schwartz. Gnration de terrain par lalgorithme de perlin. http://khayyam.
developpez.com/articles/algo/perlin/.
Index
B
bruit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
bruit de Perlin. . . . . . . . . . . . . . . . . . . . . . . 18
C
champs vectoriels . . . . . . . . . . . . . . . . . . . . 23
changement de base. . . . . . . . . . . . . . . . . . 30
D
dimensions. . . . . . . . . . . . . . . . . . . . . . . . . . . 13
F
fonction de bruit . . . . . . . . . . . . . . . . . . . . . . 5
frquence . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
fractals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
G
gradients . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
I
interpolation . . . . . . . . . . . . . . . . . . . . . . . . . . 7
interpolation cosinusodale . . . . . . . . . . . . 8
interpolation cubique . . . . . . . . . . . . . . . . 10
interpolation de bruit . . . . . . . . . . . . . . . . 10
interpolation linaire . . . . . . . . . . . . . . . . . . 7
interpolation polynmiale . . . . . . . . . . . . 23
O
octaves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
P
pavage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
persistance. . . . . . . . . . . . . . . . . . . . . . . . . . . 19
pixelisation . . . . . . . . . . . . . . . . . . . . . . . . . . 20
pseudo-alatoire. . . . . . . . . . . . . . . . . . . . . . . 4
S
simplexe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
splines cubiques. . . . . . . . . . . . . . . . . . . . . . 16
T
tables de hachage . . . . . . . . . . . . . . . . . . . . 23
37

You might also like