Catégories
code créativité

Comment faire une boucle avec un bruit de Perlin

Dans cet article, je vais t’expliquer ce qu’est un bruit de Perlin, Ă  quoi il sert et comment rĂ©ussir Ă  faire une boucle sur un bruit de Perlin. Je te montrerai comment le faire avec la librairie Three.js. et p5.js

Pour faire nos boucles de bruit de Perlin, je te propose d’Ă©couter ce mix de (+)earth

Je me suis trÚs largement inspiré de cet article pour comprendre et écrire mon article.

Qu’est-ce qu’un bruit de Perlin

Avant de plonger dans la crĂ©ation de boucles, il est important de comprendre ce qu’est le bruit de Perlin. DĂ©veloppĂ© par Ken Perlin en 1983, c’est une fonction de bruit qui gĂ©nĂšre des textures lisses et naturelles. Il est souvent utilisĂ© pour crĂ©er des paysages, des nuages, des textures et d’autres Ă©lĂ©ments visuels qui nĂ©cessitent un aspect organique.

Voici une Ɠuvre dans laquelle je suppose que l’artiste Ock1tess a utilisĂ©e des bruits de Perlin :

exemple d'utilisation d'un bruit de Perlin : ☁ clouds ☁ || rainbow special edition par Ock1tess
☁ clouds ☁ || rainbow special edition par Ock1tess

Comment utiliser un bruit de Perlin

Pour crĂ©er une boucle avec un bruit de Perlin, tu auras besoin d’un langage de programmation et d’une bibliothĂšque supportant cette fonctionnalitĂ©. Des langages populaires incluent Python, JavaScript et C++. Il existe Ă©galement des bibliothĂšques spĂ©cifiques, comme p5.js, qui simplifient grandement le travail avec le bruit de Perlin.

Des logiciels comme Blender permettent aussi d’utiliser et de gĂ©nĂ©rer du bruit de Perlin comme l’indique cette doc. On y dĂ©couvre que Blender gĂšre d’ailleurs le bruit en 4D et au-delĂ  en contrepartie d’un temps de rendu plus long.

La fonction noise intégrée dans p5.js gÚre un bruit en 3D, mais pas au-delà. Pour aller en 4D et pouvoir ajouter le temps pour faire notre boucle, il faut utiliser une lib externe.

Comment boucler un bruit de Perlin, théorie en image

La thĂ©orie pour boucler un bruit de Perlin c’est de passer le bruit dans un cercle en utilisant de coordonnĂ©es polaires. Alors lĂ , je rĂ©pĂšte ce que j’ai lu, car je suis loin d’ĂȘtre un mathĂ©maticien… En tout cas en regardant le GIF suivant, j’espĂšre que tu comprendras le principe.

visualisation d'une boucle de bruit de perlin

Ajouté à cela, il faut aussi savoir que la fonction de noise de p5.js se lance avec une graine (seed) à chaque chargement du script. On peut si on veut imposer une graine. La fonction renvoie ensuite des valeurs entre 0 et 1 centrées sur 0.5.

Un autre article intĂ©ressant pour comprendre la gĂ©nĂ©ration de nombre alĂ©atoire est ce billet de blog de l’artiste anglaise Amy Goodchild, dans lequel elle explique ce qu’est la gĂ©nĂ©ration de nombres pseudo alĂ©atoires.

PrĂ©parer l’environnement de travail : l’extension p5.vscode

Pour quelqu’un d’habituĂ© Ă  la complĂ©tion, utiliser processing (version java) dans l’environnement proposĂ©, c’est un peu revenir en arriĂšre. Il faut apprendre l’api, connaĂźtre les paramĂštres, constamment, avoir une page de doc ouverte, car l’outil ne donne pas de complĂ©tion et pour dĂ©boguer, je n’en parle pas… Cela ne me plaisait pas. Je suis donc passĂ© sur p5.js sa version JavaScript. J’ai d’abord voulu utiliser le module JavaScript via npm i p5 mais lĂ  aussi, ce n’Ă©tait pas du tout pratique de l’adapter pour l’utiliser dans d’autres projets. Pour faire vite, pour l’utiliser vraiment en mode module, il faut tout prĂ©fixer par p5 et donc les codes qu’on trouve sur le net ne sont pas utilisables tel quel.

Bref, pour utiliser p5.js facilement et dans le confort, j’ai installĂ© l’extension p5.vscode. Elle permet de :

  • crĂ©er un projet p5 : Ctrl + P puis taper p5 > crĂ©er
  • avoir la complĂ©tion (configurĂ©e dans jsconfig.json)
  • lancer un server html > via le bouton en bas Ă  droit de la fenĂȘtre VSCode > Go Live

