Nei due post precedenti abbiamo sempre usato la funzione noise() in modo mono dimensionale. È arrivato il momento di fare un passo in avanti e aggiungere la seconda dimensione.

Ripasso: 1D Perlin Noise

Quando parliamo di Perlin Noise mono dimensionale dobbiamo immaginare i valori su una linea temporale orizzontale; quando noi chiediamo alla funzione di restituirci un determinato valore di noise, tale valore sarà correlato a quello precedente e a quello successivo. Nell’immagine viene rappresentato il valore di noise con parametro xOff pari a 3.32. Come nel post precedente, l’incremento che ho usato per generare l’immagine è 0.02.

Perlin Noise Monodimensionale

2D Perlin Noise

Quando aggiungiamo una dimensione, invece, dobbiamo pensare a una griglia i cui valori sono correlati tra loro sia sull’asse delle x che su quello delle y.

2D Perlin Noise

Come si evince dall’immagine, la situazione diventa più complicata perché se analizziamo singolarmente i punti centrali rosso o blu intuiamo facilmente la correlazione con i punti che li circondano. Se li consideriamo entrambi contemporaneamente, invece, notiamo subito come ci siano dei punti in comune che dovranno essere a loro volta correlati tra loro.

Questo è un esempio molto semplificato: provate a immaginare se ciascuno dei punti disegnati fosse un pixel!

Generiamo una texture

È arrivato il momento di sporcarsi le mani e scrivere un po’ di codice: lo scopo del programma di oggi è generare una texture con Processing utilizzando Perlin Noise bidimensionale.

Partiamo da un’analisi del risultato finale per capire tutti i passaggi e il codice che ci serve:

Texture generata con Perlin Noise bidimensionale

Per generare la texture dobbiamo prendere ciascun pixel della nostra finestra facendo in modo che il suo colore sia correlato ai pixel vicini: è facile notare come ci siano delle aree più scure e altre più chiare e che, in generale, la texture generata sia uniforme.

Per farvi capire la differenza, nell’immagine qui sotto ho sostituito nel programma la funzione noise() con random():

Random Texture Processing
Sostituendo la funzione noise() con random() il risultato è molto differente.

Per lavorare con i pixel utilizzeremo le funzioni loadPixels() updatePixels() che avremo modo di analizzare in modo approfondito in futuro. Per il momento vi basti sapere che la prima funzione carica tutti i pixel della finestra in un array chiamato pixels[] e che la seconda ricarica i pixel nella finestra dopo che sono stati modificati.

Un altro punto molto importante è sapere che, benché i pixel presenti in una finestra siano un insieme di righe e colonne, nell’array pixels[] vengono salvati con numero progressivo.

Per modificare il colore di ciascun pixel della finestra abbiamo bisogno di due cicli for annidati: uno per i valori di x, l’altro per quelli di y. La funzione noise() entra in gioco proprio in questa fase: attraverso due variabili – xOff e yOff – imposteremo il colore di ciascun pixel.

Ecco il codice finale:

/*
 * Texture con Perlin Noise 2D
 * by Federico Pepe
 *
 */

float increment = 0.015;

void setup() {
  size(500, 500);
}

void draw() {
  // Carico i pixel della finestra
  loadPixels();
  float xOff = 0;
  for(int x = 0; x < width; x++) {
    xOff += increment;
    float yOff = 0;
    for (int y = 0; y < height; y++) {
      yOff += increment;
      // Ottengo il valore noise passando le variabili xOff e yOff.
      float bright = noise(xOff, yOff) * 255;
      // Riassegno a ogni pixel il nuovo colore
      pixels[x+y*width] = color(bright);
    }
  }
  // Aggiorno tutti i pixel della finestra
  updatePixels();
}

Domanda: perché non ho inizializzato le due variabili xOff e yOff all'inizio del programma? Cosa succede se non reimposto a 0 la variabile yOff a ogni ciclo?

Per aggiungere l'interazione con l'utente, aggiungiamo subito dopo updatePixels() la seguente riga: increment = map(mouseX, 0, width, 0.1, 0.01);

In questo modo rimapperemo la posizione X del mouse che può andare da 0 alla larghezza della finestra in un nuovo range compreso tra 0.1 e 0.01.

Unisciti alla discussione

1 commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.