Le bruit de Perlin est une texture procédurale utilisée comme effet visuel pour augmenter le réalisme apparent dans la synthèse d'image. La fonction a une apparence pseudo-aléatoire, et pourtant tous ses détails visuels sont de taille égale (voir image). Cette propriété permet à cette texture d'être facilement contrôlable. De multiples copies zoomées de bruit de Perlin peuvent être insérées dans des expressions mathématiques pour créer une grande variété de textures procédurales.

Bruit de Perlin en deux dimensions.

Usages

modifier
 
Bruit de Perlin redimensionné et combiné à lui-même pour créer un bruit fractal.

Le bruit de Perlin est une primitive utilisée pour la génération de textures procédurales. C'est un bruit de gradient (par opposition aux bruits de valeur) utilisé pour améliorer le réalisme des infographies. La fonction a un aspect pseudo-aléatoire, cependant ses détails sont de la même taille : cette propriété la rend facile à contrôler et à combiner à différentes échelles.

Le bruit de Perlin est souvent utilisé dans les images de synthèse pour des éléments tels que le feu, la fumée ou les nuages.

Les démos utilisent couramment le bruit de Perlin car il est très économe en espace mémoire.

Il est aussi utilisé dans le jeu vidéo : par exemple, Minecraft utilise le bruit de Perlin pour générer ses mondes[1].

Développement

modifier
Boule de feu générée par "Bruit de Perlin".

Le bruit de Perlin a été développé par Ken Perlin en 1985. À cette époque, après avoir travaillé sur les effets spéciaux de Tron pour MAGI (en) en 1981, il cherchait à éviter le rendu « très artificiel »[2] des images de synthèse. Il commença donc à mettre au point une fonction pseudo-aléatoire de bruit qui remplit les trois dimensions de l'espace[3],[4], avant d'inventer l'année suivante le premier langage de shading (en)[5]. Ses travaux sur les textures procédurales ont valu à Ken Perlin l'Academy Award for Technical Achievement (en) en 1997[6].

Algorithme

modifier

Le bruit de Perlin est le plus couramment utilisé à deux, trois, voire quatre dimensions, il peut être défini pour un nombre quelconque de dimensions. L'algorithme se décompose en trois étapes :

  • Définition de la grille avec des vecteurs de gradient aléatoires
  • Calcul du produit scalaire entre le vecteur de gradient et le vecteur distance
  • Interpolation entre ces valeurs

Définition de la grille

modifier

Définir une grille à n dimensions. À chaque intersection de la grille (ou sommet), attribuer un vecteur de gradient unitaire, de direction aléatoire et de dimension n.

Par exemple :

  • Pour une grille à deux dimensions (n = 2), on assigne à chaque sommet un vecteur aléatoire du cercle unité.
  • Pour une grille à une dimension (n = 1), on assigne à chaque sommet un nombre aléatoire entre -1 et 1.

Le calcul des gradients (pseudo)-aléatoires en une et deux dimensions est trivial en utilisant un générateur de nombres aléatoires. Pour les dimensions supérieures, une approche Monte Carlo peut être utilisée où les coordonnées cartésiennes aléatoires sont choisies dans un cube unité, les points situés en dehors de la sphère unité sont rejetés et les points restants sont normés.

Produit scalaire

modifier

Pour calculer la valeur du bruit en un point P donné, déterminer dans quelle cellule de la grille se trouve P. Pour chaque sommet de cette cellule, calculer le vecteur de distance entre P et le sommet. Calculer le produit scalaire entre le vecteur de gradient au sommet et le vecteur de distance.

Pour un point dans une grille à deux dimensions, il faut calculer 4 vecteurs de distance et 4 produits scalaires, tandis que dans une grille à trois dimensions, il faut calculer 8 vecteurs de distance et 8 produits scalaires. Ceci conduit à une complexité algorithmique   .

Interpolation

modifier

La dernière étape est l'interpolation entre les   produits scalaires calculés aux sommets de la cellule contenant P. Cela a pour conséquence que la fonction de bruit renvoie 0 pour les sommets de la grille.

L'interpolation est effectuée en utilisant une fonction dont la dérivée première (et éventuellement la dérivée seconde) est nulle aux   nœuds de la grille . Cela a pour effet que le gradient de la fonction de bruit résultante à chaque nœud de grille coïncide avec le vecteur de gradient aléatoire précalculé. Par exemple, si  , un exemple de fonction qui interpole entre la valeur   au nœud de grille 0 et la valeur   au nœud de grille 1 est

 

où la fonction smoothstep (en) a été utilisée.

Les fonctions de bruit utilisées dans l'infographie produisent généralement des valeurs comprises dans l'intervalle [-1.0,1.0]. Afin de produire du bruit Perlin dans cet intervalle, la valeur interpolée peut avoir besoin d'être mise à l'échelle par un facteur d'échelle.

Pseudo-code

modifier