Et c’est franchement beaucoup plus sympa et confort de coder dans ces conditions.

L’extension :

extension vscode p5.vscode par Sam Lavigne

Le bouton Go Live qui lance un serveur local, hyper pratique 🙂

bouton Go Live de l'extension p5.vscode pour lancer un serveur local

Créer le sketch de bruit de perlin

Maintenant qu’on a un environnement sain et agrĂ©able pour travailler, on peut coder.

Pour faire le premier gif de prĂ©sentation de la technique (oĂč on voit un rond qui parcourt une courbe de bruit de Perlin), j’ai testĂ© le code fourni par Jesse Andrews (son adaptation p5.js du code Processing de Golan Levin). J’ai activĂ© (dĂ©commentĂ©) l’enregistrement d’images, mais comme on est dans un navigateur, il fallait valider l’enregistrement de chaque image… Ce qui n’est franchement pas gĂ©nial quand on sait qu’on va devoir enregistrer 150 images et qu’en plus aprĂšs il nous faudra lancer une commande pour gĂ©nĂ©rer un gif.

C’est lĂ  que p5.capture arrive Ă  la rescousse ! Il va tout nous faire dans le navigateur et on n’aura qu’un seul fichier Ă  sauver Ă  la fin 🙂 Ouf, on se sauvegarde un peu de temps et on mĂ©nage notre taux de clic.

On peut aussi utiliser ccapture, une autre librairie d’enregistrement du canva.

Fabriquer le gif

Télécharger gisicle

DĂ©zipper puis mettre le rĂ©pertoire oĂč tu as l’habitude de mettre tes outils de ce genre, les outils sans installeur windows.

VoilĂ  ce que j’ai fait sur windows : copier-coller le rĂ©pertoire dans c:/Dev/Tools, puis j’ai ajoutĂ© C:\Dev\Tools\gifsicle-1.92 au Path

PATH=%PATH%;C:/nouveau/chemin;

commande gifsicle pour convertir en gif tout un rĂ©pertoire d’image, la commande suivante est lancĂ©e depuis le rĂ©pertoire qui contient les images (cd c:/chemin/mon-rep-avec-mes-images)

gifsicle --delay=2 --loop --optimize *.gif > perlin-1.gif

on peut aussi faire le gif avec ffmpeg, (je n’ai pas rĂ©ussi Ă  donner des gif Ă  ffmpeg donc il faut lui donner des png)

ffmpeg -f image2 -framerate 25 -i fr%03d.png -loop 0 perlin-4.gif

Comme j’avais des pb de couleur, j’ai demandĂ© Ă  ChatGPT de me trouver une solution et voici sa rĂ©ponse :

ffmpeg -f image2 -framerate 25 -i ./simplex-21-2/%07d.png -vf "fps=25,palettegen" -y palette.png
ffmpeg -f image2 -framerate 25 -i ./simplex-21-2/%07d.png -i palette.png -filter_complex "fps=25,paletteuse" -loop 0 perlin-21-2.gif

Et pour l’explication : le format gif n’a qu’une palette de 256 couleurs, on crĂ©e donc une palette Ă  partir des images dans la premiĂšre commade puis on l’utilise dans la deuxiĂšme. Le rĂ©sultat est vraiment trĂšs bien, au dĂ©but, je n’avais quasiment pas de couleur.

Le fichier de dĂ©part faisait 24 Mo, donc je l’ai ensuite compressĂ© avec ce service en ligne : https://www.iloveimg.com/fr/compresser-image/compresser-gif

Mes images Ă©taient trop grosses, car il doit y avoir un bug dans CCapture et il multiplie par 2 la taille des images par rapport Ă  la taille du canva, rĂ©sultat avec un canva de 500×500 je me retrouvais avec des images de 1000×1000 et donc des gros GIF. Je ne m’en suis aperçu qu’au moment d’uploader mon GIF pour cet article.

Pour rattraper le coup, j’ai retaillĂ© les images avec imagemagick, (si tu n’as pas cet outil, je te conseille de l’installer) de cette façon :

 magick mogrify -resize 500x500 perlin-16-50/*.png

J’ai retaillĂ© tous les PNG du rĂ©pertoire perlin-16-50 pour qu’elles fassent 500×500.

Puis, j’ai relancĂ© ma commande de crĂ©ation de GIF (la commande simple pour les GIF pour lesquels je n’avais pas besoin de crĂ©er de palette, cf. plus haut).

ffmpeg -f image2 -framerate 25 -i perlin-14-50/%07d.png -loop 0 perlin-14-50.gif

J’ai ainsi divisĂ© par presque 10 la taille de mes gifs 🙂

Amélioration du programme

Finalement, aprĂšs une bonne nuit de sommeil, j’ai revu mon code, j’ai intĂ©grĂ© P5Capture trĂšs rapidement et maintenant le code lance l’animation et enregistre la premiĂšre boucle dans un GIF. Plus besoin de s’embĂȘter Ă  retailler les PNG et Ă  lancer la commande de gĂ©nĂ©ration de GIF ! 🙂

Voici le code :

P5Capture.setDefaultOptions({
  format: "gif",
  framerate: 60,
  quality: 0.5,
  width: 500,
});

const totalFrames = 360;
let counter = 0;

// function ease(p) {
//   return 3 * p * p - 2 * p * p * p;
// }

function ease(p, g) {
  if (p < 0.5)
    return 0.5 * Math.pow(2 * p, g);
  else
    return 1 - 0.5 * Math.pow(2 * (1 - p), g);
}

let record = true
let recorded = false

let N = 75;
let n = 100;
let l = 250;
let scl = 0.01;
let r = 0.5;
let noise;

function setup() {
  createCanvas(500, 500);
  noise = new OpenSimplexNoise();
  colorMode(HSB, 360, 100, 100);
  frameRate(50)
}

function draw() {
  let percent = float(counter % totalFrames) / totalFrames;

  background(0);
  noStroke();
  strokeWeight(0.1);
  

  for (let i = 0; i < N; i++) {
    let y = map(i, 0, N - 1, 0, height);
    let widthPercentage = map(i, 0, N - 1, 60, 90) / 100;

    let hue = map(i, 0, N - 1, 180, 330);
    stroke(hue, 100, 100);

    
    beginShape();
    for (let j = 0; j < n; j++) {
      
      let x = map(j, 0, n - 1, width * (1 - widthPercentage) / 2, width * (1 + widthPercentage) / 2);

      let n2 = noise.noise3D(100 * y + scl * x, 10 + r * cos(TWO_PI * (j / n) + 0.05 * i + percent * TWO_PI), 10 + r * sin(TWO_PI * (j / n) + 0.05 * i + percent * TWO_PI))
      strokeWeight(map(n2, -1, 1, 0, 5.7));

      let intensity = ease(constrain(map(dist(x, y, width / 2, height / 2), 0, 0.5 * width, 1, 0), 0, 1), 2.0);
      let yy = y + intensity * l * n2;
      vertex(x, yy);
    }
    endShape();
  }

  // enregistrement P5Capture
  if(frameCount < totalFrames && !recorded) {
    const capture = P5Capture.getInstance();
    capture.start({
      format: "gif",
      duration: 360,
      frameRate: 60,
    });
  }
  if(frameCount >= totalFrames) {
    recorded = true
  }


  counter++;
}

et le code HTML :

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Sketch</title>

    <link rel="stylesheet" type="text/css" href="style.css">
    <script src="libraries/p5.min.js"></script>    
    <script src="libraries/OpenSimplexNoise.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/p5.capture.umd.min.js"></script>
    <script src="sketch.js"></script>
  </head>

  <body>
  </body>
</html>

Quelques GIFs rĂ©alisĂ©s pour la crĂ©ation de l’article :

Pour terminer, je me suis amusĂ© Ă  demander Ă  Midjourney quelle Ă©tait sa vision d’un bruit de Perlin et j’ai eu des rĂ©sultats trĂšs intĂ©ressants, pistes pour des programmes d’art gĂ©nĂ©ratif :

Avec le prompt :

photographie rĂ©aliste d'un codeur:: crĂ©atif qui diffuse du bruit de perlin sur une Ɠuvre digitale abstraite qui flotte dans un cube en verre, dans le style de jeff wall --v 5 --no fluide

À bientît !

Tu as ❀ aimĂ© l'article ?

J'ai créé un guide pour te lancer rapidement dans le crypto art.

Tu y découvriras :

  • La blockchain
  • Les NFTs
  • L'installation d'un wallet crypto
  • La frappe et la vente ton premier NFT
Si tu as aimé l'article, tu es libre de le partager ;)

Par François

J'ai créé le blog L'Artiste Crypto dans le but d'aider les artistes amateurs comme moi à se professionnaliser. Je souhaite apporter de l'inspiration en documentant la poursuite d'un objectif : devenir crypto artiste et réussir sur le Web3. A travers des articles, des vidéos et des interviews j'espÚre y parvenir et te faciliter la tùche.

Une réponse sur « Comment faire une boucle avec un bruit de Perlin »

Laisser un commentaire