Voici le pseudo-code de l'implémentation du bruit de Perlin dans un espace à deux dimensions.

 // Fonction lisse de l'intervalle [0.0, 1.0] vers lui-même
 function smoothstep(float w) {
     if (w <= 0.0) return 0.0;
     if (w >= 1.0) return 1.0;
     return w * w * (3.0 - 2.0 * w);
 }
 
 // Fonction d'interpolation lisse entre a0 et a1
 // Le poids w doit être dans l'intervalle [0.0, 1.0]
 function interpolate(float a0, float a1, float w) {
     return a0 + (a1 - a0) * smoothstep(w);
 }
 
 // Fonction de calcul du produit scalaire entre le vecteur de distance et le vecteur de gradient.
 function dotGridGradient(int ix, int iy, float x, float y) {
 
     // Vecteurs de gradient aux intersections de la grille (pré-calculés ou non)
     extern float Gradient[IYMAX][IXMAX][2];
 
     // Calcul du vecteur de distance
     float dx = x - (float)ix;
     float dy = y - (float)iy;
 
     // Calcul du produit scalaire
     return (dx*Gradient[iy][ix][0] + dy*Gradient[iy][ix][1]);
 }
 
 // Calcul du bruit de Perlin au point de coordonnées (x, y)
 function perlin(float x, float y) {
 
     // Coordonnées de la case de la grille dans laquelle se trouve le point
     int x0 = floor(x);
     int x1 = x0 + 1;
     int y0 = floor(y);
     int y1 = y0 + 1;
 
     // Poids pour l'interpolation
     // (On pourrait utiliser des polynômes d'ordre supérieur ou d'autres fonctions lisses)
     float sx = x - (float)x0;
     float sy = y - (float)y0;
 
     // Interpolation entre les coins de la case
     float n0, n1, ix0, ix1, value;
     n0 = dotGridGradient(x0, y0, x, y);
     n1 = dotGridGradient(x1, y0, x, y);
     ix0 = interpolate(n0, n1, sx);
     n0 = dotGridGradient(x0, y1, x, y);
     n1 = dotGridGradient(x1, y1, x, y);
     ix1 = interpolate(n0, n1, sx);
     value = interpolate(ix0, ix1, sy);
 
     return value;
 }

Annexes

modifier

Sur les autres projets Wikimedia :

Notes et références

modifier
  1. David Louapre, Le Labo du jeu vidéo, Paris, Albin Michel, coll. « Sciences », 2026, 432 p. (ISBN 978-2-226-49023-0), 3 – Algorithmes et comportements, chap. 13 (« Quand la machine rêve les mondes »), p. 176-184.
  2. (en) Ken Perlin, « History », sur www.noisemachine.com (consulté le 19 mai 2014).
  3. (en) Ken Perlin, « Controlled random primitive », sur www.noisemachine.com (consulté le 19 mai 2014).
  4. (en) Ken Perlin, « coherent noise function over 1, 2 or 3 dimensions », sur nyu.edu (consulté le 19 mai 2014).
    Code (en C) de la première version de la fonction, en 1983.
  5. (en) Ken Perlin, « Rapid adoption », sur www.noisemachine.com (consulté le 19 mai 2014).
  6. (en) Ken Perlin, « Noise and Turbulence », sur nyu.edu (consulté le 19 mai 2014).

Article connexe

modifier

Liens externes

modifier

📚 Artikel Terkait di Wikipedia

Fonction hyperbolique

intitulé « Hyperbolic functions » (voir la liste des auteurs). (en) George F. Becker et C. E. Van Orstrand, Hyperbolic Functions, The Smithsonian Institution

Redresseur (réseaux neuronaux)

En mathématiques, la fonction Unité Linéaire Rectifiée (ou ReLU pour Rectified Linear Unit) est définie pour tout réel x {\displaystyle x}  : ∀ x ∈ R

Paramilitaire

ligne), « Paramilitary » « Designating, of, or relating to a force or unit whose function and organization are analogous or ancillary to those of a professional

Unit.js

'); Unit.js s'intègre dans une suite de tests de type Behavior Driven Development describe('Hello world', function() { it('says hello', function() { var

Garmin G1000

typiquement de deux écrans, ou Garmin Display Unit (GDU), appelés Primary Flight Display (PFD) et Multi-Function Display (MFD) ainsi que d'un module de communication

Trait (programmation)

héritage multiple : trait Hello { public function sayHello() { echo 'Hello '; } } trait World { public function sayWorld() { echo ' World'; } } class MyHelloWorld

Test unitaire

Test. En programmation informatique, le test unitaire (ou TU, voire UT pour Unit Testing en anglais) est une procédure permettant de vérifier le bon fonctionnement

Maladie du cri du chat

« Delta-catenin is required for the maintenance of neural structure and function in mature cortex in vivo », Neuron, vol. 64, no 3,‎ 2009, p. 320-7. (PMID 19914181