Merge branch 'master' into gallery

This commit is contained in:
kynd 2016-11-06 12:25:38 +09:00
commit 1f11baaf36
56 changed files with 1792 additions and 175 deletions

View File

@ -41,7 +41,7 @@ Alternativamente, dependiendo cuales sean tus necesidades puedes:
- [Crear una versión offline del libro](https://thebookofshaders.com/appendix/)
- [Correr los ejemplos en una RaspberryPI sin un navegador](https://thebookofshaders.com/appendix/)
- [Correr los ejemplos en una Raspberry Pi sin un navegador](https://thebookofshaders.com/appendix/)
- [Crear un PDF del libro para imprimir.](https://thebookofshaders.com/appendix/)

View File

@ -52,7 +52,7 @@ Cela étant et selon ce que vous voulez faire de ce livre, vous pouvez :
- [créer une copie locale de ce livre pour le consulter hors-ligne](https://thebookofshaders.com/appendix/)
- [lancer les exemples directement sur RaspberryPi, sans navigateur](https://thebookofshaders.com/appendix/)
- [lancer les exemples directement sur Raspberry Pi, sans navigateur](https://thebookofshaders.com/appendix/)
- [créer un PDF du livre pour l'imprimer](https://thebookofshaders.com/appendix/)

View File

@ -48,7 +48,7 @@ Chrome、FirefoxやSafariなどWebGLの使える今時のブラウザーとイ
- [Make an off-line version of this book](https://thebookofshaders.com/appendix/)
- [Run the examples on a RaspberryPi without a browser](https://thebookofshaders.com/appendix/)
- [Run the examples on a Raspberry Pi without a browser](https://thebookofshaders.com/appendix/)
- [Make a PDF of the book to print](https://thebookofshaders.com/appendix/)

View File

@ -40,7 +40,7 @@ Fragment shader는 매우 빠른 속도로 스크린에 렌더되는 픽셀들
- [이책의 오프라인 버젼](https://thebookofshaders.com/appendix/)
- [RaspberryPi에서 브라우져 없이 예제들 돌리기](https://thebookofshaders.com/appendix/)
- [Raspberry Pi에서 브라우져 없이 예제들 돌리기](https://thebookofshaders.com/appendix/)
- [이책의 PDF버젼 만들기](https://thebookofshaders.com/appendix/)

View File

@ -40,7 +40,7 @@ Alternatively, based on what you have or what you need from this book you can:
- [Make an off-line version of this book](https://thebookofshaders.com/appendix/)
- [Run the examples on a RaspberryPi without a browser](https://thebookofshaders.com/appendix/)
- [Run the examples on a Raspberry Pi without a browser](https://thebookofshaders.com/appendix/)
- [Make a PDF of the book to print](https://thebookofshaders.com/appendix/)

54
02/README-it.md Normal file
View File

@ -0,0 +1,54 @@
## Ciao Mondo
Di solito l'esempio "Ciao Mondo!" è il primo passo per imparare un nuovo linguaggio. Si tratta di un semplice programma di una riga che visualizza un messaggio entusiastico di benvenuto.
Nel mondo GPU rendere un testo è un esercizio troppo complicato per un primo passo, perciò sceglieremo un colore brillante di benvenuto per mostrare il nostro entusiasmo!
<div class="codeAndCanvas" data="hello_world.frag"></div>
Se stai leggendo questo libro in un navigatore, noterai che il precedente blocco di codice è interattivo. Ciò significa che è possibile fare click e modificare qualsiasi parte del codice per capire come funziona. Le modifiche verranno aggiornate immediatamente grazie all'architettura GPU che compila e sostituisce gli shaders *al volo*. Prova per esempio a cambiare i valori della linea 6.
Anche se queste semplici righe di codice non sembrano essere molto importanti, possiamo trarre molte informazioni:
1. Gli Shaders hanno una unica funzione ```main``` che alla fine restituisce un colore. Questa caratteristica è molto simile al linguaggio C.
2. Il colore finale dei pixel viene assegnato a una variabile globale riservata ```gl_FragColor```.
3. Questo linguaggio è simile al C e ha *variabili* built-in (come ```gl_FragColor```), *funzioni* e *tipi*. In questo esempio abbiamo introdotto ```vec4``` che è un vettore a virgola mobile(float) di quattro dimensioni. Più avanti incontreremo altri tipi come ```vec3``` e ```vec2``` insieme ai più popolari: ```float```, ```int``` e ```bool```.
4. Se analizziamo il tipo ```vec4``` possiamo dedurre che i quattro argomenti corrispondono ai canali ROSSO, VERDE, BLU e ALFA. Inoltre possiamo notare che questi valori sono *normalizzati*, il che significa che vanno da ```0.0``` a ```1.0```. In seguito, impareremo che normalizzare i valori rendere più facile *mapparli* fra le variabili.
5. Un'altra importante *caratteristica del C* che si può vedere in questo esempio è la presenza di macro del preprocessore. Le macro sono parte di una fase di pre-compilazione. Con loro è possibile ```#define``` variabili globali e fare alcune funzioni condizionali di base (con ```#ifdef``` e ```#endif```). Tutti i comandi macro iniziano con un hashtag (```#```). La pre-compilazione avviene appena prima di compilare lo shader e copia tutte le chiamate a ```#defines``` e verifica ```#ifdef``` (è definito) e ```#ifndef``` (non è definito) nel caso di chiamate condizionali . Nel nostro esempio precedente "Ciao mondo!", abbiamo inserito solo la linea 2 per verificare se ```GL_ES``` è definito, chiamata che avviene soprattutto quando il codice viene compilato su dispositivi mobili e browser.
6. I tipi float sono vitali negli shader, dove il livello di *precisione* è fondamentale. Precisione inferiore significa resa più veloce, ma a scapito della qualità. Si può essere pignoli e specificare la precisione di ogni variabile che utilizza la virgola mobile. Nella prima riga (```precision mediump float;```) stiamo definendo tutti i float a media precisione. Ma possiamo impostare la loro precisione a un livello basso (```precision lowp float;```) o alto (```precision highp float;```).
7. L'ultimo, e forse più importante, dettaglio è che le specifiche GLSL non garantiscono che le variabili siano convertite automaticamente. Cosa significa? I produttori delle carte grafiche hanno differenti approcci per accelerare i processi delle carte grafiche, ma sono costretti a garantire delle specifiche minime. La conversione automatica non è una di queste. Nel nostro esempio "Ciao mondo", ```vec4``` ha precisione in virgola mobile e per questo ci si aspetta dei ```floats```. Se si vuole realizzare un codice omogeneo e non passare ore a fare il debug di schermi bianchi, abituatevi a mettere il punto ( ```.``` ) all'interno dei vostri float. Questo tipo di codice non funziona sempre:
```glsl
void main() {
gl_FragColor = vec4(1,0,0,1); // ERRORE
}
```
Ora che abbiamo descritto gli elementi più rilevanti del nostro programma "ciao mondo!", è il momento di cliccare sul blocco di codice e iniziare a mettere alla prova tutto quello che abbiamo imparato. Noterete che in caso di errore, il programma non sarà in grado di compilare e mostrerà uno schermo bianco. Ci sono alcune cose interessanti da provare, per esempio:
* Provate a sostituire i float con degli integer, la vostra scheda grafica potrebbe o non accettare questo comportamento.
* Commentate la linea 6 e non assegnate alcun valore ai pixel della funzione.
* Provate a fare una funzione separata che restituisce un colore specifico e utilizzarla all'interno del ```main()```. Piccolo suggerimento, ecco il codice per una funzione che restituisce un colore rosso:
```glsl
vec4 red(){
return vec4(1.0,0.0,0.0,1.0);
}
```
* Ci sono diversi modi per costruire dei tipi ```vec4```, prova a scoprire gli altri modi. Per esempio:
```glsl
vec4 color = vec4(vec3(1.0,0.0,1.0),1.0);
```
Anche se questo esempio non è molto eccitante, è il più elementare possibile - stiamo cambiando tutti i pixel all'interno del canvas con il medesimo colore. Nel prossimo capitolo vedremo come cambiare i colori dei pixel utilizzando due tipi di input: spazio (cioè la posizione dei pixel sullo schermo) e il tempo (cioè il numero di secondi da quando la pagina è stata caricata).

61
03/README-it.md Normal file
View File

@ -0,0 +1,61 @@
## Uniforms
Finora abbiamo visto come la GPU gestisce un gran numero di thread paralleli, ciascuno responsabile nell'assegnazione d'un colore ad una frazione dell'immagine totale. Sebbene ogni thread parallelo è cieco nei confronti degli altri, dobbiamo essere in grado d'inviare alcuni input dalla CPU a tutti i thread. A causa dell'architettura della scheda grafica tali input saranno uguali (*uniform*) per tutti i thread e necessariamente impostati come di *sola lettura*. In altre parole, ogni thread riceve gli stessi dati che possono essere letti ma non possono essere cambiati.
Questi input sono chiamati ```uniform``` e sono disponibili nella maggior parte di tipi supportati: ```float```, ```vec2```, ```vec3```, ```vec4```, ```mat2```, ```mat3```, ```mat4```, ```sampler2D``` e ```samplerCube```. Gli Uniforms sono definiti con i rispettivi tipi, all'inizio del codice, dopo aver definito la precisione della virgola mobile.
```glsl
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution; // dimensione del Canvas (larghezza, altezza)
uniform vec2 u_mouse; // posizione del mouse (x,y) in pixels
uniform float u_time; // tempo in secondi da quando lo shader è iniziato
```
È possibile immaginare gli uniforms come piccoli ponti tra la CPU e la GPU. I nomi variano da applicazione ad applicazione, ma in questa serie di esempi userò: ```u_time``` (tempo in secondi da quando lo shader è iniziato), ```u_resolution``` (la dimensione della finestra in cui lo shader è in corso d'elaborazione) e ```u_mouse``` (la posizione in pixel del mouse all'interno della finestra). Seguirò la convenzione di mettere ```u_``` prima del nome degli uniforms per essere espliciti sulla natura di questa variabile, ma incontrerete varie nomenclature per gli uniforms. Per esempio [ShaderToy.com](https://www.shadertoy.com/) utilizza gli stessi uniforms, ma con i seguenti nomi:
```glsl
uniform vec3 iResolution; // dimensione del Canvas (in pixels)
uniform vec4 iMouse; // posizione del mouse in pixels. xy: corrente, zw: click
uniform float iGlobalTime; // tempo (in secondi) da quando lo shader è iniziato
```
Ma ora basta chiacchiere, vediamo gli uniforms in azione. Nel seguente codice utilizziamo ```u_time``` - il numero di secondi da quando lo shader è iniziato - insieme ad una funzione seno per animare con una transizione la quantità di rosso sullo schermo.
<div class="codeAndCanvas" data="time.frag"></div>
Come potete vedere GLSL ha molte sorprese. La GPU ha funzioni trigonometriche ed esponenziali, che sono accelerate dall'hardware. Alcune di queste funzioni sono: [```sin()```](../glossary/?search=sin), [```cos()```](../glossary/?search=cos), [```tan()```](../glossary/?search=tan), [```asin()```](../glossary/?search=asin), [```acos()```](../glossary/?search=acos), [```atan()```](../glossary/?search=atan), [```pow()```](../glossary/?search=pow), [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log), [```sqrt()```](../glossary/?search=sqrt), [```abs()```](../glossary/?search=abs), [```sign()```](../glossary/?search=sign), [```floor()```](../glossary/?search=floor), [```ceil()```](../glossary/?search=ceil), [```fract()```](../glossary/?search=fract), [```mod()```](../glossary/?search=mod), [```min()```](../glossary/?search=min), [```max()```](../glossary/?search=max) and [```clamp()```](../glossary/?search=clamp).
Ora è il momento di giocare con il codice qui sopra.
* Rallentate la frequenza fino a quando il cambiamento di colore diventa quasi impercettibile.
* Aumentate la frequenza fino a vedere un solo colore, senza sfarfallio.
* Date tre frequenze differenti ai tre canali (RGB) per ottenere motivi e comportamenti interessanti.
## gl_FragCoord
Allo stesso modo GLSL ci dà un output di default, ```vec4 gl_FragColor```, ma anche un input di default, ```vec4 gl_FragCoord```, che contiene le coordinate sullo schermo del *pixel* o del *screen fragment* del thread attivo. Con ```vec4 gl_FragCoord```, sappiamo dove un thread sta lavorando all'interno dello schermo. In questo caso la variabile non è un ```uniform``` perché sarà diversa da thread a thread. Le variabili che cambiano in ogni thread, come ```gl_FragCoord```, sono chiamate *varying*.
<div class="codeAndCanvas" data="space.frag"></div>
Nel codice qui sopra *normalizziamo* le coordinate del fragment dividendole per la risoluzione totale dello schermo. In questo modo i valori andranno tra ```0.0``` e ```1.0```, una tecnica che rende facile mappare i valori X e Y per i canali ROSSO e VERDE.
Nel mondo degli shaders non abbiamo troppe risorse per il debug a parte l'assegnazione di colori intensi alle variabili e cercare di trovargli un senso. Scoprirete che a volte programmando in GLSL è come mettere una nave all'interno di una bottiglia: un processo difficile, bello e gratificante.
![](08.png)
Ora è il momento di mettere in pratica gli insegnamenti che abbiamo imparato.
* Sapreste dire dove è la coordinata ```(0.0,0.0)``` sul nostro schermo?
* E dove sono ```(1.0,0.0)```, ```(0.0,1.0)```, ```(0.5,0.5)``` e ```(1.0,1.0)```?
* Riuscite ad immaginare come usare ```u_mouse``` sapendo che i valori sono espressi in pixel e NON in valori normalizzati? Sapresti usare ```u_mouse``` per muovere i colori?
* Sapreste trovare un modo interessante per cambiare questo pattern grafico utilizzando ```u_time``` e le coordinate ```u_mouse```?
Dopo aver fatto questi esercizi, ci si potrebbe chiedere dove si potrebbero provare i nuovi super poteri che gli shader ci hanno dato. Nel prossimo capitolo vedremo come creare i vostri shader in Three.js, Processing e openFrameworks.

View File

@ -2,7 +2,7 @@
En este punto seguro estás entusiasmado con poder probar shaders en las plataformas en las que te sientes cómodo. En los siguientes ejemplos veremos como agregarlos el algunos frameworks populares con las mismas uniforms con las que estamos trabajando en este libro. (En el [repositorio de GitHub de este capítulo](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04) encontrarás el código completo de estos ejemplos.)
**Nota 1**: En caso de que no quieras utilizar los shaders en los siguientes frameworks pero quieras hacerlo fuera del navegador, puedes descargar y compilar [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). Este programa corre en MacOS y en RaspberryPI, permite ejecutar directamente los ejemplos desde la terminal.
**Nota 1**: En caso de que no quieras utilizar los shaders en los siguientes frameworks pero quieras hacerlo fuera del navegador, puedes descargar y compilar [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). Este programa corre en MacOS y en Raspberry Pi, permite ejecutar directamente los ejemplos desde la terminal.
**Nota 2**: Si no quieres usar WebGl con tus shaders y no te interesan los frameworks siguientes, puedes usar [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas). Esta herramienta fue diseñada para este libro, pero se volvió tan útil que he terminado usándola en muchos proyectos.

View File

@ -1,7 +1,7 @@
## exécuter vos shaders
Pour les besoins de ce livre comme pour ma pratique artistique, j'ai créé un écosystème d'outils permettant de créer, d'afficher, de partager et d'organiser mes shaders.
Ces outils fonctionnent de la même manière sur Linux Desktop, MacOS, [RaspberryPi](https://www.raspberrypi.org/) et dans les navigateurs sans avoir besoin d'altérer le code.
Ces outils fonctionnent de la même manière sur Linux Desktop, MacOS, [Raspberry Pi](https://www.raspberrypi.org/) et dans les navigateurs sans avoir besoin d'altérer le code.
**Affichage**: tous les exemples de ce livre sont affichés dans la page grâce à [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) qui facilite grandement la fabrication et l'affichage de shaders autonomes.
@ -14,7 +14,7 @@ Pour en savoir plus, [vous pouvez lire ceci](https://github.com/patriciogonzalez
Si vous êtes comme moi, vous aurez sans doute envie de lancer vos shaders en lignes de commandes, dans ce cas vous devriez regarder [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer).
Cette application permet d'incorporer un shader dans un script ```bash``` ou un pipeline Unix et de l'utiliser comme [ImageMagick](http://www.imagemagick.org/script/index.php).
[glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) est aussi un bon moyen de compiler vos shaders sur un [RaspberryPi](https://www.raspberrypi.org/) et c'est la raison pour laquelle [openFrame.io](http://openframe.io/) l'utilise pour afficher les oeuvres.
[glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) est aussi un bon moyen de compiler vos shaders sur un [Raspberry Pi](https://www.raspberrypi.org/) et c'est la raison pour laquelle [openFrame.io](http://openframe.io/) l'utilise pour afficher les oeuvres.
Pour en savoir plus, [cliquez ici](https://github.com/patriciogonzalezvivo/glslViewer).
```bash

190
04/README-it.md Normal file
View File

@ -0,0 +1,190 @@
## Eseguite il vostro shader
Nell'ambito della realizzazione di questo libro e della mia pratica artistica ho creato un ecosistema di strumenti per creare, visualizzare, condividere e curare gli shaders. Questo strumento funziona in modo coerente su Linux Desktop, MacOS, [Raspberry Pi](https://www.raspberrypi.org/) e browser, senza la necessità di dover cambiare il vostro codice.
**Visualizzare**: tutti gli esempi di questo libro vengono visualizzati utilizzando [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) che rende il processo di esecuzione dello shader standalone incredibilmente facile.
```html
<canvas class="glslCanvas" data-fragment-url=“yourShader.frag" data-textures=“yourInputImage.png” width="500" height="500"></canvas>
```
Come potete vedere, è solo necessario l'elemento ```canvas``` con l'attributo ```class="glslCanvas"``` e l'indirizzo verso il vostro shader nel ```data-fragment-url```. Scoprite di più a proposito [cliccando qui](https://github.com/patriciogonzalezvivo/glslCanvas).
Se siete come me, probabilmente vorrete eseguire gli shader direttamente dalla console. In questo caso date un'occhiata a [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). Questa applicazione consente d'incorporare gli shader nel vostro script ```bash``` o pipelines UNIX e d?utilizzarli in modo simile a [ImageMagick](http://www.imagemagick.org/script/index.php). Anche [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) è un ottimo modo per compilare gli shader sul [Raspberry Pi](https://www.raspberrypi.org/), motivo per il quale [openFrame.io](http://openframe.io/) lo usa per visualizzare le opere d'arte di tipo shader. Potete trovare ulteriori informazioni su questa applicazione [cliccando qui](https://github.com/patriciogonzalezvivo/glslViewer).
```bash
glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -s 1 -o yourOutputImage.png
```
**Creare**: per migliorare la programmazione degli shader, ho realizzato un editor online chiamato [glslEditor](https://github.com/patriciogonzalezvivo/glslEditor). Questo editor è integrato agli esempi del libro e mette a disposizione una serie di comodi widget per rendere più tangibile il codice astratto GLSL. È anche possibile eseguirlo come un'applicazione standalone web da [editor.thebookofshaders.com/](http://editor.thebookofshaders.com/). Scoprite di più a proposito [cliccando qui](https://github.com/patriciogonzalezvivo/glslEditor).
![](glslEditor-01.gif)
Se si preferisce lavorare offline utilizzando [SublimeText](https://www.sublimetext.com/) è possibile installare questo [pacchetto per glslViewer](https://packagecontrol.io/packages/glslViewer). Scoprite di più [cliccando qui](https://github.com/patriciogonzalezvivo/sublime-glslViewer).
![](glslViewer.gif)
**Condividere**: l'editor online ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) può condividere i tuoi shader! Sia la versione standalone che quella integrata hanno un pulsante per esportare con il quale è possibile ottenere un URL unico verso il vostro shader. Avete anche la possibilità d'esportare direttamente verso un [openFrame.io](http://openframe.io/).
![](glslEditor-00.gif)
**Curare**: Condividere il vostro codice è la prima tappa per intendere il vostro shader come un'opera d'arte! Accanto alla possibilità di esportare verso [openFrame.io](http://openframe.io/) ho fatto uno strumento per curare i vostri shader in una galleria che può essere integrata su qualsiasi sito, il suo nome è [glslGallery](https://github.com/patriciogonzalezvivo/glslGallery). Per saperne di più [cliccando qui](https://github.com/patriciogonzalezvivo/glslGallery).
![](glslGallery.gif)
## Eseguire i vostri shader nel vostro framework preferito
Nel caso in cui si dispone già di esperienze di programmazione in framework quali: [Processing](https://processing.org/), [Three.js](http://threejs.org/) o [OpenFrameworks](http://openframeworks.cc/), probabilmente sarete ansiosi di provare gli shader sulle piattaforme su cui vi trovate bene. I seguenti sono esempi di come impostare gli shader in alcuni dei framework più popolari con le stesse uniforms che andremo ad utilizzare in questo libro. (Nella [repository GitHub per questo capitolo](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04), troverete il codice sorgente completo per questi tre framework.)
### In **Three.js**
Il brillante e molto umile Ricardo Cabello (aka [MrDoob](https://twitter.com/mrdoob)) ha sviluppato insieme ad altri [collaboratori](https://github.com/mrdoob/three.js/graphs/contributors), probabilmente uno dei più famosi framework per WebGL, chiamato [Three.js](http://threejs.org/). Troverete un sacco di esempi, tutorial e libri che vi insegneranno come utilizzare questa libreria JavaScript per fare grafica 3D.
Di seguito è riportato un esempio di codice HTML e JS per iniziare con gli shader in three.js. Prestate attenzione allo script ```id="fragmentShader"```, qui è dove è possibile copiare gli shader che si trovano in questo libro.
```html
<body>
<div id="container"></div>
<script src="js/three.min.js"></script>
<script id="vertexShader" type="x-shader/x-vertex">
void main() {
gl_Position = vec4( position, 1.0 );
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec2 u_resolution;
uniform float u_time;
void main() {
vec2 st = gl_FragCoord.xy/u_resolution.xy;
gl_FragColor=vec4(st.x,st.y,0.0,1.0);
}
</script>
<script>
var container;
var camera, scene, renderer;
var uniforms;
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
var geometry = new THREE.PlaneBufferGeometry( 2, 2 );
uniforms = {
u_time: { type: "f", value: 1.0 },
u_resolution: { type: "v2", value: new THREE.Vector2() },
u_mouse: { type: "v2", value: new THREE.Vector2() }
};
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
document.onmousemove = function(e){
uniforms.u_mouse.value.x = e.pageX
uniforms.u_mouse.value.y = e.pageY
}
}
function onWindowResize( event ) {
renderer.setSize( window.innerWidth, window.innerHeight );
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
uniforms.u_time.value += 0.05;
renderer.render( scene, camera );
}
</script>
</body>
```
### In **Processing**
Iniziato da [Ben Fry](http://benfry.com/) e [Casey Reas](http://reas.com/) nel 2001, [Processing](https://processing.org/) è un framework straordinariamente semplice e potente in cui muovere i primi passi nel codice (o almeno lo è stato per me). [Andres Colubri](https://codeanticode.wordpress.com/) ha fatto importanti aggiornamenti a openGL e la gestione video in Processing, rendendo più facile che mai usare e giocare con i GLSL shader. Processing cercherà lo shader chiamato ```"shader.frag"``` nella cartella ```data``` dello sketch. Assicuratevi di copiare gli esempi che trovate qui in quella cartella e rinominate il file.
```cpp
PShader shader;
void setup() {
size(640, 360, P2D);
noStroke();
shader = loadShader("shader.frag");
}
void draw() {
shader.set("u_resolution", float(width), float(height));
shader.set("u_mouse", float(mouseX), float(mouseY));
shader.set("u_time", millis() / 1000.0);
shader(shader);
rect(0,0,width,height);
}
```
Affinché lo shader lavori su versioni precedenti alla 2.1, è necessario aggiungere la seguente riga all'inizio del vostro Shader: ```#define PROCESSING_COLOR_SHADER```. In questo modo dovrebbe assomigliare a:
```glsl
#ifdef GL_ES
precision mediump float;
#endif
#define PROCESSING_COLOR_SHADER
uniform vec2 u_resolution;
uniform vec3 u_mouse;
uniform float u_time;
void main() {
vec2 st = gl_FragCoord.st/u_resolution;
gl_FragColor = vec4(st.x,st.y,0.0,1.0);
}
```
Per ulteriori informazioni sugli shader in Processing controllate questo [tutorial](https://processing.org/tutorials/pshader/).
### In **openFrameworks**
Ognuno ha un luogo in cui sentirsi a proprio agio e, nel mio caso, è ancora la [comunità di openFrameworks](http://openframeworks.cc/). Questo framework C++ integra OpenGL e altre librerie C++ open source. Per molti aspetti è molto simile a Processing, ma con le ovvie complicazioni dovute ai compilatori C++. Allo stesso modo di Processing, openFrameworks cercherà i tuoi file shader nella cartella dati, quindi non dimenticate di copiare i file ```.frag``` che si desiderano utilizzare e modificate il nome quando li si carica.
```cpp
void ofApp::draw(){
ofShader shader;
shader.load("","shader.frag");
shader.begin();
shader.setUniform1f("u_time", ofGetElapsedTimef());
shader.setUniform2f("u_resolution", ofGetWidth(), ofGetHeight());
ofRect(0,0,ofGetWidth(), ofGetHeight());
shader.end();
}
```
Per ulteriori informazioni sugli shader in openFrameworks consultate questo [ottimo tutorial](http://openframeworks.cc/ofBook/chapters/shaders.html) fatto da [Joshua Noble](http://thefactoryfactory.com/).

View File

@ -1,14 +1,46 @@
## シェーダーを使う
そろそろ自分の得意なプラットフォームを使ってシェーダーを試してみたいところでしょう。以下ではこの本で使用するのと同じuniform変数を使えるよう、いくつかの一般的なフレームワークでシェーダーを設定する方法をお見せします。[この章のGitHubレポジトリー](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04)には、この章で取り上げる3つのフレームワークに対応したソースコードが置いてあります
この本を書くに当たり自分自身の練習も兼ねて、シェーダーを書いて表示したり、シェアしたり、まとめたりする為のツールを作成しました。このツールはLinux Desktop、 MacOs、[RaspberryPi](https://www.raspberrypi.org/)やブラウザ上で同じように動作します。あなたのコードを書き換える必要はありません。
**表示する**: この本のすべてのサンプルは[glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas)を使って表示されています。glslCanvasを使うとシェーダーを単体で、とても簡単に走らせることができます。
```html
<canvas class="glslCanvas" data-fragment-url=“yourShader.frag" data-textures=“yourInputImage.png” width="500" height="500"></canvas>
```
ご覧の通り、必要なのは ```class="glslCanvas"``` を指定した ```canvas``` 要素に ```data-fragment-url```でシェーダーのURLを指定することだけです。詳しくは[こちら](https://github.com/patriciogonzalezvivo/glslCanvas)をご覧ください。
もしあなたが私のような人だったら、コンソールから直接シェーダーを走らせたいと思うでしょう。その場合は[glslViewer](https://github.com/patriciogonzalezvivo/glslViewer)を試してみてください。このアプリケーションを利用すると[ImageMagic](http://www.imagemagick.org/script/index.php)を使うのと同じような方法で、シェーダーをbashスクリプトやUNIXパイプラインで使うことができます。[glslViewer](https://github.com/patriciogonzalezvivo/glslViewer)は[RaspberryPi](https://www.raspberrypi.org/)でシェーダーをコンパイルするのにとても便利なので、[openFrame.io](http://openframe.io/)でもglslViewerをシェーダーによる作品の表示に使っています。詳しくは[こちら](https://github.com/patriciogonzalezvivo/glslViewer)をご覧ください。
```bash
glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -s 1 -o yourOutputImage.png
```
**作成する**: シェーダーのコーディングを簡単にするため、[glslEditor](https://github.com/patriciogonzalezvivo/glslEditor)というオンラインのエディターを用意しました。このエディターはこの本のサンプルにも埋め込まれています。glslEditorには幾つもの便利なウィジェットが備わっていて、直接触って具体的に結果を見ることで、抽象的なglslのコーディングをより理解しやすくしてくれます。[editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)から単体で使うこともできます。詳しくは[こちら](https://github.com/patriciogonzalezvivo/glslEditor)をご覧ください。
![](glslEditor-01.gif)
もしオフラインで[SublimeText](https://www.sublimetext.com/)を使って作業したい場合はこの[glslViewerのパッケージ](https://packagecontrol.io/packages/glslViewer)をインストールすることもできます。詳しくは[こちら](https://github.com/patriciogonzalezvivo/sublime-glslViewer)をご覧ください。
![](glslViewer.gif)
**シェアする**: オンラインのglslEditorを使うとあなたのシェーダーをシェアすることもできます。ページに埋め込まれたものもスタンドアローン版にもexportボタンがあり、あなたのシェーダーのURLを取得することができます。また、[openFrame.io](http://openframe.io/)に直接シェアすることもできます。
![](glslEditor-00.gif)
**まとめる**: コードをシェアしてあなたのシェーダーを作品として共有しましょう。[openFrame.io](http://openframe.io/)に書き出す以外にも、あなたのシェーダーをまとめてウェブサイトに埋め込むことのできるツールを用意しました。このツールは[glslGallery](https://github.com/patriciogonzalezvivo/glslGallery)と呼ばれています。詳しくは[こちら](https://github.com/patriciogonzalezvivo/glslGallery)をご覧ください.
もしこれらのフレームワークを使わずにブラウザー以外でシェーダーを試したい場合は、[glslViewer](https://github.com/patriciogonzalezvivo/glslViewer)をダウンロードしてコンパイルしてください。
このプログラムは本書のサンプルのために特別に設計されたもので、MacOSまたはRasberryPIの上でターミナルから直接実行することできます。
![](glslGallery.gif)
## 好みのフレームワークでシェーダーを実行する
もし[Processing](https://processing.org/)、[Three.js](http://threejs.org/) 、[OpenFrameworks](http://openframeworks.cc/)などのフレームワークを使ったブログラミングの経験があるならば、慣れ親しんだ環境でシェーダーを試してみたいと思うでしょう。下記では人気のあるこれらのフレームワークで、この本で紹介するシェーダーを実行できるように設定する方法をお見せします(この本の[GitHubのリポジトリ](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/04)にはこれら3つのフレームワークのためのソースコードが丸ごと置いてあります
### **Three.js**を使う
謙虚で才気あふれる[Ricardo CabelloMrDoob](https://twitter.com/mrdoob)と[その他のメンバー](https://github.com/mrdoob/three.js/graphs/contributors)によって開発された[Three.js](http://threejs.org/)は、おそらく最もよく知られたWebGLのフレームワークのひとつです。このJavascriptのライブラリを使って3Dグラフィックを作る方法を学べる、サンプルやチュートリアル、本も沢山あります。
謙虚で才気あふれる[Ricardo CabelloMrDoob](https://twitter.com/mrdoob)と[その他のメンバー](https://github.com/mrdoob/three.js/graphs/contributors)によって開発された[Three.js](http://threejs.org/)は、おそらく最もく知られたWebGLのフレームワークのひとつです。このJavascriptのライブラリを使って3Dグラフィックを作る方法を学べる、サンプルやチュートリアル、本も沢山あります。
下記はシェーダーをThree.jsで使うために必要なHTMLとJavascriptのサンプルです。```id="fragmentShader"```と書かれたスクリプトに注目してください。ここに、この本に登場するシェーダーをコピーして実行することができます。
@ -50,7 +82,8 @@
uniforms = {
u_time: { type: "f", value: 1.0 },
u_resolution: { type: "v2", value: new THREE.Vector2() }
u_resolution: { type: "v2", value: new THREE.Vector2() },
u_mouse: { type: "v2", value: new THREE.Vector2() }
};
var material = new THREE.ShaderMaterial( {
@ -69,6 +102,11 @@
onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
document.onmousemove = function(e){
uniforms.u_mouse.value.x = e.pageX
uniforms.u_mouse.value.y = e.pageY
}
}
function onWindowResize( event ) {
@ -94,7 +132,7 @@
[Ben Fry](http://benfry.com/)と[Casey Reas](http://reas.com/)が2001年に開発を始めた[Processing](https://processing.org/) はコーディングを始めるのに最適な、驚くほどシンプルでパワフルな開発環境です(少なくとも私にとってはそうでした)。[Andres Colubri](https://codeanticode.wordpress.com/)はopenGLとビデオに関する重要なアップデートを行いました。これによってProcessingでのシェーダーの使用が今まで以上に簡単になりました。Processingのスケッチは ```data``` フォルダーからシェーダーを検索します。このフォルダーにサンプルコードをコピーして ```shader.frag``` と名前を付けてください。
```processing
```cpp
PShader shader;
void setup() {

View File

@ -1,8 +1,8 @@
## Running your shader
As part of the construction of this book and my art practice I made an ecosystem of tools to create, display, share and curate shaders. This tools works consistently across Linux Desktops, MacOS, [RaspberryPi](https://www.raspberrypi.org/) and browsers without the need of changing your code.
As part of the construction of this book and my art practice I made an ecosystem of tools to create, display, share and curate shaders. This tools works consistently across Linux Desktops, MacOS, [Raspberry Pi](https://www.raspberrypi.org/) and browsers without the need of changing your code.
**Display**: all life-examples in this book are displayed using [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) which makes the process of running standalone shader incredible easy.
**Display**: all live examples in this book are displayed using [glslCanvas](https://github.com/patriciogonzalezvivo/glslCanvas) which makes the process of running standalone shader incredible easy.
```html
<canvas class="glslCanvas" data-fragment-url=“yourShader.frag" data-textures=“yourInputImage.png” width="500" height="500"></canvas>
@ -10,13 +10,13 @@ As part of the construction of this book and my art practice I made an ecosystem
As you can see, it just needs a ```canvas``` element with ```class="glslCanvas"``` and the url to your shader in the ```data-fragment-url```. Learn more about it [here](https://github.com/patriciogonzalezvivo/glslCanvas).
If you are like me, you will probably want to run shaders directly from the console, in that case you should check out [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). This application allows you to incorporate shaders into your ```bash``` scripts or unix pipelines and use it in a similar way that [ImageMagick](http://www.imagemagick.org/script/index.php). Also [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) is a great way to compile shaders on your [RaspberryPi](https://www.raspberrypi.org/), reason why [openFrame.io](http://openframe.io/) use it to display shader artwork. Learn more about this application [here](https://github.com/patriciogonzalezvivo/glslViewer).
If you are like me, you will probably want to run shaders directly from the console, in that case you should check out [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer). This application allows you to incorporate shaders into your ```bash``` scripts or unix pipelines and use it in a similar way that [ImageMagick](http://www.imagemagick.org/script/index.php). Also [glslViewer](https://github.com/patriciogonzalezvivo/glslViewer) is a great way to compile shaders on your [Raspberry Pi](https://www.raspberrypi.org/), reason why [openFrame.io](http://openframe.io/) use it to display shader artwork. Learn more about this application [here](https://github.com/patriciogonzalezvivo/glslViewer).
```bash
glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -s 1 -o yourOutputImage.png
```
**Create**: in order to illuminate the experience of coding shaders I made an online editor called [glslEditor](https://github.com/patriciogonzalezvivo/glslEditor). This editor is embebed on the book's life examples, it brings a series of handy widgets to make more tangible the abstract experience of working with glsl code. You can also run it as a standalone web application from [editor.thebookofshaders.com/](http://editor.thebookofshaders.com/). Learn more about it [here](https://github.com/patriciogonzalezvivo/glslEditor).
**Create**: in order to illuminate the experience of coding shaders I made an online editor called [glslEditor](https://github.com/patriciogonzalezvivo/glslEditor). This editor is embedded on the book's live examples, it brings a series of handy widgets to make more tangible the abstract experience of working with glsl code. You can also run it as a standalone web application from [editor.thebookofshaders.com/](http://editor.thebookofshaders.com/). Learn more about it [here](https://github.com/patriciogonzalezvivo/glslEditor).
![](glslEditor-01.gif)
@ -24,7 +24,7 @@ If you prefer to work offline using [SublimeText](https://www.sublimetext.com/)
![](glslViewer.gif)
**Share**: the online editor ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) can share your shaders! Both the embebed and standalone version have an export button where you can get an unique URL's to your shader. Also have the ability to export directly to an [openFrame.io](http://openframe.io/).
**Share**: the online editor ([editor.thebookofshaders.com/](http://editor.thebookofshaders.com/)) can share your shaders! Both the embedded and standalone version have an export button where you can get an unique URL's to your shader. Also have the ability to export directly to an [openFrame.io](http://openframe.io/).
![](glslEditor-00.gif)

141
05/README-it.md Normal file
View File

@ -0,0 +1,141 @@
# Disegno Algoritmico
## Funzioni di forma
Questo capitolo potrebbe essere chiamato "la lezione del recinto di Mr. Miyagi". In precedenza abbiamo associato la posizione normalizzata di *x* e *y* ai canali *rosso* e *verde*. Fondamentalmente abbiamo creato una funzione che prende un vettore bidimensionale (x e y) e restituisce un vettore quadridimensionale (r, g, b e a). Ma prima di andare avanti nella trasformazione dei dati tra dimensioni, dobbiamo iniziare da qualcosa di più semplice…molto più semplice. Questo significa comprendere come creare funzioni unidimensionali. Maggiori sono lenergia e il tempo che impieghi nel comprendere e nel padroneggiarle, migliore sarà il tuo karate shader.
![The Karate Kid (1984)](mr_miyagi.jpg)
La seguente struttura di codice sarà la nostra recinzione. In questa visualizziamo il valore normalizzato della coordinata *x* (```st.x```) in due modi: uno con la luminosità (osserva il bel gradiente dal nero al bianco) e laltro tracciando sopra una linea verde (in questo caso il valore di *x* è assegnato direttamente al valore di *y*). Non ti concentrare troppo sulla funzione plot, la vedremo nel dettaglio tra poco.
<div class="codeAndCanvas" data="linear.frag"></div>
**Nota veloce**: il costruttore di tipo ```vec3``` "capisce" che vuoi assegnare i tre canali di colori allo stesso valore, mentre ```vec4``` capisce che vuoi costruire un vettore a quattro dimensioni con tre unidimensionali più un quarto valore (in questo caso il valore che controlla lalfa o lopacità). Guarda, ad esempio, le righe 20 e 26 qui sopra.
Questo codice è il tuo recinto; è importante osservarlo e capirlo. Tornerai spesso in questo spazio tra *0.0* e *1.0*. Imparerai larte di combinare e modellare questa linea.
Questa relazione uno a uno tra *x* e *y* (o la luminosità) è conosciuta come *interpolazione lineare*. A partire da qui, possiamo usare alcune funzioni matematiche per *modellare* la linea. Per esempio, possiamo elevare *x* alla quinta potenza e creare una linea *curva*.
<div class="codeAndCanvas" data="expo.frag"></div>
Interessante, vero? Alla riga 22 prova esponenti diversi, per esempio: 20.0, 2.0, 1.0, 0.0, 0.2 e 0.02. comprendere questa relazione tra il valore e lesponente sarà molto utile. Questo genere di funzioni matematiche ci darà un controllo espressivo sul codice, come una specie di agopuntura che permette di controllare il flusso dei valori.
[```pow()```](../glossary/?search=pow) è una funzione nativa il GLSL e ce ne sono molte altre. La maggior parte di queste sono accelerate al livello dellhardware; ciò significa che se esse sono usate in modo appropriato e con discrezione, renderanno il tuo codice molto più veloce.
Sostituisci la funzione alla riga 22. Provane altre, come: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) e [```sqrt()```](../glossary/?search=sqrt). Alcune di queste funzioni sono più interessanti quando le si utilizza con PI. Puoi vedere alla riga 8, che ho definito un macro che sostituisce qualsiasi chiamata a ```PI``` con valore ```3.14159265359```.
### Step e Smoothstep
GLSL ha anche alcune funzioni interpolanti native uniche che sono accelerate dallhardware.
Linterpolazione [```step()```](../glossary/?search=step) riceve due parametri. Il primo è il limite o la soglia, mentre il secondo è il valore che volgiamo controllare. Qualsiasi valore al di sotto del limite tornerà a ```0.0```, mentre tutto ciò al di sopra del limite tornerà a ```1.0```.
Prova a cambiare il valore della soglia alla riga 20 del seguente codice.
<div class="codeAndCanvas" data="step.frag"></div>
Laltra funzione unica è conosciuta come [```smoothstep()```](../glossary/?search=smoothstep). Data una serie di due numeri e un valore, questa funzione interpolerà il valore tra la serie definita. I primi due parametri sono per linizio e la fine della transizione, mentre il terzo è per il valore dinterpolazione.
<div class="codeAndCanvas" data="smoothstep.frag"></div>
Nellesempio precedente, alla riga 12, nota che abbiamo usato smoothstep ( ) per disegnare la linea verde sulla funzione ```plot()```. Per ciascuna posizione lungo lasse *x*, questa funzione crea un *salto* ad un particolare valore di *y*. Come? Collegando tra di loro due [```smoothstep()```](../glossary/?search=smoothstep). Guarda la funzione qui di seguito, sostituiscila alla riga 20 di sopra e pensa ad esso come ad un taglio verticale. Lo sfondo assomiglia ad una linea, vero?
```glsl
float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);
```
### Seno e coseno.
Quando si vuole usare la matematica per animare, modellare o combinare, non cè nulla di meglio che essere amici del seno e del coseno.
Queste due basiche funzioni trigonometriche lavorano congiuntamente per costruire cerchi che sono utili come il coltellino svizzero di MacGyver. È importante sapere come si comportano e in che modo possono essere combinate. In breve: dato un angolo (in radianti), essi ritorneranno alla corretta posizione di *x* ([cosine](../glossary/?search=cos)) e di *y* ([sine](../glossary/?search=sin)) di un punto sul margine del cerchio con raggio uguale a 1. Il fatto che queste funzioni ritornano ai valori normalizzati ( tra -1 e 1) in modo così armonioso e fluido le rende uno strumento incredibile.
![](sincos.gif)
Mentre è difficile descrivere tutte le relazioni tra le funzioni trigonometriche e i cerchi, le animazioni soprastanti le riassumono molto bene visivamente.
<div class="simpleFunction" data="y = sin(x);"></div>
Guarda attentamente questa curva sinusoidale. Nota come i valori di *y* ondeggiano dolcemente tra +1 e -1. Come abbiamo visto nellesempio del tempo nel capitolo precedente, si può usare questo comportamento ritmico di [```sin()```](../glossary/?search=sin) per animare le proprietà. Se stai leggendo questo esempio su un browser, vedrai che puoi cambiare il codice nella formula soprastante per osservare come cambia londa. (Nota: non dimenticare il punto e virgola alla fine delle righe).
Prova questi esercizi e osserva cosa succede:
* Aggiungi tempo (```u_time```) a *x* prima di calcolare ```sin```. Osserva attentamente questo **movimento** lungo *x*.
* Moltiplica *x* per ```PI``` prima di calcolare ```sin```. Nota come le due fasi si **restringano** e ciascun ciclo si ripeta tra due valori interi.
* Moltiplica tempo (```u_time```) per *x* prima di calcolare ```sin```. Osserva come la **frequenza** tra le fasi diventi sempre più compressa. Nota che u_time può avere già assunto un valore molto grande, rendendo il grafico difficile da leggere.
* Aggiungi 1.0 a [```sin(x)```](../glossary/?search=sin). Osserva come tutte le onde siano **dislocate** verso lalto e adesso tutti i valori siano tra 0.0 e 2.0.
* Moltiplica [```sin(x)```](../glossary/?search=sin) per 2.0. Osserva come l**ampiezza** raddoppi di misura.
* Calcola il valore assoluto ([```abs()```](../glossary/?search=abs)) di ```sin(x)```. Sembra la traccia di una palla che **rimbalza**.
* Estrai solo la parte frazionaria ([```fract()```](../glossary/?search=fract)) della risultante di [```sin(x)```](../glossary/?search=sin).
* Aggiungi il numero intero più elevato ([```ceil()```](../glossary/?search=ceil)) e il più basso ([```floor()```](../glossary/?search=floor)) della risultante di [```sin(x)```](../glossary/?search=sin) per ottenere unonda digitale dei valori 1 e -1.
### Altre funzioni utili
AAl termine dellultimo esercizio abbiamo presentato alcune nuove funzioni. È arrivato il momento di provare con ciascuna, decommentando le righe sottostanti, una alla volta. Impara quete funzioni e studia il loro comportamento. Lo so, ti stai chiedendo perché e se cerchi velocemente su Google "arte generativa" capirai subito. Ricorda che queste funzioni sono il nostro recinto. Stiamo controllando il movimento in una dimensione, su e giù. Presto arriverà il momento per due, tre e quattro dimensioni!
![Anthony Mattox (2009)](anthony-mattox-ribbon.jpg)
<div class="simpleFunction" data="y = mod(x,0.5); // restituisce il modulo di 0.5
//y = fract(x); // restituisce solo la parte frazionale di un numero
//y = ceil(x); // il numero intero più vicino che sia più grande o uguale a x
//y = floor(x); // il numero intero più vicino che sia più piccolo o uguale a x
//y = sign(x); // estrae il segno di x
//y = abs(x); // restituisce il valore assoluto di x
//y = clamp(x,0.0,1.0); // costringe x a restare fra 0.0 e 1.0
//y = min(0.0,x); // restituisce il valore più piccolo fra x e 0.0
//y = max(0.0,x); // restituisce il valore più grande fra x e 0.0"></div>
### Funzioni di forma avanzate
[Golan Levin](http://www.flong.com/) possiede unampia documentazione molto utile sulle funzioni di forma complesse. Trasportare queste funzioni in GLSL è un ottimo modo per incominciare a costruire la propria cassetta degli attrezzi per creare codici.
* [Polynomial Shaping Functions: www.flong.com/texts/code/shapers_poly](http://www.flong.com/texts/code/shapers_poly/)
* [Exponential Shaping Functions: www.flong.com/texts/code/shapers_exp](http://www.flong.com/texts/code/shapers_exp/)
* [Circular & Elliptical Shaping Functions: www.flong.com/texts/code/shapers_circ](http://www.flong.com/texts/code/shapers_circ/)
* [Bezier and Other Parametric Shaping Functions: www.flong.com/texts/code/shapers_bez](http://www.flong.com/texts/code/shapers_bez/)
<div class="glslGallery" data="160414041542,160414041933,160414041756" data-properties="clickRun:editor,hoverPreview:false"></div>
Come i cuochi collezionano con passione spezie e ingredienti esotici, così gli artisti digitali e i creative coders adorano lavorare sulle proprie funzioni di forma.
[Iñigo Quiles](http://www.iquilezles.org/) possiede una grande raccolta di [funzioni molto utili](http://www.iquilezles.org/www/articles/functions/functions.htm). Dopo aver letto [quest'articolo](http://www.iquilezles.org/www/articles/functions/functions.htm), leggi le seguenti traduzioni di queste funzioni in GLSL. Fai attenzione ai piccoli cambiamenti necessari, come mettere "."" (punto) sui valori flessibili, e usare il nome GLSL per le *funzioni in C*; per esempio, invece di ```powf()```, usa ```pow()```:
<div class="glslGallery" data="05/impulse,05/cubicpulse,05/expo,05/expstep,05/parabola,05/pcurve" data-properties="clickRun:editor,hoverPreview:false"></div>
Per mantenere alta la tua motivazione, qui trovi un esempio elegante dellessere esperti nel karate delle funzioni di forma (creato da [Danguafer](https://www.shadertoy.com/user/Danguafer)).
<iframe width="800" height="450" frameborder="0" src="https://www.shadertoy.com/embed/XsXXDn?gui=true&t=10&paused=true" allowfullscreen></iframe>
Nel *Prossimo >>* capitolo inizieremo ad usare nuove mosse. Prima mescolando i colori e poi disegnando forme.
#### Esercizio
Guarda la seguente tabella di equazioni fatta da [Kynd](http://www.kynd.info/log/). Osserva come combini le funzioni e le loro proprietà per controllare i valori tra 0.0 e 1.0. Ora è il tuo momento di fare pratica replicando queste funzioni. Ricordati: più ti eserciti, migliore sarà il tuo karate.
![Kynd - www.flickr.com/photos/kynd/9546075099/ (2013)](kynd.png)
#### Per la tua cassetta degli attrezzi
Qui trovi alcuni strumenti che ti faciliteranno la visualizzazione di questi tipi di funzione.
* Grapher: se hai un computer MacOS, digita ```grapher``` nel tuo spotlight e riuscirai ad usare questo magnifico attrezzo.
![OS X Grapher (2004)](grapher.png)
* [GraphToy](http://www.iquilezles.org/apps/graphtoy/): ancora una volta [Iñigo Quilez](http://www.iquilezles.org) ha creato un mezzo per visualizzare le funzioni GLSL in WebGL.
![Iñigo Quilez - GraphToy (2010)](graphtoy.png)
* [Shadershop](http://tobyschachman.com/Shadershop/): questo favoloso mezzo creato da [Toby Schachman](http://tobyschachman.com/) ti insegnerà a costruire funzioni complesse in un modo visivo ed incredibilmente intuitivo.
![Toby Schachman - Shadershop (2014)](shadershop.png)

View File

@ -17,11 +17,11 @@ This one-to-one relationship between *x* and *y* (or the brightness) is know as
<div class="codeAndCanvas" data="expo.frag"></div>
Interesting, right? On line 19 try different exponents: 20.0, 2.0, 1.0, 0.0, 0.2 and 0.02 for example. Understanding this relationship between the value and the exponent will be very helpful. Using these types of mathematical functions here and there will give you expressive control over your code, a sort of data acupuncture that let you control the flow of values.
Interesting, right? On line 22 try different exponents: 20.0, 2.0, 1.0, 0.0, 0.2 and 0.02 for example. Understanding this relationship between the value and the exponent will be very helpful. Using these types of mathematical functions here and there will give you expressive control over your code, a sort of data acupuncture that let you control the flow of values.
[```pow()```](../glossary/?search=pow) is a native function in GLSL and there are many others. Most of them are accelerated at the level of the hardware, which means if they are used in the right way and with discretion they will make your code faster.
Replace the power function on line 19. Try other ones like: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) and [```sqrt()```](../glossary/?search=sqrt). Some of these functions are more interesting when you play with them using PI. You can see on line 5 that I have defined a macro that will replace any call to ```PI``` with the value ```3.14159265359```.
Replace the power function on line 22. Try other ones like: [```exp()```](../glossary/?search=exp), [```log()```](../glossary/?search=log) and [```sqrt()```](../glossary/?search=sqrt). Some of these functions are more interesting when you play with them using PI. You can see on line 8 that I have defined a macro that will replace any call to ```PI``` with the value ```3.14159265359```.
### Step and Smoothstep

144
06/README-it.md Normal file
View File

@ -0,0 +1,144 @@
![Paul Klee - Color Chart (1931)](klee.jpg)
## Colori
Non abbiamo ancora avuto occasione di parlare dei tipi di vettore in GLSL. Prima di andare avanti, è importante imparare meglio come funzionano queste variabili e parlare di colori è un buon modo per capirle meglio.
Se siete pratici con i paradigmi di programmazione orientata agli oggetti, probabilmente avrete notato che stiamo accedendo ai dati interni ai vettori, come se fossero una qualunque ```struct``` di C.
```glsl
vec3 red = vec3(1.0,0.0,0.0);
red.x = 1.0;
red.y = 0.0;
red.z = 0.0;
```
Definire il colore usando una notazione *x*, *y* e *z* può essere fuorviante e creare confusione, vero? Per questo esistono altri modi di accedere alle stesse informazioni, con nomi diversi. I valori di ```.x```, ```.y``` e ```.z``` possono anche essere chiamati ```.r```, ```.g``` e ```.b```, e ```.s```, ```.t``` e ```.p```. (```.s```, ```.t``` e ```.p``` solitamente sono usati per le coordinate spaziali di una texture, che vedremo nel prossimo capitolo). Puoi anche accedere ai valori in un vettore usando gli indici di posizione ```[0]```, ```[1]``` e ```[2]```.
Le righe seguenti mostrano tutti i modi per accedere agli stessi valori:
```glsl
vec4 vector;
vector[0] = vector.r = vector.x = vector.s;
vector[1] = vector.g = vector.y = vector.t;
vector[2] = vector.b = vector.z = vector.p;
vector[3] = vector.a = vector.w = vector.q;
```
Questi diversi modi di indicare le variabili allinterno di un vettore sono solo nomenclature progettate per aiutarvi nella scrittura di un codice chiaro. Tale flessibilità incorporata nel linguaggio shading è una porta per iniziare a pensare allintercambiabilità tra colore e coordinate spaziali.
Unaltra grandiosa caratteristica dei tipi di vettore in GLSL è che le proprietà possono essere combinate in qualsiasi ordine voi vogliate, e ciò rende più facile manipolare e mescolare i valori. Questabilità è chiamata *swizzle*.
```glsl
vec3 yellow, magenta, green;
// Per creare il giallo
yellow.rg = vec2(1.0); // Assegnare 1. ai canali del rosso e del verde
yellow[2] = 0.0; // Assegnare 0. al canale del blu
// Per fare il magenta
magenta = yellow.rbg; // Invertite il canale del verde con quello del blu
// Per ottenere il verde
green.rgb = yellow.bgb; // Assegnare il canale blu del giallo (0) ai canali rosso e blu
```
#### Per la vostra cassetta degli attrezzi
Potreste non essere abituati a selezionare i colori attraverso numeri - di sicuro questo processo potrebbe risultare controintuitivo. Per vostra fortuna esistono tanti programmi che semplificano questo lavoro. Trovatene uno che vada incontro ai vostri bisogni e usatelo per ottenere colori in formato ```vec3``` 0 ```vec4``` format. Per esempio, qui trovate i templates che io uso su [Spectrum](http://www.eigenlogik.com/spectrum/mac):
```
vec3({{rn}},{{gn}},{{bn}})
vec4({{rn}},{{gn}},{{bn}},1.0)
```
### Mescolare i colori
Ora che sapete come sono definiti i colori, è tempo di integrare ciò con le nostre conoscenze precedenti. In GLSL cè una funzione molto utile, [```mix()```](../glossary/?search=mix), che vi permette di mescolare due valori in percentuali. Riuscite ad indovinare lestensione della percentuale? Esatto, i valori tra 0.0 e 1.0! Dopo lunghe ore di esercizio, finalmente è ora di mettere le vostre conoscenze in pratica!
![](mix-f.jpg)
Guardate il codice seguente alla riga 18 e osservate come stiamo usando i valori assoluti di unonda sinusoidale nel tempo per mescolare ```colorA``` e ```colorB```.
<div class="codeAndCanvas" data="mix.frag"></div>
Mettete in risalto le vostre capacità:
* Create una transizione espressiva tra colori. Pensate a unemozione particolare. Quale colore la rappresenta meglio? Come appare? Come si dissolve? Pensate ad unaltra emozione e al colore corrispondente. Cambiate il colore iniziale e finale del codice soprastante per ricreare quelle emozioni. Poi animate la transizione usando le funzioni di forma. Robert Penner ha sviluppato una serie di funzioni di forma famose per animazioni al computer, note come [easing functions](http://easings.net/). Potete usare questesempio come ricerca ed ispirazione ma il risultato migliore sarà ottenuto facendo le vostre transizioni.
### Giocare con i gradienti
La funzione [```mix()```](../glossary/?search=mix) ha molto da offrire. Invece di usare un solo ```float```, possiamo passare un tipo di variabile che abbina i primi due argomenti, nel nostro caso un ```vec3```. Facendo così, possiamo controllare le percentuali di ciascun canale colore ```r```, ```g``` e ```b```.
![](mix-vec.jpg)
Guardate l'esempio seguente. Così come negli esempi nel capitolo precedente, stiamo collegando la transizione alla *x* normalizzata e la visualizziamo con una linea. In questo momento tutti e tre i canali seguono la medesima linea.
Ora, togliete il commento alla riga 25 e guardate cosa succede. Poi provate a togliere il commento alle righe 26 e 27. Ricordate che le linee visualizzano la quantità di ```colorA``` e ```colorB``` da mescolare per ogni canale.
<div class="codeAndCanvas" data="gradient.frag"></div>
Probabilmente riconoscerete le tre funzioni di forma che stiamo usando dalla riga 25 alla 27. Giocate con queste! È il momento per esplorare e mostrare le vostre abilità acquisite nel capitolo precedente e creare gradienti interessanti. Provate i seguenti esercizi:
![William Turner - The Fighting Temeraire (1838)](turner.jpg)
* Create un gradiente che assomigli al tramonto di William Turner.
* Animate una transizione tra un'alba e un tramonto usando ```u_time```.
* Riuscite a creare un arcobaleno usando ciò che abbiamo imparato fino ad ora?
* Usate la funzione ```step()``` per creare una bandiera variopinta.
### HSB
Non possiamo parlare di colore senza menzionare lo spazio di colore. Come probabilmente saprete, ci sono diversi modi di organizzare il colore, oltre ai canali del rosso, verde e blu.
[HSB](https://it.wikipedia.org/wiki/Hue_Saturation_Brightness) sta per Hue (Tonalità), Saturation (Saturazione) e Brightness (Luminosità o Valore) ed è un modo di organizzare i colori più intuitivo e utile. Prendete un momento per leggere le funzioni ```rgb2hsv()``` e ```hsv2rgb()``` nel codice seguente.
Mappando la posizione sull'asse x con la tonalità e la posizione sull'asse y con la luminosità, otteniamo uno spettro dei colori visibili. Questa distribuzione spaziale del colore può essere molto pratica; è più intuitivo selezionare un colore con HSB che con RGB.
<div class="codeAndCanvas" data="hsb.frag"></div>
### HSB nelle coordinate polari
Originariamente HSB è stato creato per essere rappresentato in coordinate polari (basate su angoli e raggio) e non in coordinate cartesiane (basate su x e y). Per unire la nostra funzione HSB alle coordinate polari, dobbiamo ottenere l'angolo e la distanza dal centro del canvas per ogni coordinata pixel. Per far questo usiamo la funzione [```length()```](../glossary/?search=length) e [```atan(y,x)```](../glossary/?search=atan) (che è la versione GLSL della più comune ```atan2(y,x)```).
Quando si usano vettori e funzioni trigonometriche, ```vec2```, ```vec3``` e ```vec4``` sono considerati come vettori anche quando rappresentano i colori. Inizieremo a considerare in modo simile i colori e i vettori, e in realtà troverete che questa flessibilità concettuale è molto potente.
**Nota:** se ve lo stavate chiedendo, esistono altre funzioni geometriche oltre a [```length```](../glossary/?search=length), come: [```distance()```](../glossary/?search=distance), [```dot()```](../glossary/?search=dot), [```cross```](../glossary/?search=cross), [```normalize()```](../glossary/?search=normalize), [```faceforward()```](../glossary/?search=fraceforward), [```reflect()```](../glossary/?search=reflect) e [```refract()```](../glossary/?search=refract). Anche GLSL ha speciali funzioni vettoriali come: [```lessThan()```](../glossary/?search=lessThan), [```lessThanEqual()```](../glossary/?search=lessThanEqual), [```greaterThan()```](../glossary/?search=greaterThan), [```greaterThanEqual()```](../glossary/?search=greaterThanEqual), [```equal()```](../glossary/?search=equal) e [```notEqual()```](../glossary/?search=notEqual).
Una volta che otteniamo l'angolo e la lunghezza dobbiamo "normalizzare" i loro valori in una scala tra 0.0 e 1.0. alla riga 27, [```atan(y,x)```](../glossary/?search=atan) restituirà un angolo in radianti tra PI e PI (-3.14 e 3.14), quindi dobbiamo dividere questo numero per ```TWO_PI``` (definito nella parte superiore del codice) per ottenere valori tra -0.5 e 0.5, che con una semplice addizione cambiamo nella scala desiderata tra 0.0 e 1.0. Il raggio restituirà un massimo di 0.5 (perché stiamo calcolando la distanza dal centro del punto di osservazione), quindi abbiamo bisogno di raddoppiare questa distanza (moltiplicando per due) per ottenere un massimo di 1.0.
Come potete vedere, il nostro gioco qui riguarda semplicemente il trasformare e manipolare le distanze tra 0.0 e 1.0.
<div class="codeAndCanvas" data="hsb-colorwheel.frag"></div>
Provate gli esercizi successivi:
* Modificate l'esempio polare per ottenere una ruota di colori che gira, proprio come l'icona del mouse che indica il caricamento.
* Usate una funzione di forma unita alla funzione di conversione da HSB a RGB per espandere un particolare valore di tonalità e comprimere il resto.
![William Home Lizars - Red, blue and yellow spectra, with the solar spectrum (1834)](spectrums.jpg)
* Se guardate da vicino la ruota cromatica usata dai selettori del colore (guardate l'immagine qui sotto), essi usano uno spettro diverso da quello dello spazio di colore RYB. Per esempio, il colore opposto al rosso dovrebbe essere il verde, ma nel nostro esempio è il ciano. Riuscite a trovare un modo per rimediare e far sì che sembri esattamente l'immagine seguente? [Suggerimento: è un buon momento per usare le funzioni di forma].
![](colorwheel.png)
* Leggete il [libro di Josep Alver "L'interazione dei colori”](http://www.goodreads.com/book/show/111113.Interaction_of_Color) e usate i seguenti esempi di shader come pratica.
<div class="glslGallery" data="160505191155,160505193939,160505200330,160509131554,160509131509,160509131420,160509131240" data-properties="clickRun:editor,openFrameIcon:false,showAuthor:false"></div>
#### Nota sulle funzioni e sugli argomenti.
Prima di addentrarci nel capitolo successivo, fermiamoci e torniamo indietro. Osservate le funzioni negli esempi precedenti. Noterete un ```in``` prima di definire il tipo degli argomenti. Questo è un [*qualificatore*](http://www.shaderific.com/glsl-qualifiers/#inputqualifier) e in questo caso specifica che la variabile è solamente letta. Negli esempi futuri vedremo che è anche possibile definire argomenti come ```out``` o ```inout```. Quest'ultimo, ```inout```, è concettualmente simile a passare un argomento per referenza, il che ci dà la possibilità di modificare una variabile passata.
```glsl
int newFunction(in vec4 aVec4, // solo lettura
out vec3 aVec3, // solo scritture
inout int aInt); // lettura e scrittura
```
Potreste non crederci ma ora abbiamo tutti gli elementi per creare dei fantastici disegni. Nel prossimo capitolo impareremo come si possono combinare tutte queste tecniche per creare forme geometriche *fondendo* lo spazio. Sì, avete capito bene, *fondendo* lo spazio.

230
07/README-it.md Normal file
View File

@ -0,0 +1,230 @@
![Alice Hubbard, Providence, United States, ca. 1892. Photo: Zindman/Freemont.](froebel.jpg)
## Figure
Finalmente! Abbiamo costruito e allenato le nostre abilità per questo momento! Avete imparato la maggior parte delle basi, dei tipi e delle funzioni in GLSL. Vi siete esercitati continuamente sulle equazioni di forma. Ora è arrivato il momento di collegare tutti gli elementi. Siete allaltezza di questa sfida! In questo capitolo imparerete a disegnare forme semplici con una procedura in parallelo.
### Rettangolo
Immaginate di avere una carta millimetrata, come quelle che si usano per le lezioni di matematica, e che il nostro compito sia quello di disegnare un quadrato. Le dimensioni del foglio sono 10x10 e il quadrato dovrebbe essere 8x8. Cosa fareste?
![](grid_paper.jpg)
Colorereste tutto tranne la prima e lultima riga e la prima e lultima colonna, giusto?
Come si collega ciò agli shaders? Ogni piccolo quadrato della vostra carta millimetrata è un thread (un pixel). Ogni piccolo quadretto conosce la propria posizione, come per le coordinate di una scacchiera. Nei capitoli precedenti abbiamo associato *x* e *y* ai canali di colore *rosso* e *verde*, e abbiamo imparato come usare il limitato spazio bidimensionale tra 0.0 e 1.0. Come possiamo utilizzare tutto questo per disegnare un quadrato centrato nel mezzo del nostro canvas?
Iniziamo facendo uno pseudocodice che usi la dichiarazione ```if``` sul campo dello spazio. I principi per fare ciò sono straordinariamente simili a come immaginiamo lo scenario della carta millimetrata.
```glsl
if ( (X più grande di 1) AND (Y più grande di 1) )
colora di bianco
else
colora di nero
```
Ora che abbiamo unidea più chiara di come funziona, sostituiamo la dichiarazione ```if``` con [```step()```](../glossary/?search=step), e invece di usare 10x10, usiamo i valori normalizzati tra 0.0 e 1.0.
```glsl
uniform vec2 u_resolution;
void main(){
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.0);
// per ogni valore restituirà 1.0 (bianco) o 0.0 (nero).
float left = step(0.1,st.x); // Simile a ( X più grande di 0.1 )
float bottom = step(0.1,st.y); // Simile a ( Y più grande di 0.1 )
// La moltiplicazione di left*bottom sarà simile alla porta logica AND.
color = vec3( left * bottom );
gl_FragColor = vec4(color,1.0);
}
```
La funzione [```step()```](../glossary/?search=step) trasformerà ogni pixel al di sotto di 0.1 in nero (```vec3(0.0)```) e il resto in bianco (```vec3(1.0)```). La moltiplicazione tra left e bottom funziona come loperazione logica AND, dove entrambi devono essere tra 1.0 per tornare a 1.0. Questo traccia due linee nere, una alla base e laltra sul lato sinistro del canvas.
![](rect-01.jpg)
Nel codice precedente abbiamo ripetuto la struttura per ciascun asse (sinistra e base). Possiamo risparmiare alcune linee di codice passando due valori, invece di uno, direttamente a [```step()```](../glossary/?search=step) Ecco comè:
```glsl
vec2 borders = step(vec2(0.1),st);
float pct = borders.x * borders.y;
```
Fino ad ora abbiamo disegnato solamente due bordi (base-sinistra) del nostro rettangolo. Facciamo gli altri due (alto-destra). Osserva il seguente codice:
<div class="codeAndCanvas" data="rect-making.frag"></div>
Togliete il commento alle righe 21-22 e osservate come invertiamo le coordinate ```st``` e ripetiamo la stessa funzione [```step()```](../glossary/?search=step). In questo modo il ```vec2(0.0,0.0)``` sarà nellangolo in alto a destra. Questo è lequivalente digitale del capovolgimento della pagina e della ripetizione della procedura precedente.
![](rect-02.jpg)
Osservate che alla *riga 18 e alla riga 22* ogni lato è stato moltiplicato insieme. Questo equivale a scrivere:
```glsl
vec2 bl = step(vec2(0.1),st); // sotto-sinistra
vec2 tr = step(vec2(0.1),1.0-st); // sopra-destra
color = vec3(bl.x * bl.y * tr.x * tr.y);
```
Interessante, vero? Questa tecnica si basa tutta sulluso di [```step()```](../glossary/?search=step), della moltiplicazione per le operazioni logiche e il capovolgimento delle coordinate.
Prima di proseguire, provate i seguenti esercizi:
* Cambiate le misure e le proporzioni del rettangolo.
* Provate con lo stesso codice ma usando [```smoothstep()```](../glossary/?search=smoothstep) al posto di [```step()```](../glossary/?search=step). Notate che cambiando valori, potete passare da margini indistinti a lati eleganti e lisci.
* Fate unaltra implementazione che usi [```floor()```](../glossary/?search=floor).
* Scegliete limplementazione che preferite e create una sua funzione che potrete riusare in futuro. Rendete la vostra funzione flessibile ed efficiente.
* Create unaltra funzione che semplicemente tracci il contorno di un rettangolo.
* Come pensate di poter importare e spostare diversi rettangoli sullo stesso canvas? Se immaginate come, dimostrate le vostre capacità costruendo una composizione di rettangoli e colori che ricordi il dipinto di [Piet Mondrian](https://it.wikipedia.org/wiki/Piet_Mondrian).
![Piet Mondrian - Tableau (1921)](mondrian.jpg)
### Circonferenze
Disegnare quadrati e rettangoli su carta millimetrata con coordinate cartesiane è semplice, ma le circonferenze richiedono un approccio diverso, specialmente per il fatto che abbiamo bisogno di un algoritmo “per-pixel”. Una soluzione è riassegnare le coordinate spaziali, in modo tale da poter usare la funzione [```step()```](../glossary/?search=step) per disegnare una circonferenza.
Come? Iniziamo tornando indietro alla lezione di matematica e al foglio a quadretti, sul quale abbiamo aperto il compasso con il raggio della circonferenza, abbiamo premuto lago del compasso al centro della circonferenza e tracciato il perimetro della circonferenza con una semplice rotazione.
![](compass.jpg)
Tradurre ciò in un shader, dove ogni quadrato sul foglio a quadretti è un pixel, implica *chiedere* ad ogni pixel (o thread) se si trova allinterno dellarea della circonferenza. Lo facciamo calcolando la distanza tra il pixel e il centro della circonferenza.
![](circle.jpg)
Esistono diversi modi per calcolare questa distanza. Il più semplice utilizza la funzione [```distance()```](../glossary/?search=distance), che al suo interno calcola la funzione [```length()```](../glossary/?search=length) della differenza tra due punti ( nel nostro caso le coordinate del pixel e il centro del canvas). La funzione ```length()``` non è altro che una scorciatoia dell[equazione dellipotenusa](https://it.wikipedia.org/wiki/Ipotenusa), che usa al suo interno la radice quadrata (([```sqrt()```](../glossary/?search=sqrt))).
![](hypotenuse.png)
Potete usare [```distance()```](../glossary/?search=distance), [```length()```](../glossary/?search=length) o [```sqrt()```](../glossary/?search=sqrt) per calcolare la distanza dal centro del canvas. Il codice seguente contiene queste tre funzioni e il fatto non sorprendente è che ciascuna restituisce esattamente lo stesso risultato.
* Commentate e togliete il commento alle righe per provare i diversi modi di ottenere il medesimo risultato.
<div class="codeAndCanvas" data="circle-making.frag"></div>
Nellesempio precedente abbiamo mappato la distanza dal centro del canvas con la luminosità del colore del pixel. Più un pixel è vicino al centro, minore ( più scuro) è il suo valore. Notate che i valori non diventano troppo alti perché la massima distanza dal centro ( ```vec2(0.5, 0.5)``` ) va a malapena oltre 0.5. Osservate attentamente questa mappa e pensate:
* Cosa potete dedurre da essa?
* Come possiamo usarla per tracciare una circonferenza?
* Modificate il codice qui sopra per far sì che lintero gradiente circolare sia contenuto nel canvas.
### Campo di distanza
Possiamo anche immaginare lesempio soprastante come una carta delle altitudini, dove più scuro implica più alto. Il gradiente ci mostra qualcosa di simile al modello creato da un cono. Immaginate di trovarvi sulla cima di un cono. La distanza orizzontale dal bordo del cono è 0.5. Questa sarà costante in ogni direzione. Scegliendo dove “tagliare” il cono, otterrete una superficie circolare più grande o più piccola.
![](distance-field.jpg)
In sostanza, per creare delle forme, stiamo utilizzando una reinterpretazione dello spazio basata sulla distanza dal centro. Questa tecnica è conosciuta come “campo di distanza” (distance field) ed è usata in modi diversi, dai profili dei caratteri (font) alla grafica 3D.
Esercitatevi con i seguenti esercizi:
* Usate [```step()```](../glossary/?search=step) per trasformare in bianco tutto ciò che è al di sopra di 0.5 e al di sotto di 0.0.
* Invertite i colori dello sfondo e del primo piano.
* Usate [```smoothstep()```](../glossary/?search=smoothstep), provate con valori diversi per ottenere dei margini lisci sulla vostra circonferenza.
* Una volta che siete soddisfatti con unimplementazione, createne una funzione, che potrete riutilizzare in futuro.
* Aggiungete il colore alla circonferenza.
* Riuscite a creare animazioni sulla circonferenza per farla crescere e rimpicciolire, simulando il battito del cuore? (Potete trarre ispirazione dalle animazioni nel capitolo precedente).
* Che ne dite di spostare questa circonferenza? Riuscite a spostarla e a mettere altre circonferenze su uno stesso canvas?
* Cosa succede se combinate i campi di distanza con diverse operazioni e funzioni?
```glsl
pct = distance(st,vec2(0.4)) + distance(st,vec2(0.6));
pct = distance(st,vec2(0.4)) * distance(st,vec2(0.6));
pct = min(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
pct = max(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
```
* Create tre composizioni usando questa tecnica. Se poi riuscite ad animarle, ancora meglio!
#### Per la vostra cassetta degli attrezzi
In termini di potenza computazionale, la funzione [```sqrt()```](../glossary/?search=sqrt), e le altre funzioni che dipendono da essa, possono essere dispendiose. Ecco un altro modo per creare un campo di distanza circolare, basato sulla funzione [```dot()```](../glossary/?search=dot).
<div class="codeAndCanvas" data="circle.frag"></div>
### Proprietà utili dei campi di distanza
![Zen garden](zen-garden.jpg)
I campi di distanza possono essere usati per disegnare quasi qualsiasi cosa. Ovviamente, più una forma è complessa, più sarà complicata la sua equazione, ma una volta che avete la formula per creare un campo di distanza di una certa forma è molto facile combinare e/o applicare degli effetti ad essa, come lati lisci e profili multipli. Per questo motivo, i campi di distanza hanno molto successo nella rappresentazione dei caratteri (font), come [Mapbox GL Labels](https://www.mapbox.com/blog/text-signed-distance-fields/), [Matt DesLauriers](https://twitter.com/mattdesl) [Material Design Fonts](http://mattdesl.svbtle.com/material-design-on-the-gpu) e come è descritto nel [Capitolo 7 del libro "iPhone 3D Programming", OReilly](http://chimera.labs.oreilly.com/books/1234000001814/ch07.html#ch07_id36000921)
Osservate il codice seguente.
<div class="codeAndCanvas" data="rect-df.frag"></div>
Iniziamo spostando il sistema di coordinate al centro e riducendolo a metà per riassegnare i valori di posizione tra -1 e 1. Alla *riga 24* stiamo vedendo i valori del campo di distanza usando una funzione [```fract()```](../glossary/?search=fract), semplificando la visualizzazione dei motivi che essi creano. Il motivo del campo di distanza si continua a ripetere come i cerchi in un giardino zen.
Osserviamo la formula del campo di distanza alla *riga 19*. Lì stiamo calcolando la distanza dalla posizione su ```(.3,.3)``` o ```vec3(.3)``` in tutti e quattro i quadranti ( questo è ciò che fa [```abs()```](../glossary/?search=abs) qui) .
Se togliete il commento alla *riga 20*, noterete che stiamo collegando le distanze a questi quattro punti usando il [```min()```](../glossary/?search=min) a zero. Il risultato produce un nuovo motivo interessante.
Ora provate a togliere il commento alla *riga 21*; stiamo facendo la stessa cosa ma usando la funzione [```max()```](../glossary/?search=max). Il risultato è un rettangolo con gli angoli arrotondati. Notate come gli anelli del campo di distanza diventano più lisci mano a mano che si allontanano dal centro.
Terminate togliendo il commento una ad una alle *righe da 27 a 29*, per capire i diversi usi dei motivi di un campo di distanza.
### Forme polari
![Robert Mangold - Untitled (2008)](mangold.jpg)
Nel capitolo sul colore, abbiamo assegnato alle coordinate cartesiane le coordinate polari, calcolando il *raggio* e gli *angoli* di ciascun pixel con la seguente formula:
```glsl
vec2 pos = vec2(0.5)-st;
float r = length(pos)*2.0;
float a = atan(pos.y,pos.x);
```
Usiamo parte di questa formula allinizio del capitolo per tracciare una circonferenza. Abbiamo calcolato la distanza dal centro usando [```length()```](../glossary/?search=length). Ora che conosciamo i campi di distanza, possiamo imparare un altro modo per disegnare le forme usando le coordinate polari.
Questa tecnica è un po restrittiva ma molto semplice. Consiste nel cambiare il raggio di una circonferenza in funzione dellangolo per realizzare forme diverse. Come funziona la modulazione? Esatto, usando le funzioni di forma!
Qui sotto troverete le medesime funzioni sul diagramma cartesiano e in un esempio shader nelle coordinate polari ( tra le *righe 21 e 25*). Togliete il commento alle funzioni una alla volta, facendo attenzione alla relazione tra un sistema di coordinate e laltro.
<div class="simpleFunction" data="y = cos(x*3.);
//y = abs(cos(x*3.));
//y = abs(cos(x*2.5))*0.5+0.3;
//y = abs(cos(x*12.)*sin(x*3.))*.8+.1;
//y = smoothstep(-.5,1., cos(x*10.))*0.2+0.5;"></div>
<div class="codeAndCanvas" data="polar.frag"></div>
Provate a:
* Animare queste forme.
* Combinare diverse funzioni di forma per fare dei *buchi* nella forma e creare fiori, fiocchi di neve e degli ingranaggi.
* Usare la funzione ```plot()``` che abbiamo usato nel capitolo sulle *funzioni di forma*, per disegnare solamente la sagoma.
### Unire i poteri
Ora che abbiamo imparato come modulare il raggio di una circonferenza in relazione allangolo, usando la funzione [```atan()```](../glossary/?search=atan) per disegnare diverse forme, possiamo imparare come usare ```atan()``` con i campi di distanza e applicare tutti i trucchi e gli effetti possibili con i campi di distanza.
Il nostro trucco userà il numero di lati di un poligono per costruire il campo di distanza, usando le coordinate polari. Controllate [il seguente codice](http://thndl.com/square-shaped-shaders.html) di [Andrew Baldwin](https://twitter.com/baldand).
<div class="codeAndCanvas" data="shapes.frag"></div>
* Usando questesempio, create una funzione che inserisca la posizione e il numero degli angoli di una forma desiderata e restituisca il valore di un campo di distanza.
* Mescolate i campi di distanza usando [```min()```](../glossary/?search=min) e [```max()```](../glossary/?search=max).
* Scegliete un logo geometrico da riprodurre usando i campi di distanza.
Congratulazioni! Avete affrontato la parte più complicata! Fate una pausa per poter assimilare questi concetti: disegnare delle semplici forme con Processing è facile, ma qui no. Nella “terra degli Shader”, disegnare le forme è contorto e può essere faticoso adattarsi al nuovo paradigma di codificazione.
Ora che sapete come disegnare le forme, sono sicuro che vi verranno in mente nuove idee. Nel capitolo successivo imparerete a spostare, ruotare e ridimensionare le forme. Questo vi permetterà di fare delle composizioni!

View File

@ -86,7 +86,7 @@ Before going forward, try the following exercises:
* How do you think you can move and place different rectangles in the same billboard? If you figure out how, show off your skills by making a composition of rectangles and colors that resembles a [Piet Mondrian](http://en.wikipedia.org/wiki/Piet_Mondrian) painting.
![Piet Mondria - Tableau (1921)](mondrian.jpg)
![Piet Mondrian - Tableau (1921)](mondrian.jpg)
### Circles

101
08/README-it.md Normal file
View File

@ -0,0 +1,101 @@
## Matrici 2D
<canvas id="custom" class="canvas" data-fragment-url="matrix.frag" width="700px" height="200px"></canvas>
### Traslare
Nel capitolo precedente abbiamo imparato a fare alcune figure - il trucco per spostare quelle figure è stato di spostare il sistema di coordinate stesso. Siamo in grado d'ottenere questa trasformazione aggiungendo un vettore alla variabile ```st``` che contiene la posizione di ogni frammento. Ciò causa uno spostamento complessivo del sistema di coordinate.
![](translate.jpg)
Di sicuro è più facile da vedere che da spiegare:
* Rimuovete il commento alla linea 35 del codice sottostante e osservate come il sistema di coordinate si muove.
<div class="codeAndCanvas" data="cross-translate.frag"></div>
Ora provate il seguente esercizio:
* Utilizzate ```u_time``` insieme alle funzioni di forma per spostare la piccola croce in un modo interessante. Pensate a un tipo di movimento e tentate di applicarlo alla croce. Prendete degli esempi dal "mondo reale", potrebbero esservi utili - per esempio l'andirivieni delle onde, un movimento a pendolo, una palla che rimbalza, una macchina che accelera, una bicicletta che si ferma.
### Rotazioni
Anche per ruotare degli oggetti abbiamo bisogno di spostare l'intero sistema spaziale. Per questo utilizzeremo una [matrice](https://it.wikipedia.org/wiki/Matrice). Una matrice è un insieme di numeri organizzato in colonne e righe. Quando si moltiplica un vettore per una matrice, la matrice esegue una serie di operazioni e trasforma il vettore in funzione dei valori che questa contiene.
[![Wikipedia entry for Matrix (mathematics) ](matrixes.png)](https://it.wikipedia.org/wiki/Matrice)
GLSL ha un supporto nativo per le matrici a due, tre e quattro dimensioni: [```mat2```](../glossary/?search=mat2) (2x2), [```mat3```](../glossary/?search=mat3) (3x3) e [```mat4```](../glossary/?search=mat4) (4x4). GLSL supporta anche la moltiplicazione di matrici (```*```) e una funzione specifica chiamata ([```matrixCompMult()```](../glossary/?search=matrixCompMult)).
Le matrici possono essere usate per produrre dei comportamenti specifici. Per esempio per traslare un vettore:
![](3dtransmat.png)
Ancora più interessante è la possibilità di utilizzare una matrice per ruotare il sistema di coordinate:
![](rotmat.png)
Il seguente codice mostra come costruire una matrice di rotazione 2D. Questa funzione segue la [formula](http://en.wikipedia.org/wiki/Rotation_matrix) per vettori a due dimensioni e fa ruotare le coordinate intorno al punto ```vec2(0.0)```.
```glsl
mat2 rotate2d(float _angle){
return mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle));
}
```
Questa maniera d'effettuare una rotazione (intorno all'origine) non funziona con l'approccio che abbiamo utilizzato finora per disegnare le figure. La nostra croce viene disegnata al centro della tela, che corrisponde alla posizione ```vec2(0.5)```. Quindi, prima di ruotare lo spazio, abbiamo bisogno di spostare la figura dal `centro` alla coordinata ```vec2(0.0)```, poi di ruotare lo spazio, e infine di spostarla di nuovo nella posizione originale.
![](rotate.jpg)
Date un'occhiata al codice:
<div class="codeAndCanvas" data="cross-rotate.frag"></div>
Provate i seguenti esercizi:
* Rimuovete il commento alla linea 45 del codice qui sopra e prestate attenzione a ciò che accade.
* Commentate le traslazioni, prima e dopo la rotazione, alle linee 37 e 39, e osservate le conseguenze.
* Utilizzate delle rotazioni per migliorare l'animazione che avete simulato nell'esercizio sulla traslazione.
### Scalare
Abbiamo visto come le matrici sono usate per traslare e ruotare gli oggetti nello spazio. (O più precisamente come trasformare il sistema di coordinate per ruotare e spostare gli oggetti.) Se avete utilizzato un software di modellazione 3D o le funzioni push e pop delle matrici in Processing, si sa che le matrici possono essere utilizzati anche per scalare la dimensione di un oggetto.
![](scale.png)
Usando la formula precedente, siamo in grado di scrivere una matrice a due dimensioni per scalare una figura:
```glsl
mat2 scale(vec2 _scale){
return mat2(_scale.x,0.0,
0.0,_scale.y);
}
```
<div class="codeAndCanvas" data="cross-scale.frag"></div>
Provate i seguenti esercizi per capirne il funzionamento.
* Rimuovete il commento alla linea 42 del codice per vedere come funziona la messa in scala attraverso l'uso di colori.
* Osservate cosa succede quando si commentano le traslazioni, prima e dopo il ridimensionamento alle linee 37 e 39.
* Provate a combinare una matrice di rotazione insieme con una matrice di scala. Attenzione, l'ordine delle operazioni è importante: per prima cosa moltiplicate le matrici fra di loro e poi moltiplicate la matrice finale per i vettori.
* Ora che sapete come disegnare, spostare, ruotare, scalare molteplici forme, è il momento di fare una bella composizione. Progettate e realizzate una [falsa UI o HUD (heads up display)](https://www.pinterest.com/patriciogonzv/huds/). Utilizzate il seguente esempio su ShaderToy di [Ndel](https://www.shadertoy.com/user/ndel) per avere un riferimento.
<iframe width="800" height="450" frameborder="0" src="https://www.shadertoy.com/embed/4s2SRt?gui=true&t=10&paused=true" allowfullscreen></iframe>
### Altri usi delle matrici: il colore YUV
Lo [YUV](https://it.wikipedia.org/wiki/YUV) è uno spazio colore utilizzato per la codifica analogica di foto e video che tenga conto della gamma di percezione umana per ridurre la larghezza di banda dei componenti della crominanza.
Nel seguente codice utilizzeremo delle operazioni di matrice in GLSL per trasformare i colori da uno spazio colore all'altro.
<div class="codeAndCanvas" data="yuv.frag"></div>
Come si può vedere, stiamo trattando i colori come dei vettori che vengono moltiplicati con delle matrici. Abbiamo "spostato" i valori di colore come se avessimo spostato un vettore di posizione nello spazio.
In questo capitolo abbiamo imparato come usare le trasformazioni di matrice per spostare, ruotare e ridimensionare i vettori. Queste trasformazioni saranno essenziali per creare delle composizioni con le figure che abbiamo visto nel capitolo precedente. Nel prossimo capitolo provvederemo ad applicare tutto quello che abbiamo imparato per fare dei bei pattern procedurali. Vedrete come la ripetizione e la variazione del codice possano diventare delle pratiche gratificanti.

119
09/README-it.md Normal file
View File

@ -0,0 +1,119 @@
## Motivi
Siccome i programmi shader sono eseguiti pixel per pixel non importa quante volte voi ripetiate una forma, infatti il numero dei calcoli rimane costante. Questo significa che i fragment shader sono particolarmente adatti per creare dei motivi ripetitivi.
[ ![Nina Warmerdam - The IMPRINT Project (2013)](warmerdam.jpg) ](../edit.php#09/dots5.frag)
In questo capitolo applicheremo ciò che abbiamo imparato fin ad ora e lo ripeteremo all'interno del canvas. Così come nel capitolo precedente, la nostra strategia sarà basata sulla moltiplicazione delle coordinate spaziali (tra 0.0 e 0.1), in modo che le forme che disegniamo tra i valori 0.0 e 1.0 saranno ripetute per creare una griglia.
*"The grid provides a framework within which human intuition and invention can operate and that it can subvert. Within the chaos of nature patterns provide a constrast and promise of order. From early patterns on pottery to geometric mosaics in Roman baths, people have long used grids to enhance their lives with decoration."* [*10 PRINT*, Mit Press, (2013)](http://10print.org/)
Prima ricordiamo la funzione [```fract()```](../glossary/?search=fract). Questa restituisce la parte frazionale di un numero, facendo in sostanza ```fract()``` il modulo di uno ([```mod(x,1.0)```](../glossary/?search=mod)). In altre parole, [```fract()```](../glossary/?search=fract) restituisce il numero dopo la virgola mobile. Il nostro sistema variabile di coordinate (```st```) va già da 0.0 a 1.0, quindi non ha senso fare una cosa simile a:
```glsl
void main(){
vec2 st = gl_FragCoord.xy/u_resolution;
vec3 color = vec3(0.0);
st = fract(st);
color = vec3(st,0.0);
gl_FragColor = vec4(color,1.0);
}
```
Ma se ingrandiamo il sistema di coordinate, diciamo di tre volte, otterremo tre sequenze di interpolazioni lineari tra 0-1: la prima tra 0-1, la seconda per le virgole mobili tra 1-2 e la terza per le virgole mobili tra 2-3.
<div class="codeAndCanvas" data="grid-making.frag"></div>
È arrivato il momento di disegnare qualcosa in ciascuno sottospazio, togliendo il commento alla riga 27 (Siccome stiamo moltiplicando sia in x sia in y, il rapporto di forma dello spazio non cambia e le forme saranno come previste).
Provate alcuni dei seguenti esercizi per capire meglio:
* Moltiplicate lo spazio per numeri diversi. Provate con valori con la virgola mobile e anche con valori diversi per x e y.
* Create una funzione riutilizzabile con questo trucco di piastrellatura.
* Suddividete lo spazio in 3 righe e 3 colonne. Trovate un modo di sapere in quale colonna e quale riga si trova il thread e usatelo per cambiare la forma che è mostrata. Provate a creare una griglia per il tris.
### Applicare le matrici all'interno dei motivi
Siccome ciascuna suddivisione, o cella, è una versione più piccola del sistema normalizzato di coordinate che abbiamo già usato, possiamo applicarle una trasformazione matrice per traslare, ruotare o ridimensionare lo spazio interno.
<div class="codeAndCanvas" data="checks.frag"></div>
* Pensate a modi interessanti di animare questo motivo. Considerate le animazioni di colore, forma e movimento. Fate tre animazioni diverse.
* Riproducete dei motivi più complicati componendo forme diverse.
[![](diamondtiles-long.png)](../edit.php#09/diamondtiles.frag)
* Combinate diversi livelli di motivi per comporre il vostro personale motivo di [Tartan Scozzese](https://www.google.com/search?q=scottish+patterns+fabric&tbm=isch&tbo=u&source=univ&sa=X&ei=Y1aFVfmfD9P-yQTLuYCIDA&ved=0CB4QsAQ&biw=1399&bih=799#tbm=isch&q=Scottish+Tartans+Patterns).
[ ![Vector Pattern Scottish Tartan di Kavalenkava](tartan.jpg) ](http://graphicriver.net/item/vector-pattern-scottish-tartan/6590076)
### Compensare i motivi
Immaginiamo di voler imitare un muro di mattoni. Guardando il muro, potete vedere un offset a mezzo mattone sull'asse x a file alternate. Come possiamo farlo?
![](brick.jpg)
Come primo passo dobbiamo sapere se la riga del nostro thread è un numero pari o dispari, perché possiamo usare ciò per determinare se abbiamo bisogno di compensare con un offset le x in quella fila.
____dobbiamo unire i prossimi due paragrafi____
Per determinare se il nostro thread è in una fila pari o dispari, useremo [```mod()```](../glossary/?search=mod) di ```2.0``` e poi vedremo se il risultato è inferiore a ```1.0``` o no. Osservate la formula seguente e togliete il commento alle ultime due righe.
<div class="simpleFunction" data="y = mod(x,2.0);
// y = mod(x,2.0) < 1.0 ? 0. : 1. ;
// y = step(1.0,mod(x,2.0));"></div>
Come potete vedere, usiamo un [operatore ternario](https://it.wikipedia.org/wiki/%3F:) per controllare se il [```mod()```](../glossary/?search=mod) di ```2.0``` sia al di sotto di ```1.0``` (seconda riga) o potremmo anche usare una funzione [```step()```](../glossary/?search=step) che fa la stessa operazione ma più velocemente. Perché? Nonostante sia difficile sapere come ciascuna carta grafica ottimizza e compila il codice, è sicuro assumere che questa funzione built-in sia più veloce di una non built-in. Ogni volta che potete usare una funzione built-in, fatelo!
Ora che abbiamo la formula per il numero dispari, possiamo applicare un offset alle file dispari per dare l'effetto *muro di mattoni* alla nostra piastrellatura. La riga 14 del codice seguente è dove stiamo usando la funzione per "rilevare" le file dispari e dare loro un offset di mezza unità sulle ```x```. Notate che per le file pari, il risultato della nostra funzione è ```0.0```, e moltiplicando ```0.0``` per l'offset di ```0.5```, otteniamo una compensazione di ```0.0```; sulle file dispari moltiplichiamo il risultato della nostra funzione, ```1.0```, per l'offset di ```0.5```, che sposta di ```0.5``` l'asse delle ```x``` del sistema.
Ora provate a togliere il commento alla riga 32 - questo allunga il rapporto di forma del sistema di coordinate per simulare l'aspetto di un "mattone moderno". Togliendo il commento alla riga 40 potete vedere come il sistema di coordinate appaia mappato con il rosso e il verde.
<div class="codeAndCanvas" data="bricks.frag"></div>
* Provate ad animare questo motivo spostando l'offset in base al tempo.
* Fate un'altra animazione dove le file pari si spostano a sinistra e le file dispari si spostano a destra.
* Riuscite a ripetere quest'effetto con le colonne?
* Provate a combinare un offset sugli assi delle ```x``` e delle ```y``` per ottenere qualcosa di simile a questo:
<a href="../edit.php#09/marching_dots.frag"><canvas id="custom" class="canvas" data-fragment-url="marching_dots.frag" width="520px" height="200px"></canvas></a>
## Tessere di Truchet
Ora che abbiamo imparato come dire se la nostra cella è in una fila o colonna pari o dispari. È possibile riutilizzare un singolo motivo in relazione alla sua posizione. Considerate il caso delle tessere di [Truchet Tiles](http://en.wikipedia.org/wiki/Truchet_tiles), dove un singolo motivo può essere rappresentato in quattro modi diversi:
![](truchet-00.png)
Cambiando il motivo lungo le tessere, è possibile costruire una serie infinita di motivi complessi.
![](truchet-01.png)
Osservate più da vicino la funzione ```rotateTilePattern()```, che suddivide lo spazio in quattro celle e assegna un angolo di rotazione a ciascuna di esse.
<div class="codeAndCanvas" data="truchet.frag"></div>
* Commentate, togliete il commento e duplicate le righe da 69 a 72 per comporre nuovi motivi.
* Cambiate il triangolo bianco e nero con un altro elemento, ad esempio: semicerchi, quadrati o linee ruotati.
* Codificate altri motivi dove gli elementi siano ruotati a seconda della loro posizione.
* Create un motivo che cambi altre proprietà a seconda della posizione degli elementi.
* Immaginate qualcos'altro, che non sia necessariamente un motivo, dove potete applicare i principi visti in questa sezione (es. esagrammi di I Ching).
<a href="../edit.php#09/iching-01.frag"><canvas id="custom" class="canvas" data-fragment-url="iching-01.frag" width="520px" height="200px"></canvas></a>
## Create il vostro insieme di tessere
Creare motivi procedurali è un esercizio mentale nel trovare il più piccole elemento riutilizzabile. Questa è una pratica antica; nel corso della storia abbiamo usato schemi e motivi per decorare tessuti, i fondi e i bordi di oggetti: dai motivi nell'antica Grecia al motivo reticolare cinese, il piacere della ripetizione e della variazione affascina la nostra immaginazione. Prendete del tempo per guardare i [motivi](https://www.pinterest.com/patriciogonzv/paterns/) [decorativi](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) e osservate come artisti e designers nel corso della loro lunga tradizione abbiano saputo navigare tra predicibilità dell'ordine e la sorpresa della variazione e del caos. Dai motivi geometrici arabi, ai bellissimi motivi delle stoffe africane, esiste un intero universo di motivi dal quale imparare.
![Franz Sales Meyer - A handbook of ornament (1920)](geometricpatters.png)
Con questo capitolo terminiamo la sezione sul disegno algoritmico. Nei prossimi capitoli impareremo a portare dell'entropia nei nostri shader e a produrre motivi generativi.

View File

@ -91,7 +91,7 @@ Now that we've learned how to tell if our cell is in an even or odd row or colum
![](truchet-00.png)
By changing the pattern across tiles, it's possible to contruct an infinite set of complex designs.
By changing the pattern across tiles, it's possible to construct an infinite set of complex designs.
![](truchet-01.png)

92
10/README-it.md Normal file
View File

@ -0,0 +1,92 @@
# Progettazione generativa
Non è una sorpresa che dopo aver passato tanto tempo a organizzare e a definire precisamente le cose, l'autore voglia introdurre un po' di caos.
## Random
[![Ryoji Ikeda - test pattern (2008) ](ryoji-ikeda.jpg) ](http://www.ryojiikeda.com/project/testpattern/#testpattern_live_set)
La casualità è la massima espressione d'entropia. Come possiamo generare casualità all'interno di un ambiente apparentemente prevedibile e rigido?
Iniziamo analizzando la seguente funzione:
<div class="simpleFunction" data="y = fract(sin(x)*1.0);"></div>
Qui sopra abbiamo estratto il contenuto frazionario di una sinusoide. I valori di [```sin()```](../glossary/?search=sin) che oscillano tra ```-1.0``` e ```1.0``` sono stati tagliati dopo la virgola mobile, restituendo tutti i valori positivi tra ```0.0``` e ```1.0```. Possiamo usare questo effetto per ottenere alcuni valori pseudo-casuali per "rompere" questa onda sinusoidale in pezzi più piccoli. Come? Moltiplicando la risultante di [```sin(x)```](../glossary/?search=sin) con numeri più grandi. Provate ad aggiungere alcuni zeri alla funzione qui sopra.
Arrivando a ```100000.0``` ( l'equazione si presenta così: ```y = fract(sin(x)*100000.0)``` ) non si è più in grado di distinguere l'onda sinusoidale. La granularità della parte frazionaria ha corrotto il flusso della sinusoide al punto di trasformarla in caos pseudo-casuale.
## Controllare il caos
L'utilizzo della casualità può essere difficile; è sia troppo caotica e a volte non abbastanza casuale. Date un'occhiata al grafico seguente. Per farlo, stiamo utilizzando una funzione ```rand()``` che viene implementata esattamente come si è descritto in precedenza.
Dando uno sguardo più da vicino, si può vedere i picchi dell'onda di [```sin()```](../glossary/?search=sin) sono fra ```-1.5707``` e ```1.5707```. Scommetto che ora sapete il perché: è dove la sinusoide raggiunge i suoi valori massimi e minimi.
Se guardate la distribuzione del funzione random, si nota che vi è una certa concentrazione intorno a 0.5 rispetto che a 0.0 e 1.0.
<div class="simpleFunction" data="y = rand(x);
//y = rand(x)*rand(x);
//y = sqrt(rand(x));
//y = pow(rand(x),5.);"></div>
Qualche tempo fa [Pixelero](https://pixelero.wordpress.com) ha pubblicato un [interessante articolo sulla distribuzione random](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/). Ho aggiunto per voi alcune delle funzioni che ha usato nel grafico precedente per vedere come la distribuzione può essere modificata. Decommentate le funzioni e guardate cosa succede.
Se andate a leggere [l'articolo di Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/), è importante tenere a mente che la nostra funzione ```rand()``` è deterministica casuale, in altre parole pseudo-casuale. Il che significa, per esempio, che ```rand(1.)``` restituisce sempre lo stesso valore. [Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/) fa riferimento alla funzione ActionScript ```Math.random()``` che è non-deterministica; cioè ogni chiamata restituirà un valore diverso.
## 2D Random
Ora che abbiamo una migliore comprensione della casualità, è il momento d'applicarla alle dimensioni ```x``` e ```y```. Per fare ciò abbiamo bisogno di trasformare un vettore di due dimensioni in un float unidimensionale. Ci sono diversi modi per farlo, ma la funzione [```dot()```](../glossary/?search=dot) è particolarmente utile in questo caso. Questa funzione restituisce un singolo valore decimale compreso tra ```0.0``` e ```1.0``` a seconda dell'allineamento dei due vettori.
<div class="codeAndCanvas" data="2d-random.frag"></div>
Date un'occhiata al codice a partire della linea 13 fino alla 15 e noterete come stiamo confrontando il ```vec2 st``` con un altro vettore a due dimensioni (```vec2(12.9898,78.233)```).
* Provate a cambiare i valori delle linee 14 e 15. Vedrete come i pattern random cambiano e provate a trarne una conclusione.
* Collegate questa funzione random alla posizione del mouse (```u_mouse```) e al tempo (```u_time```) per capire meglio il suo funzionamento.
## Usare il caos
Il random in due dimensioni assomiglia molto al rumore TV, giusto? Si tratta di un materiale grezzo difficile da usare se si vuole comporre delle immagini. Impariamo come usarlo.
Il primo passo è quello di applicargli una griglia; usando la funzione [```floor()```](../glossary/?search=floor) saremo in grado di generare una tabella di celle composta da integer. Date un'occhiata al seguente codice, in particolare alle linee 22 e 23.
<div class="codeAndCanvas" data="2d-random-mosaic.frag"></div>
Dopo il ridimensionamento dello spazio per 10 (alla linea 21), separiamo dalla parte frazionaria i numeri interi delle coordinate. Abbiamo una certa familiarità con questa ultima operazione, perché l'abbiamo utilizzata per suddividere lo spazio in celle più piccole che vanno da ```0.0``` a ```1.0```. Il valore intero della coordinata è un valore comune per una regione di pixel, che sarà simile a una singola cella. Quindi possiamo usare che il valore intero in comune per ottenere un valore random per quella zona. Poiché la nostra funzione random è deterministica, il valore restituito sarà costante per tutti i pixel in quella cella.
Rimuovete il commento alla linea 29 per mantenere la parte float della coordinata, in modo da poterla usare come un sistema di coordinate per disegnare delle cose all'interno di ogni cellula.
Se combinate questi due valori - la parte intera e la parte frazionaria della coordinata - sarete in grado di mixare variabilità e ordine.
Date un'occhiata all'implementazione del famoso generatore di labirinti ```10 PRINT CHR$(205.5+RND(1)); : GOTO 10``` .
<div class="codeAndCanvas" data="2d-random-truchet.frag"></div>
Qui sto usando i valori random delle celle per disegnare una linea in una direzione o nell'altra utilizzando la funzione ```truchetPattern()``` del capitolo precedente (linee da 41 a 47).
È possibile ottenere un altro pattern interessante decommentando il blocco di righe tra la linea 50 a 53, o animare il pattern decommentando le linee 35 e 36.
## Padroneggiare il Random
[Ryoji Ikeda](http://www.ryojiikeda.com/), compositore elettronico e artista visivo giapponese, è diventato un maestro nell'uso del random; è difficile non essere colpiti ed ipnotizzati dal suo lavoro. Nelle sue opere d'arte audio e visive è riuscito ad utilizzare la casualità in modo tale da non ottenere un fastidioso caos, ma uno specchio della complessità della nostra cultura tecnologica.
<iframe src="https://player.vimeo.com/video/76813693?title=0&byline=0&portrait=0" width="800" height="450" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
Date un'occhiata al lavoro di [Ikeda](http://www.ryojiikeda.com/) e provate i seguenti esercizi:
* Create delle righe di celle in movimento (in direzioni opposte) con valori random. Mostrate solo le celle con valori più luminosi. Provate a rendere costante nel tempo la velocità delle righe.
<a href="../edit.php#10/ikeda-00.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-00.frag" width="520px" height="200px"></canvas></a>
* Fate la stessa cosa con varie righe ma ogni volta con velocità e direzione diverse. Collegate la posizione del mouse alla soglia per decidere quale celle visualizzare.
<a href="../edit.php#10/ikeda-03.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-03.frag" width="520px" height="200px"></canvas></a>
* Creare altri effetti interessanti.
<a href="../edit.php#10/ikeda-04.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-04.frag" width="520px" height="200px"></canvas></a>
L'utilizzo del random può essere problematico dal punto di vista estetico, soprattutto se si vuole creare simulazioni che sembrano naturali. Il random è semplicemente troppo caotico e poche cose nella vita di tutti i giorni sembrano ```random()```. Se si considera un pattern generato dalla pioggia o un grafico azionario, che sono entrambi abbastanza casuali, questi non assomigliano per niente al pattern random che abbiamo fatto all'inizio di questo capitolo. La ragione? Beh, i valori random non hanno alcuna correlazione tra di loro e la maggior parte dei motivi naturali conserva una certa memoria dello stato precedente.
Nel prossimo capitolo impareremo di più a proposito del rumore, una maniera semplice e dall'*aspetto naturale* di creare il caos computazionale.

217
11/README-it.md Normal file
View File

@ -0,0 +1,217 @@
![NASA / WMAP science team](mcb.jpg)
## Rumore
È tempo di fare una pausa! Abbiamo giocato con le funzioni random che sembrano creare del rumore bianco di una televisione, la testa ci gira ancora solo al pensiero degli shader e i nostri occhi sono stanchi. È ora di andare a fare una passeggiata!
Sentiamo l'aria sulla nostra pelle, il sole in faccia. Il mondo è un posto così vivido e ricco: colori, texture, suoni. Mentre camminiamo, non possiamo evitare di notare la superficie delle strade, rocce, alberi e nuvole.
![](texture-00.jpg)
![](texture-01.jpg)
![](texture-02.jpg)
![](texture-03.jpg)
![](texture-04.jpg)
![](texture-05.jpg)
![](texture-06.jpg)
L'imprevedibilità di queste texture potrebbe essere intesa come "random", ma non sembrano di certo il risultato delle funzioni random che abbiamo sperimentato in precedenza. Il "mondo reale" è un posto così ricco e complesso! Come possiamo approssimare questa varietà computazionale?
Questa è stata la domanda che [Ken Perlin](https://mrl.nyu.edu/~perlin/) stava cercando di risolvere nei prima anni '80 quando gli fu commissionato di generare delle texture più realistiche per il film "Tron". Il risultato delle sue ricerche fu un elegante algoritmo di rumore *vincitore del premio Oscar*. (Non disperatevi.)
![Disney - Tron (1982)](tron.jpg)
Quanto segue non è il classico algoritmo di Perlin, ma è un buon punto di partenza per capire come generare del rumore.
<div class="simpleFunction" data="
float i = floor(x); // intero
float f = fract(x); // frazione
y = rand(i); //rand() è spiegata nel capitolo precedente
//y = mix(rand(i), rand(i + 1.0), f);
//y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
"></div>
In queste righe stiamo facendo qualcosa di simile a quello che abbiamo fatto nel capitolo precedente. Stiamo suddividendo un numero floating continuo (```x```) nel suo intero (```i```) e nelle componenti frazionarie (```f```). Usiamo [```floor()```](../glossary/?search=floor) per ottenere ```i``` e [```fract()```](../glossary/?search=fract) per ottenere ```f```. Poi applichiamo ```rand()``` per la parte intera di ```x```, che dà un valore random unico a ogni integer.
Dopo di che si osservino le due righe commentate. La prima interpola ogni valore random in modo lineare.
```glsl
y = mix(rand(i), rand(i + 1.0), f);
```
Andate avanti e rimuovete il commento di questa linea per vedere che cosa succede. Utilizziamo la parte frazionale `f` per mischiare ([```mix()```](../glossary/?search=mix)) i due valori random.
A questo punto del libro, abbiamo imparato che possiamo fare meglio d'una interpolazione lineare, giusto?
Ora provate a decommentare la riga seguente, che utilizza una interpolazione [```smoothstep()```](../glossary/?search=smoothstep) invece di una lineare.
```glsl
y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
```
Tolto il commento, si noti che la transizione tra i picchi diventa armoniosa. In alcune implementazioni del rumore, troverete che i programmatori preferiscono creare le proprie curve cubiche (come la seguente formula) invece di utilizzare la funzione [```smoothstep()```](../glossary/?search=smoothstep).
```glsl
float u = f * f * (3.0 - 2.0 * f ); // curva cubica personalizzata
y = mix(rand(i), rand(i + 1.0), u); // e con un'interpolazione
```
Questo *casualità armoniosa* è un punto di svolta per gli ingegneri grafici o artisti perché fornisce la capacità di generare delle immagini e delle geometrie con un tocco organico. L'Algoritmo del Rumore di Perlin è stato implementato più e più volte in diversi linguaggi e spazio dimensionale per ottenere ogni tipo di uso creativo.
![Robert Hodgin - Written Images (2010)](robert_hodgin.jpg)
Ora è il vostro turno:
* Create la vostra funzione ```float noise(float x)```.
* Utilizzate la funzione di rumore per animare una forma geometrica spostandola, ruotandola o ridimensionandola.
* Fate 'ballare' diverse forme geometriche usando il rumore.
* Costruite forme "organiche" utilizzando la funzione di rumore.
* Una volta che avete la vostra "creatura", cercate di svilupparla ulteriormente assegnandogli un particolare movimento.
## Rumore 2D
![](02.png)
Ora che sappiamo come creare il rumore in una dimensione, è il momento di passare alla 2D. Nelle due dimensioni, invece di interpolare tra due punti di una linea (```fract(x)``` e ```fract(x)+1.0```), interpoleremo tra i quattro angoli di un piano quadrato (```fract(st)```, ```fract(st)+vec2(1.,0.)```, ```fract(st)+vec2(0.,1.)``` e ```fract(st)+vec2(1.,1.)```).
![](01.png)
Allo stesso modo, se si vuole ottenere del rumore 3D dobbiamo interpolare tra gli otto angoli di un cubo. Questa tecnica consiste nell'interpolazione di valori random, che è il motivo per cui si chiama **rumore del valore** (**value noise**) .
![](04.jpg)
Come per l'esempio 1D, questa interpolazione non è lineare, ma cubica, e interpola senza problemi tutti i punti all'interno di una griglia quadrata.
![](05.jpg)
Date un'occhiata alla seguente funzione di rumore.
<div class="codeAndCanvas" data="2d-noise.frag"></div>
Iniziamo scalando lo spazio di 5 (linea 45) per vedere l'interpolazione tra i quadrati della griglia. Poi all'interno della funzione rumore suddividiamo lo spazio in celle. Memorizziamo la posizione "integer" della cella insieme alle posizioni frazionarie all'interno della cella. Usiamo la posizione dell'integer per calcolare le coordinate dei quattro angoli e ottenere un valore random per ciascuno di essi (linee 23-26). Infine, alla linea 35 interpoliamo tra i 4 valori random degli angoli utilizzando le posizioni frazionarie che abbiamo ricavato in precedenza.
Ora è il vostro turno. Provate i seguenti esercizi:
* Cambiate il moltiplicatore alla linea 45. Provate ad animarlo.
* A quale livello di zoom il rumore comincia a sembrare di nuovo random?
* A che livello di zoom il rumore è impercettibile?
* Provate a collegare questa funzione rumore alle coordinate del mouse.
* Che cosa succede se utilizziamo il gradiente del rumore come un campo di distanza? Fatene qualcosa di interessante.
* Ora che avete raggiunto un certo controllo sull'ordine e il caos, è il momento di utilizzare tale conoscenza. Effettuate una composizione di rettangoli, colori e rumore che assomiglia a un dipinto di [Mark Rothko](https://it.wikipedia.org/wiki/Mark_Rothko).
![Mark Rothko - Three (1950)](rothko.jpg)
## Usare il Rumore nella Progettazione Generativa
Gli algoritmi di rumore sono stati originariamente progettati per dare un naturale *je ne sais quoi* alle texture digitali. Le implementazioni 1D e 2D che abbiamo visto fino ad ora erano interpolazioni tra *valori random*, che è il motivo per cui sono chiamate **valore di rumore**, ma ci sono altri modi per ottenere il rumore...
[ ![Inigo Quilez - Value Noise](value-noise.png) ](../edit.php#11/2d-vnoise.frag)
Come avete scoperto negli esercizi precedenti, il valore del rumore tende a sembrare a dei "blocchi". Per ridurre questo effetto, nel 1985 [Ken Perlin](https://mrl.nyu.edu/~perlin/) ha sviluppato un'altra implementazione dell'algoritmo denominato **Rumore di Gradiente** (**Gradient Noise**). Ken aveva capito come interpolare dei *gradienti* random invece che dei valori. Questi gradienti sono stati il risultato d'una funzione random 2D che restituisce le direzioni (rappresentata da un ```vec2```) al posto di singoli valori (```float```). Clicca sull'immagine seguente per vedere il codice e come funziona.
[ ![Inigo Quilez - Gradient Noise](gradient-noise.png) ](../edit.php#11/2d-gnoise.frag)
Guardate questi due esempi di [Inigo Quilez](http://www.iquilezles.org/) e prestate attenzione alle differenze tra il [valore del rumore](https://www.shadertoy.com/view/lsf3WH) e il [gradiente del rumore](https://www.shadertoy.com/view/XdXGW8).
Come un pittore che capisce come i pigmenti funzionano, più sappiamo sulle varie implementazioni del rumore e meglio saremo in grado di usarle. Ad esempio, se si usa un'implementazione del rumore in due dimensioni per ruotare lo spazio in cui sono visualizzate delle linee rette, otterremo il seguente effetto visuale che sembra del legno. Anche in questo caso è possibile fare clic sull'immagine per vedere il codice.
[ ![Wood texture](wood-long.png) ](../edit.php#11/wood.frag)
```glsl
pos = rotate2d( noise(pos) ) * pos; // ruota lo spazio
pattern = lines(pos,.5); // disegna delle linee
```
Un altro modo per ottenere dal rumore dei pattern interessanti è quello di trattarlo come un campo di distanza e applicare alcuni dei trucchi descritti nel [capitolo sulle Figure](../07/).
[ ![Splatter texture](splatter-long.png) ](../edit.php#11/splatter.frag)
```glsl
color += smoothstep(.15,.2,noise(st*10.)); // schizzo nero
color -= smoothstep(.35,.4,noise(st*10.)); // buchi sugli schizzi
```
Un terzo modo di utilizzare la funzione di rumore è di modulare una forma. Questo richiede anche alcune delle tecniche che abbiamo imparato nel [capitolo sulle figure](../07/).
<a href="../edit.php#11/circleWave-noise.frag"><canvas id="custom" class="canvas" data-fragment-url="circleWave-noise.frag" width="300px" height="300"></canvas></a>
Per la vostra pratica:
* Quali altri pattern generativi si possono fare? Che dire del granito? marmo? magma? acqua? Trovate tre immagini di texture di vostro interesse e come poterle realizzare algoritmicamente usando il rumore.
* Utilizzate il rumore per modulare una forma.
* Cosa succede se usate il rumore per il movimento? Tornate al [capitolo sulle Matrici](../08/). Utilizzate l'esempio per traslare il "+", e applicateci alcuni movimenti *random* e derivati dal *rumore*.
* Fate un dipinto generativo alla Jackson Pollock.
![Jackson Pollock - Number 14 gray (1948)](pollock.jpg)
## Rumore Simplesso
Per Ken Perlin il successo del suo algoritmo non è stato sufficiente. Ha pensato che avrebbe potuto funzionare meglio. Al Siggraph 2001 ha presentato il "rumore simplesso", in cui ha ottenuto i seguenti miglioramenti rispetto al precedente algoritmo:
* Un algoritmo con una minore complessità computazionale e un minor numero di moltiplicazioni.
* Un rumore in grado di scalare a dimensioni superiori con meno costo computazionale.
* Un rumore senza artefatti direzionali.
* Un rumore con gradienti ben definiti e continui che possono essere calcolati abbastanza facilmente.
* Un algoritmo che è facile da implementare sull'hardware.
So cosa state pensando... "Chi è costui?" Sì, il suo lavoro è fantastico! Ma sul serio, come ha fatto a migliorare l'algoritmo? Beh, abbiamo visto come per le due dimensioni ha interpolato 4 punti (angoli di un quadrato); allo stesso modo possiamo indovinare che per [tre (vedi un'implementazione qui)](../edit.php#11/3d-noise.frag) e quattro dimensioni abbiamo bisogno di interpolare rispettivamente 8 e 16 punti. Giusto? In altre parole per N dimensioni è necessario interpolare agevolmente dai 2 agli N punti(2^N). Ma Ken ha elegantemente notato che, anche se il quadrato è la scelta ovvia per riempire lo spazio, la figura più semplice in 2D è il triangolo equilatero. Così ha iniziato a sostituire la griglia quadrata (abbiamo appena appreso come usarla) per una griglia simplessa di triangoli equilateri.
![](simplex-grid-00.png)
La figura simplessa per N dimensioni è una figura con N + 1 angoli. In altre parole, un angolo in meno da calcolare in 2D, 4 in meno in 3D e 11 in meno in 4D! Questo è un enorme miglioramento!
In due dimensioni l'interpolazione avviene in modo simile al rumore regolare, interpolando i valori degli angoli di una sezione. Ma in questo caso, utilizzando una griglia simplessa, abbiamo solo bisogno di interpolare la somma di 3 angoli.
![](simplex-grid-01.png)
Come è fatta la griglia simplessa? Con un'altra mossa brillante ed elegante, la griglia simplessa può essere ottenuta suddividendo le celle di una regolare griglia a 4 angoli in due triangoli isosceli e poi distorcendola finché ogni triangolo sia equilatero.
![](simplex-grid-02.png)
Poi, come [Stefan Gustavson descrive in questo articolo](http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf): _".. cercando le parti intere delle coordinate trasformate (x,y) per il punto che vogliamo valutare, siamo in grado di determinare rapidamente quale cella di due simplessi contiene il punto. Confrontando anche le grandezze di x e y, siamo in grado di determinare se il punto è nel simplesso più alto o più basso, e percorrere i tre punti d'angolo corretti."_
Nel seguente codice è possibile rimuovere il commento alla linea 44 per vedere come la griglia è distorta, e poi rimuovere il commento alla linea 47 per vedere come una griglia simplessa può essere costruita. Notate come alla linea 22 stiamo suddividendo il quadrato distorto in due triangoli equilateri semplicemente controllando se ```x > y``` (triangolo "inferiore") oppure ```y > x``` (triangolo "superiore").
<div class="codeAndCanvas" data="simplex-grid.frag"></div>
Un altro miglioramento introdotto da Perlin con il **Rumore Simplesso**, è la sostituzione della Curva Cubica di Hermite ( _f(x) = 3x^2-2x^3_ , che è identica alla funzione [```smoothstep()```](../glossary/?search=smoothstep) ) con una Curva Quintica di Hermite ( _f(x) = 6x^5-15x^4+10x^3_ ). In questo modo entrambe le estremità della curva sono più "piatte" così che ogni limite si unisce con grazia con quello successivo. In altre parole si ottiene una transizione più continua tra le celle. Si può osservare ciò decommentando la seconda formula nel seguente esempio grafico (o osservando le [due equazioni fianco a fianco cliccando qui](https://www.desmos.com/calculator/2xvlk5xp8b)).
<div class="simpleFunction" data="
// Curva Cubica di Hermite. Identica alla funzione SmoothStep()
y = x*x*(3.0-2.0*x);
// Curva Quintica di Hermite
//y = x*x*x*(x*(x*6.-15.)+10.);
"></div>
Si noti come le estremità della curva cambino. Si può leggere di più a proposito [sul sito di Ken](http://mrl.nyu.edu/~perlin/paper445.pdf).
Tutti questi miglioramenti si traducono in un capolavoro algoritmico noto come **Rumore Simplesso**. La seguente è una implementazione GLSL di questo algoritmo fatta da Ian McEwan(e presentato in [questo articolo](http://webstaff.itn.liu.se/~stegu/jgt2012/article.pdf)) che è troppo complicata per scopi didattici, ma sarete felici di fare un clic su di esso e vedere che è meno criptica di quanto si possa pensare.
[ ![Ian McEwan of Ashima Arts - Simplex Noise](simplex-noise.png) ](../edit.php#11/2d-snoise-clear.frag)
Beh... direi che abbiamo avuto abbastanza tecnicismi, è il momento d'utilizzare queste risorse in modo creativo:
* Osservate ogni implementazione del rumore. Immaginatele come delle materie grezze, come delle rocce di marmo per uno scultore. Che cosa si può dire a proposito delle "sensazione" che ci trasmettono? Chiudete gli occhi per far scattare la vostra immaginazione, come quando si cercano delle forme in una nuvola. Cosa vedi? Cosa ricorderai? Che cosa si potrebbe creare da ogni implementazione del rumore? Seguite le vostre ispirazioni e cercate di realizzarle con il codice.
* Fate uno shader che crea l'illusione di un flusso. Come una lampada di lava, gocce d'inchiostro, dell'acqua, ecc.
<a href="../edit.php#11/lava-lamp.frag"><canvas id="custom" class="canvas" data-fragment-url="lava-lamp.frag" width="520px" height="200px"></canvas></a>
* Utilizzate il rumore simplesso per aggiungere delle texture a dei lavori precedenti.
<a href="../edit.php#11/iching-03.frag"><canvas id="custom" class="canvas" data-fragment-url="iching-03.frag" width="520px" height="520px"></canvas></a>
In questo capitolo abbiamo preso controllo sul caos. Non è stato un lavoro facile! Diventare un maestro del rumore richiede tempo e impegno.
Nei capitoli seguenti vedremo alcune tecniche ben note per perfezionare le proprie competenze e ottenere di più dal vostro rumore per progettare del contenuto generativo di qualità. Fino ad allora godetevi un po' di tempo all'aria aperta, contemplate la natura e i suoi pattern complicati. La capacità d'osservazione è altrettanto importante (se non di più) rispetto a quella di creare dei pattern. Andate fuori e godetevi il resto della giornata!
<p style="text-align:center; font-style: italic;">"Parla con l'albero, per farsi un amico." Bob Ross
</p>

View File

@ -31,7 +31,7 @@ y = rand(i); //rand() is described in the previous chapter
//y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
"></div>
In these lines we are doing something similar to what we did in the previous chapter. We are subdividing a continuous floating number (```x```) into its integer (```i```) and fractional (```f```) components. We use [```floor()```](.../glossary/?search=floor) to obtain ```i``` and [```fract()```](.../glossary/?search=fract) to obtain ```f```. Then we apply ```rand()``` to the integer part of ```x```, which gives a unique random value for each integer.
In these lines we are doing something similar to what we did in the previous chapter. We are subdividing a continuous floating number (```x```) into its integer (```i```) and fractional (```f```) components. We use [```floor()```](../glossary/?search=floor) to obtain ```i``` and [```fract()```](../glossary/?search=fract) to obtain ```f```. Then we apply ```rand()``` to the integer part of ```x```, which gives a unique random value for each integer.
After that you see two commented lines. The first one interpolates each random value linearly.
@ -39,16 +39,16 @@ After that you see two commented lines. The first one interpolates each random v
y = mix(rand(i), rand(i + 1.0), f);
```
Go ahead and uncomment this line to see how this looks. We use the [```fract()```](.../glossary/?search=fract) value store in `f` to [```mix()```](.../glossary/?search=mix) the two random values.
Go ahead and uncomment this line to see how this looks. We use the [```fract()```](../glossary/?search=fract) value store in `f` to [```mix()```](../glossary/?search=mix) the two random values.
At this point in the book, we've learned that we can do better than a linear interpolation, right?
Now try uncommenting the following line, which uses a [```smoothstep()```](.../glossary/?search=smoothstep) interpolation instead of a linear one.
Now try uncommenting the following line, which uses a [```smoothstep()```](../glossary/?search=smoothstep) interpolation instead of a linear one.
```glsl
y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
```
After uncommenting it, notice how the transition between the peaks gets smooth. In some noise implementations you will find that programmers prefer to code their own cubic curves (like the following formula) instead of using the [```smoothstep()```](.../glossary/?search=smoothstep).
After uncommenting it, notice how the transition between the peaks gets smooth. In some noise implementations you will find that programmers prefer to code their own cubic curves (like the following formula) instead of using the [```smoothstep()```](../glossary/?search=smoothstep).
```glsl
float u = f * f * (3.0 - 2.0 * f ); // custom cubic curve
@ -152,6 +152,20 @@ For you to practice:
![Jackson Pollock - Number 14 gray (1948)](pollock.jpg)
## Improved Noise
An improvement by Perlin to his original non-simplex noise **Simplex Noise**, is the replacement of the cubic Hermite curve ( _f(x) = 3x^2-2x^3_ , which is identical to the [```smoothstep()```](../glossary/?search=smoothstep) function) with a quintic interpolation curve ( _f(x) = 6x^5-15x^4+10x^3_ ). This makes both ends of the curve more "flat" so each border gracefully stitches with the next one. In other words, you get a more continuous transition between the cells. You can see this by uncommenting the second formula in the following graph example (or see the [two equations side by side here](https://www.desmos.com/calculator/2xvlk5xp8b)).
<div class="simpleFunction" data="
// Cubic Hermite Curve. Same as SmoothStep()
y = x*x*(3.0-2.0*x);
// Quintic interpolation curve
//y = x*x*x*(x*(x*6.-15.)+10.);
"></div>
Note how the ends of the curve change. You can read more about this in [Ken's own words](http://mrl.nyu.edu/~perlin/paper445.pdf).
## Simplex Noise
For Ken Perlin the success of his algorithm wasn't enough. He thought it could perform better. At Siggraph 2001 he presented the "simplex noise" in which he achieved the following improvements over the previous algorithm:
@ -182,18 +196,7 @@ In the following code you can uncomment line 44 to see how the grid is skewed, a
<div class="codeAndCanvas" data="simplex-grid.frag"></div>
Another improvement introduced by Perlin with **Simplex Noise**, is the replacement of the Cubic Hermite Curve ( _f(x) = 3x^2-2x^3_ , which is identical to the [```smoothstep()```](.../glossary/?search=smoothstep) function) for a Quintic Hermite Curve ( _f(x) = 6x^5-15x^4+10x^3_ ). This makes both ends of the curve more "flat" so each border gracefully stiches with the next one. In other words you get a more continuous transition between the cells. You can see this by uncommenting the second formula in the following graph example (or see the [two equations side by side here](https://www.desmos.com/calculator/2xvlk5xp8b)).
<div class="simpleFunction" data="
// Cubic Hermine Curve. Same as SmoothStep()
y = x*x*(3.0-2.0*x);
// Quintic Hermine Curve
//y = x*x*x*(x*(x*6.-15.)+10.);
"></div>
Note how the ends of the curve change. You can read more about this in [Ken's own words](http://mrl.nyu.edu/~perlin/paper445.pdf).
All these improvements result in an algorithmic masterpiece known as **Simplex Noise**. The following is a GLSL implementation of this algorithm made by Ian McEwan (and presented in [this paper](http://webstaff.itn.liu.se/~stegu/jgt2012/article.pdf)) which is overcomplicated for educational purposes, but you will be happy to click on it and see that it is less cryptic than you might expect.
All these improvements result in an algorithmic masterpiece known as **Simplex Noise**. The following is a GLSL implementation of this algorithm made by Ian McEwan and Stefan Gustavson (and presented in [this paper](http://webstaff.itn.liu.se/~stegu/jgt2012/article.pdf)) which is overcomplicated for educational purposes, but you will be happy to click on it and see that it is less cryptic than you might expect, and the code is short and fast.
[ ![Ian McEwan of Ashima Arts - Simplex Noise](simplex-noise.png) ](../edit.php#11/2d-snoise-clear.frag)

View File

@ -26,10 +26,8 @@
<ul class="navigationBar" >
<li class="navigationBar" onclick="previusPage()">&lt; &lt; Previous</li>
<li class="navigationBar" onclick="homePage()"> Home </li>
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include($path."/footer.php");
?>
<!-- <li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li> -->

View File

@ -2,41 +2,54 @@
## Cellular Noise
In 1996, sixteen years after Perlin's Noise and five years before his Simplex Noise, [Steven Worley wrote a paper call “A Cellular Texture Basis Function”](http://www.rhythmiccanvas.com/research/papers/worley.pdf). In it he describes a procedural texturing technique now extensively use by the graphics community.
In 1996, sixteen years after Perlin's original Noise and five years before his Simplex Noise, [Steven Worley wrote a paper called “A Cellular Texture Basis Function”](http://www.rhythmiccanvas.com/research/papers/worley.pdf). In it, he describes a procedural texturing technique now extensively used by the graphics community.
To understand the principles behind it we need to start thinking in terms iterations.
To understand the principles behind it we need to start thinking in terms of **iterations**. Probably you know what that means: yes, start using ```for``` loops. There is only one catch with ```for``` loops in GLSL: the number we are checking against must be a constant (```const```). So, no dynamic loops - the number of iterations to do must be fixed.
### A distance field for some points
Let's take a look at an example.
Let's say we want to make a distance field of 4 points. What we need to do? in a nutshell, **for each pixel we want to calculate the distance to the closest point**. That means that we need to iterate through all the points and store the value to the most close one.
### Points for a distance field
Cellular Noise is based on distance fields, the distance to the closest one of a set of feature points. Let's say we want to make a distance field of 4 points. What do we need to do? Well, **for each pixel we want to calculate the distance to the closest point**. That means that we need to iterate through all the points, compute their distances to the current pixel and store the value for the one that is closest.
```glsl
float min_dist = 100.; // A variable to store the closest distance to a point
min_dist = min(min_dist, distance(st, point_a));
min_dist = min(min_dist, distance(st, point_b));
min_dist = min(min_dist, distance(st, point_c));
min_dist = min(min_dist, distance(st, point_d));
```
![](cell-00.png)
This is not very elegant, but it does the trick. Now let's re-implement it using an array and a ```for``` loop.
```glsl
float m_dist = 1.; // minimun distance
float m_dist = 100.; // minimum distance
for (int i = 0; i < TOTAL_POINTS; i++) {
float dist = distance(st, points[i]);
m_dist = min(m_dist, dist);
}
```
To do that we can use a ```for``` loop to iterate through an array of points and keep track of the minimum distance using a [```min()```](../glossary/?search=min) function. Here a brief implementation of that:
Note how we use a ```for``` loop to iterate through an array of points and keep track of the minimum distance using a [```min()```](../glossary/?search=min) function. Here's a brief working implementation of this idea:
<div class="codeAndCanvas" data="cellnoise-00.frag"></div>
Note in the above code, how one of the points is the mouse position. Play with it so you can get a more intuitive idea of how this code behaves. Then try this:
In the above code, one of the points is assigned to the mouse position. Play with it so you can get an intuitive idea of how this code behaves. Then try this:
- How can you animate the rest of the points?
- After reading [the chapter about shapes](../07/), imagine interesting ways to use this distance field?
- After reading [the chapter about shapes](../07/), imagine interesting ways to use this distance field!
- What if you want to add more points to this distance field? What if we want to dynamically add/subtract points?
### Tiling and iterating
### Tiling and iteration
You probably notice that ```for``` loops and *arrays* are not so friendly in GLSL. Loops don't accept dynamic limits on their condition. Also iterating through a lot of instances reduce the performance of your shader significantly. So... We need to find another strategy.
You probably notice that ```for``` loops and *arrays* are not very good friends with GLSL. Like we said before, loops don't accept dynamic limits on their exit condition. Also, iterating through a lot of instances reduces the performance of your shader significantly, because loops can't exit early - they always have to run to completion. That means we can't use this direct approach for large amounts on points. We need to find another strategy, one that takes advantage of the parallel processing archeture of the GPU.
![](cell-01.png)
One way to approach this problem is to divide the space in tiles. Not every pixel need to check every single points, right? They just need to check the points that are close to them. That's the main idea of [Steven Worley's paper](http://www.rhythmiccanvas.com/research/papers/worley.pdf). We already subdivide the space into cells in the chapters about: [patterns](../09/), [random](../10/) and [noise](../11/). Hopefully by now you are familiarize with this technique.
One way to approach this problem is to divide the space into tiles. Not every pixel needs to check the distance to every single point, right? Given the fact that each pixel runs in its own thread, we can subdivide the space into cells, each one with one unique point to watch. Also, to avoid aberrations at the edges between cells we need to check for the distances to the points on the neighboring cells. That's the main brillant idea of [Steven Worley's paper](http://www.rhythmiccanvas.com/research/papers/worley.pdf). At the end, each pixel needs to check only nine positions: their own cell's point and the points in the 8 cells around it. We already subdivide the space into cells in the chapters about: [patterns](../09/), [random](../10/) and [noise](../11/), so hopefully you are familiar with this technique by now.
```glsl
// Scale
@ -47,7 +60,7 @@ One way to approach this problem is to divide the space in tiles. Not every pixe
vec2 f_st = fract(st);
```
So what's the plan? We will use the tile coordinates (stored in the integer coordinate, ```i_st```) to construct a random position of a point. The ```random2f``` function we will use receive a ```vec2``` and give us a ```vec2``` with a random position. So for each tile we will have one point in a random position.
So, what's the plan? We will use the tile coordinates (stored in the integer coordinate, ```i_st```) to construct a random position of a point. The ```random2f``` function we will use receives a ```vec2``` and gives us a ```vec2``` with a random position. So, for each tile we will have one feature point in a random position within the tile.
```glsl
vec2 point = random2(i_st);
@ -60,11 +73,11 @@ Each pixel inside that tile (stored in the float coordinate, ```f_st```) will ch
float dist = length(diff);
```
This will look like this:
The result will look like this:
<a href="../edit.php#12/cellnoise-01.frag"><img src="cellnoise.png" width="520px" height="200px"></img></a>
We still need to calculate the points around each pixel. Not just the one in the current tile. For that we need to **iterate** through the neighbor tiles. Not all of them. just the one immediately around it. That means from ```-1``` (left) to ```1``` (right) tile in ```x``` axis and ```-1``` (bottom) to ```1``` (top) in ```y``` axis. A 3x3 kernel of 9 tiles that we can iterate using a double ```for``` loop like this one:
We still need to check the distances to the points in the surrounding tiles, not just the one in the current tile. For that we need to **iterate** through the neighbor tiles. Not all tiles, just the ones immediately around the current one. That means from ```-1``` (left) to ```1``` (right) tile in ```x``` axis and ```-1``` (bottom) to ```1``` (top) in ```y``` axis. A 3x3 region of 9 tiles can be iterated through using a double ```for``` loop like this one:
```glsl
for (int y= -1; y <= 1; y++) {
@ -78,7 +91,7 @@ for (int y= -1; y <= 1; y++) {
![](cell-02.png)
Now, we can predict the position of the points on each one of the neighbors in our double ```for``` loop by adding the neighbor tile offset to the current tile coordinate.
Now, we can compute the position of the points on each one of the neighbors in our double ```for``` loop by adding the neighbor tile offset to the current tile coordinate.
```glsl
...
@ -87,7 +100,7 @@ Now, we can predict the position of the points on each one of the neighbors in o
...
```
The rest is all about calculating the distance to that point and store the closest one in a variable call ```m_dist``` (for minimal distance).
The rest is all about calculating the distance to that point and store the closest one in a variable call ```m_dist``` (for minimum distance).
```glsl
...
@ -101,30 +114,29 @@ The rest is all about calculating the distance to that point and store the close
...
```
The above code is inspired by [this Inigo's Quilez article](http://www.iquilezles.org/www/articles/smoothvoronoi/smoothvoronoi.htm) where he said:
The above code is inspired by [this article by Inigo's Quilez](http://www.iquilezles.org/www/articles/smoothvoronoi/smoothvoronoi.htm) where he said:
*"... it might be worth noting that there's a nice trick in this code above. Most implementations out there suffer from precision issues, because they generate their random points in "domain" space (like "world" or "object" space), which can be arbitrarily far from the origin. One can solve the issue moving all the code to higher precision data types, or by being a bit clever. My implementation does not generate the points in "domain" space, but in "cell" space: once the integer and fractional parts of the shading point are extracted and therefore the cell in which we are working identified, all we care about is what happens around this cell, meaning we can drop all the integer part of our coordinates away all together, saving many precision bits. In fact, in a regular voronoi implementation the integer parts of the point coordinates simply cancel out when the random per cell feature points are subtracted from the shading point. In the implementation above, we don't even let that cancelation happen, cause we are moving all the computations to "cell" space. This trick also allows one to handle the case where you want to voronoi-shade a whole planet - one could simply replace the input to be double precision, perform the floor() and fract() computations, and go floating point with the rest of the computations without paying the cost of changing the whole implementation to double precision. Of course, same trick applies to Perlin Noise patterns (but i've never seen it implemented nor documented anywhere)."*
Recaping: we subdivide the space in tiles; each pixel will calculate the distance to the point in their own tile and the other 8 tiles; store the closest distance. The resultant is distance field that looks like the following example:
Recapping: we subdivide the space in tiles; each pixel will calculate the distance to the point in their own tile and the surrounding 8 tiles; store the closest distance. The result is a distance field that looks like the following example:
<div class="codeAndCanvas" data="cellnoise-02.frag"></div>
Explore by:
Explore this further by:
- Scaling the space by different values.
- Can you think in other ways to animate the points?
- Can you think of other ways to animate the points?
- What if we want to compute an extra point with the mouse position?
- What other ways of constructing this distance field beside ```m_dist = min(m_dist, dist);```, can you imagine?
- What interesting patterns you can make with this distance field?
- What other ways of constructing this distance field can you imagine, besides ```m_dist = min(m_dist, dist);```?
- What interesting patterns can you make with this distance field?
This algorithm can also be interpreted from the perspective of the points and not the pixels. In that case it can be describe as: each point grows until it finds the area of another point. Which mirrors some of the grow rules on nature. Living forms are shaped by this tension between an inner force to expand and grow limited by the forces
on their medium. The classic algorithm that simulate this behavior is named after [Georgy Voronoi](https://en.wikipedia.org/wiki/Georgy_Voronoy).
This algorithm can also be interpreted from the perspective of the points and not the pixels. In that case it can be described as: each point grows until it finds the growing area from another point. This mirrors some of the growth rules in nature. Living forms are shaped by this tension between an inner force to expand and grow, and limitations by outside forces. The classic algorithm that simulates this behavior is named after [Georgy Voronoi](https://en.wikipedia.org/wiki/Georgy_Voronoy).
![](monokot_root.jpg)
### Voronoi Algorithm
Constructing voronoi diagrams from cellular noise is less hard that what it seams. We just need to *keep* some extra information about the precise point which is closer to the pixel. For that we are going to use a ```vec2``` call ```m_point```. By storing the position to the center of the closest point will be "keeping" and "unique" identifier of that point.
Constructing Voronoi diagrams from cellular noise is less hard that what it might seem. We just need to *keep* some extra information about the precise point which is closest to the pixel. For that we are going to use a ```vec2``` call ```m_point```. By storing the vector direction to the center of the closest point, instead of just the distance, we will be "keeping" a "unique" identifier of that point.
```glsl
...
@ -135,17 +147,17 @@ Constructing voronoi diagrams from cellular noise is less hard that what it seam
...
```
Note in the following code that we are not longer using ```min``` to calculate the closest distance but a regular ```if``` statement. Why? Because we actually want to do something every time a new closer point appears, store it position (lines 32 to 37).
Note that in the following code that we are not longer using ```min``` to calculate the closest distance, but a regular ```if``` statement. Why? Because we actually want to do something more every time a new closer point appears, namely store its position (lines 32 to 37).
<div class="codeAndCanvas" data="vorono-00.frag"></div>
Note how the color of the moving cell (hook to the mouse position) change color according it position. That's because the color is assigned using the value (position) of the closes point.
Note how the color of the moving cell (bound to the mouse position) changes color according to its position. That's because the color is assigned using the value (position) of the closest point.
Like we did before now is time to scale this up, switching to [Steven Worley's paper approach](http://www.rhythmiccanvas.com/research/papers/worley.pdf). Try implementing it your self. You can use the help of the following example by clicking on it.
Like we did before, now is the time to scale this up, switching to [Steven Worley's paper approach](http://www.rhythmiccanvas.com/research/papers/worley.pdf). Try implementing it yourself. You can use the help of the following example by clicking on it. Note that Steven Worley's original approach uses a variable number of feature points for each tile, more than one in most tiles. In his software implementation in C, this is used to speed up the loop by making early exits. GLSL loops don't allow early exits, or variable number of iterations, so you probably want to stick to one feature point per tile.
<a href="../edit.php#12/vorono-01.frag"><canvas id="custom" class="canvas" data-fragment-url="vorono-01.frag" width="520px" height="200px"></canvas></a>
Once you figurate out this algorithm think interesting and creative uses for it.
Once you figure out this algorithm, think of interesting and creative uses for it.
![Extended Voronoi - Leo Solaas (2011)](solas.png)
@ -157,21 +169,21 @@ Once you figurate out this algorithm think interesting and creative uses for it.
### Improving Voronoi
In 2011, [Stefan Gustavson optimized Steven Worley's algorithm to GPU](http://webstaff.itn.liu.se/~stegu/GLSL-cellular/GLSL-cellular-notes.pdf) by only iterating trough a 2x2 matrix instead of 3x3. This reduce the work significantly but can create artifacts in form of discontinuities. Take a look to the following examples.
In 2011, [Stefan Gustavson optimized Steven Worley's algorithm to GPU](http://webstaff.itn.liu.se/~stegu/GLSL-cellular/GLSL-cellular-notes.pdf) by only iterating trough a 2x2 matrix instead of 3x3. This reduces the amount of work significantly, but it can create artifacts in the form of discontinuities at the edges between the tiles. Take a look to the following examples.
<div class="glslGallery" data="12/2d-cnoise-2x2,12/2d-cnoise-2x2x2,12/2d-cnoise,12/3d-cnoise" data-properties="clickRun:editor,openFrameIcon:false"></div>
Later in 2012 [Inigo Quilez wrote an article on how to make precise voronoi borders](http://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm).
Later in 2012 [Inigo Quilez wrote an article on how to make precise Voronoi borders](http://www.iquilezles.org/www/articles/voronoilines/voronoilines.htm).
<a href="../edit.php#12/2d-voronoi.frag"><img src="2d-voronoi.gif" width="520px" height="200px"></img></a>
Inigio's experiment on voronoi didn't stop there. In 2014 he wrote this nice article about what he call [voro-noise](http://www.iquilezles.org/www/articles/voronoise/voronoise.htm), and exploration between regular noise and voronoi. In his words:
Inigo's experiments with Voronoi didn't stop there. In 2014 he wrote this nice article about what he calls [voro-noise](http://www.iquilezles.org/www/articles/voronoise/voronoise.htm), an function thatallows a gradual blend between regular noise and voronoi. In his words:
*"Despite this similarity, the fact is that the way the grid is used in both patterns is different. Noise interpolates/averages random values (as in value noise) or gradients (as in gradient noise), while Voronoi computes the distance to the closest feature point. Now, smooth-bilinear interpolation and minimum evaluation are two very different operations, or... are they? Can they perhaps be combined in a more general metric? If that was so, then both Noise and Voronoi patterns could be seen as particular cases of a more general grid-based pattern generator?"*
<a href="../edit.php#12/2d-voronoise.frag"><canvas id="custom" class="canvas" data-fragment-url="2d-voronoise.frag" width="520px" height="200px"></canvas></a>
Now is up to look closely at things, be inspired by nature to find your own voice on this technique.
Now it's time for you to look closely at things, be inspired by nature and find your own take on this technique!
![Deyrolle glass film - 1831](DeyrolleFilm.png)

View File

@ -2,41 +2,43 @@
## Fractal Brownian Motion
Noise tends to means different things for different people. Musicians will think it in disturbing sounds, communicators as interference and astrophysics as cosmic microwave background. In fact most of this concept have one things in common that bring as back to the begining of random. Waves and their properties. Audio or electromagnetical waves, fluctuation overtime of a signal. That change happens in amplitud and frequency. The ecuation for it looks like this:
Noise tends to mean different things to different people. Musicians will think of it in terms of disturbing sounds, communicators as interference and astrophysicists as cosmic microwave background radiation. These concepts bring us back to the physical reasons behind randomness in the world around us. However, let's start with something more fundamental, and more simple: waves and their properties. A wave is a fluctuation over time of some property. Audio waves are fluctuations in air pressure, electromagnetical waves are fluctuations in electrical and magnetic fields. Two important characteristics of a wave are its amplitude and frequency. The equation for a simple linear (one-dimensional) wave looks like this:
<div class="simpleFunction" data="
float amplitud = 1.;
float amplitude = 1.;
float frequency = 1.;
y = amplitud * sin(x * frequency);
y = amplitude * sin(x * frequency);
"></div>
* Try changing the values of the frequency and amplitud to understand how they behave.
* Using shaping functions try changing the amplitud overtime.
* Using shaping function try changing the frequency overtime.
* Try changing the values of the frequency and amplitude to understand how they behave.
* Using shaping functions, try changing the amplitud over time.
* Using shaping functions, try changing the frequency over time.
By doing the last to excersize you have manage to "modulate" a sine wave, and you just create AM (amplitud modulated) and FM (frequency modulated) waves. Congratulations!
By doing the last two exercises you have managed to "modulate" a sine wave, and you just created AM (amplitude modulated) and FM (frequency modulated) waves. Congratulations!
Another interesting property of waves is their ability to add up. Comment/uncomment and tweak the following lines. Pay atention on how the frequencies and amplitudes change conform we add different waves.
Another interesting property of waves is their ability to add up, which is formally called superposition. Comment/uncomment and tweak the following lines. Pay attention to how the overall appearance changes as we add waves of different amplitudes and frequencies together.
<div class="simpleFunction" data="
float amplitud = 1.;
float amplitude = 1.;
float frequency = 1.;
y = amplitud * sin(x * frequency);
y = sin(x * frequency);
float t = 0.01*(-u_time*130.0);
y += sin(x*2.1 + t)*4.5;
y += sin(x*1.72 + t*1.121)*4.0;
y += sin(x*2.221 + t*0.437)*5.0;
y += sin(x*3.1122+ t*4.269)*2.5;
y *= 0.06;
y += sin(x*frequency*2.1 + t)*4.5;
y += sin(x*frequency*1.72 + t*1.121)*4.0;
y += sin(x*frequency*2.221 + t*0.437)*5.0;
y += sin(x*frequency*3.1122+ t*4.269)*2.5;
y *= amplitude*0.06;
"></div>
* Experiment by changing their values.
* Is it possible to cancel two waves? how that will look like?
* Experiment by changing the frequency and amplitude for the additional waves.
* Is it possible to make two waves cancel each other out? What will that look like?
* Is it possible to add waves in such a way that they will amplify each other?
In music, each note is asociated with specific a frequency. This frequencies seams to respond to a pattern where it self in what we call scale.
In music, each note is associated with a specific frequency. The frequencies for these notes follow a pattern which we call a scale, where a doubling or halving of the frequency corresponds to a jump of one octave.
By adding different iterations of noise (*octaves*), where in each one increment the frequencies (*Lacunarity*) and decreasing amplitude (*gain*) of the **noise** we can obtain a bigger level of granularity on the noise. This technique is call Fractal Brownian Motion (*fBM*) and in it simplest form looks like the following code
Now, let's use Perlin noise instead of a sine wave! Perlin noise in its basic form has the same general look and feel as a sine wave. Its amplitude and frequency vary somewhat, but the amplitude remains reasonably consistent, and the frequency is restricted to a fairly narrow range around a center frequency. It's not as regular as a sine wave, though, and it's easier to create an appearance of randomness by summing up several scaled versions of noise. It is possible to make a sum of sine waves appear random as well, but it takes many different waves to hide their periodic, regular nature.
By adding different iterations of noise (*octaves*), where we successively increment the frequencies in regular steps (*lacunarity*) and decrease the amplitude (*gain*) of the **noise** we can obtain a finer granularity in the noise and get more fine detail. This technique is called "fractal Brownian Motion" (*fBM*), or simply "fractal noise", and in its simplest form it can be created by the following code:
<div class="simpleFunction" data="// Properties
const int octaves = 1;
@ -44,39 +46,39 @@ float lacunarity = 2.0;
float gain = 0.5;
//
// Initial values
float amplitud = 0.5;
float frequency = x;
float amplitude = 0.5;
float frequency = 1.;
//
// Loop of octaves
for (int i = 0; i < octaves; i++) {
&#9;y += amplitud * noise(frequency);
&#9;y += amplitude * noise(frequency*x);
&#9;frequency *= lacunarity;
&#9;amplitud *= gain;
&#9;amplitude *= gain;
}"></div>
* Progressively change the number of octaves to iterate from 1 to 2, 4, 8 and 10. See want happens.
* With over 4 octaves try changing the lacunarity value.
* Also with over 4 octaves change the gain value and see what happens.
* Progressively change the number of octaves to iterate from 1 to 2, 4, 8 and 10. See what happens.
* When you have more than 4 octaves, try changing the lacunarity value.
* Also with >4 octaves, change the gain value and see what happens.
Note how each in each octave the noise seams to have more detail. Also note the self similarity while more octaves are added.
Note how with each additional octave, the curve seems to get more detail. Also note the self-similarity while more octaves are added. If you zoom in on the curve, a smaller part looks about the same as the whole thing, and each section looks more or less the same as any other section. This is an important property of mathematical fractals, and we are simulating that property in our loop. We are not creating a *true* fractal, because we stop the summation after a few iterations, but theoretically speaking, we would get a true mathematical fractal if we allowed the loop to continue forever and add an infinite number of noise components. In computer graphics, we always have a limit to how small details we can resolve, for example when objects become smaller than a pixel, so there is no need to make infinite sums to create the appearance of a fractal. A lot of terms may be needed sometimes, but never an infinite number.
The following code is an example of how fBm could be implemented on two dimensions.
The following code is an example of how fBm could be implemented in two dimensions to create a fractal-looking pattern:
<div class='codeAndCanvas' data='2d-fbm.frag'></div>
* Reduce the numbers of octaves by changing the value on line 37
* Reduce the number of octaves by changing the value on line 37
* Modify the lacunarity of the fBm on line 47
* Explore by changing the gain on line 48
This techniques is use commonly to construct procedural landscapes. The self similarity of the fBm is perfect for mountains. If you are interested in this use you defenetly should read [this great article of Inigo Quiles about advance noise](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm).
This technique is commonly used to construct procedural landscapes. The self-similarity of the fBm is perfect for mountains, because the erosion processes that create mountains work in a manner that yields this kind of self-similarity across a large range of scales. If you are interested in this, use you should definitly read [this great article by Inigo Quiles about advance noise](http://www.iquilezles.org/www/articles/morenoise/morenoise.htm).
![Blackout - Dan Holdsworth (2010)](holdsworth.jpg)
Using escentially the same technique is also possible to obtain other effect like what is known as **turbulence**. It's esentially a fBm but constructed from the absolute value of a signed noise.
Using more or less the same technique, is also possible to obtain other effects like what is known as **turbulence**. It's essentially an fBm, but constructed from the absolute value of a signed noise to create sharp valleys in the function.
```glsl
for (int i = 0; i < OCTAVES; i++) {
value += amplitud * abs(snoise(st));
value += amplitude * abs(snoise(st));
st *= 2.;
amplitud *= .5;
}
@ -84,7 +86,7 @@ for (int i = 0; i < OCTAVES; i++) {
<a href="../edit.php#13/turbulence.frag"><img src="turbulence-long.png" width="520px" height="200px"></img></a>
Another member of this family of algorithms is the **ridge**. Constructed similarly to the turbolence but with some extra calculations:
Another member of this family of algorithms is the **ridge**, where the sharp valleys are turned upside down to create sharp ridges instead:
```glsl
n = abs(n); // create creases
@ -94,12 +96,16 @@ Another member of this family of algorithms is the **ridge**. Constructed simila
<a href="../edit.php#13/ridge.frag"><img src="ridge-long.png" width="520px" height="200px"></img></a>
Another variant which can create useful variations is to multiply the noise components together instead of adding them. It's also interesting to scale subsequent noise functions with something that depends on the previous terms in the loop. When we do things like that, we are moving away from the strict definition of a fractal and into the relatively unknown field of "multifractals". Multifractals are not as strictly defined mathematically, but that doesn't make them less useful for graphics. In fact, multifractal simulations are very common in modern commercial software for terrain generation. For further reading, you could read chapter 16 of the book "Texturing and Modeling: a Procedural Approach" (3rd edition), by Kenton Musgrave. Sadly, that book is out of print since a few years back, but you can still find it in libraries and on the second hand market. (There's a PDF version of the 1st edition available for purchase online, but don't buy that - it's a waste of money. It's from 1994, and it doesn't contain any of the terrain modeling stuff from the 3rd edition.)
### Domain Warping
[Inigo Quiles wrote this other fascinating article](http://www.iquilezles.org/www/articles/warp/warp.htm) about how is possible to use fBm to warp a space of a fBm. Mind blowing, Right? Is like the dream inside the dream of Inception.
![ f(p) = fbm( p + fbm( p + fbm( p ) ) ) - Inigo Quiles (2002)](quiles.jpg)
A mild example of this technique is the following code where the wrap is use to produce something this clouds-like texture. Note how the self similarity propertie still is apreciated.
A less extreme example of this technique is the following code where the wrap is use to produce something this clouds-like texture. Note how the self-similarity property is still present in the result.
<div class='codeAndCanvas' data='clouds.frag'></div>
Warping the texture coordinates with noise in this manner can be very useful, a lot of fun, and fiendishly difficult to master. It's a powerful tool, but it takes quite a bit of experience to use it well. A useful tool for this is to displace the coordinates with the derivative (gradient) of noise. [A famous article by Ken Perlin and Fabrice Neyret called "flow noise"](http://evasion.imag.fr/Publications/2001/PN01/) is based on this idea. Some modern implementations of Perlin noise include a variant that computes both the function and its analytical gradient. If the "true" gradient is not available for a procedural function, you can always compute finite differences to approximate it, although that is less accurate and involves more work.

View File

@ -26,8 +26,9 @@
<ul class="navigationBar" >
<li class="navigationBar" onclick="previusPage()">&lt; &lt; Previous</li>
<li class="navigationBar" onclick="homePage()"> Home </li>
<li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li>
</ul>';
include($path."/footer.php");
?>
<!-- <li class="navigationBar" onclick="nextPage()">Next &gt; &gt;</li> -->

BIN
15/Prokudin-Gorskii-00.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

BIN
15/Prokudin-Gorskii-01.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
15/Prokudin-Gorskii-02.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
15/Prokudin-Gorskii-03.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
15/Prokudin-Gorskii-04.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
15/Prokudin-Gorskii-05.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
15/Prokudin-Gorskii-06.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

BIN
15/Prokudin-Gorskii-07.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
15/Prokudin-Gorskii-08.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
15/Prokudin-Gorskii-09.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

View File

@ -56,7 +56,7 @@ Esta es una guía paso a paso a través del abstracto y complejo universo de los
* [Apéndice:](appendix/) Otras formas de usar este libro
* [¿Cómo puedo ver el libro offline?](appendix/)
* [¿Cómo puedo correr los ejemplos en una RaspberryPi?](appendix/)
* [¿Cómo puedo correr los ejemplos en una Raspberry Pi?](appendix/)
* [¿Cómo imprimir este libro?](appendix/)
* [Galería de ejemplos](examples/)

View File

@ -56,7 +56,7 @@ Ceci est un guide étape-par-étape à travers le monde abstrait et complexe des
* [Appendice:](appendix/) Autres manières d'utiliser ce livre
* [Comment puis-je consulter ce livre hors-ligne?](appendix/)
* [Comment exécuter les exemples sur un RaspberryPi?](appendix/)
* [Comment exécuter les exemples sur un Raspberry Pi?](appendix/)
* [Comment imprimer ce livre?](appendix/)
* [Galerie d'exemples](examples/)

View File

@ -1,7 +1,7 @@
<canvas id="custom" class="canvas" data-fragment-url="src/moon/moon.frag" data-textures="src/moon/moon.jpg" width="350px" height="350px"></canvas>
# The Book of Shaders
*di [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/)*
*di [Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) e [Jen Lowe](http://jenlowe.net/)*
Questa è una guida passo passo attraverso l'universo astratto e complesso dei Fragment Shaders.
@ -15,9 +15,9 @@ Questa è una guida passo passo attraverso l'universo astratto e complesso dei F
* Introduzione
* [Che cosa è uno shader?](01/?lan=it)
* ["Hello world!"](02/?lan=it)
* ["Ciao mondo!"](02/?lan=it)
* [Uniforms](03/?lan=it)
* [Esegui il tuo shader](04/?lan=it)
* [Eseguite il vostro shader](04/?lan=it)
* Disegno algoritmico
* [Le funzioni di forma](05/?lan=it)
@ -29,6 +29,7 @@ Questa è una guida passo passo attraverso l'universo astratto e complesso dei F
* Progettazione generativa
* [Random](10/?lan=it)
* [Rumore](11/?lan=it)
* Rumore cellulare
* Moto browniano frazionario
* Frattali
@ -42,9 +43,9 @@ Questa è una guida passo passo attraverso l'universo astratto e complesso dei F
* Simulazione
* Pingpong
* Conway
* Ripples
* Water color
* Reaction diffusion
* Increspature
* Acquerello
* Reazione-diffusione
* Grafica 3D
* Luci
@ -55,10 +56,11 @@ Questa è una guida passo passo attraverso l'universo astratto e complesso dei F
* Riflesso e rifrazione
* [Appendice:](appendix/) Altri modi per utilizzare questo libro
* [Come posso consultare questo libro offline?](appendix/)
* [Come posso far andare gli esempi su un RaspberryPi?](appendix/)
* [Come posso stampare questo libro?](appendix/)
* [Come posso collaborare?](appendix/)
* [Come posso consultare questo libro offline?](appendix/00/?lan=it)
* [Come posso eseguire gli esempi su un Raspberry Pi?](appendix/01/?lan=it)
* [Come posso stampare questo libro?](appendix/02/?lan=it)
* [Come posso collaborare a questo libro?](appendix/03/?lan=it)
* [Un'introduzione per chi proviene da JS](appendix/04/) di [Nicolas Barradeau](http://www.barradeau.com/)
* [Galleria d'esempi](examples/)
@ -68,30 +70,36 @@ Questa è una guida passo passo attraverso l'universo astratto e complesso dei F
[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) (1982, Buenos Aires, Argentina) è un artista e sviluppatore con sede a New York. Esplora lo spazio interstiziale fra organico e sintetico, analogico e digitale, individuale e collettivo. Nel suo lavoro usa il codice come un linguaggio espressivo con l'intenzione di creare un migliore vivere insieme.
Patricio studiò e praticò la psicoterapia e l'arteterapia. Ha conseguito un MFA in Design e Tecnologia alla Parsons The New School. dove ora insegna. Attualmente lavora come Ingegnere Grafico alla Mapzen realizzando strumenti cartografici openSource.
Patricio studiò e praticò la psicoterapia e l'arteterapia. Ha conseguito un MFA in Design e Tecnologia alla Parsons The New School dove ora insegna. Attualmente lavora come Ingegnere Grafico alla Mapzen realizzando strumenti cartografici openSource.
<div class="header"><a href="https://twitter.com/patriciogv" target="_blank">Twitter</a> - <a href="https://github.com/patriciogonzalezvivo" target="_blank">GitHub</a> - <a href="https://vimeo.com/patriciogv" target="_blank">Vimeo</a> - <a href="https://www.flickr.com/photos/106950246@N06/" target="_blank"> Flickr</a></div>
<div class="header"> <a href="http://patriciogonzalezvivo.com/" target="_blank">WebSite</a> - <a href="https://twitter.com/patriciogv" target="_blank">Twitter</a> - <a href="https://github.com/patriciogonzalezvivo" target="_blank">GitHub</a> - <a href="https://vimeo.com/patriciogv" target="_blank">Vimeo</a> - <a href="https://www.flickr.com/photos/106950246@N06/" target="_blank"> Flickr</a></div>
[Jen Lowe](http://jenlowe.net/) è una scienziata indipendente e comunicatrice di dati alla Datatelling dove riunisce persone + numeri + parole. Insegna alla SVA's Design per il programma di Social Innovation, ha co-fondato la School for Poetic Computation, ha insegnato Matematica per Artisti al NYU ITP, ha fatto della ricerca al Spatial Information Design Lab presso la Columbia University, e ha contribuito con idee alla White House Office of Science and Technology Policy. Ha parlato al SXSW e Eyeo. Il suo lavoro è stato trattato dal The New York Times and Fast Company. La sua ricerca, i suoi scritti e la sue dissertazioni esplorano le promesse e le implicazioni dei dati e della tecnologia nella società. Ha una laurea triennale in Matematica Applicata e una laurea specialistica in Scienze Informatiche. Spesso combattiva, è sempre dalla parte dell'amore.
<div class="header"> <a href="http://jenlowe.net/" target="_blank">WebSite</a> - <a href="https://twitter.com/datatelling" target="_blank">Twitter</a> - <a href="https://github.com/datatelling" target="_blank">GitHub</a></div>
## Ringraziamenti
Grazie a mia moglie [Jen Lowe](http://www.datatelling.com/), per il suo incondizionato supporto, aiuto e tempo nel rivedere questo libro.
Grazie a [Scott Murray](http://alignedleft.com/) per l'ispirazione e i consigli.
Grazie [Scott Murray](http://alignedleft.com/) per l'ispirazione e i consigli.
Grazie a [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo), a [Nicolas Barradeau](https://twitter.com/nicoptere), a [Karim Naaji](http://karim.naaji.fr/) per aver contribuito con il loro sostegno, con delle buone idee e con del codice.
Grazie [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) e [Sawako](https://twitter.com/sawakohome) per la [traduzione giapponese (日本語訳)](?lan=jp)
Grazie a [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) e a [Sawako](https://twitter.com/sawakohome) per la [traduzione giapponese (日本語訳)](?lan=jp)
Grazie [Tong Li](https://www.facebook.com/tong.lee.9484) e [Yi Zhang](https://www.facebook.com/archer.zetta?pnref=story) per la [traduzione cinese (中文版)](?lan=ch)
Grazie a [Tong Li](https://www.facebook.com/tong.lee.9484) e a [Yi Zhang](https://www.facebook.com/archer.zetta?pnref=story) per la [traduzione cinese (中文版)](?lan=ch)
Grazie [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) per la [traduzione coreana (한국어)](?lan=kr)
Grazie a [Jae Hyun Yoo](https://www.facebook.com/fkkcloud) per la [traduzione (한국어)](?lan=kr) coreana
Grazie [Nahuel Coppero (Necsoft)](http://hinecsoft.com/) per la [traduzione spagnola (español)](?lan=es)
Grazie a [Nahuel Coppero (Necsoft)](http://hinecsoft.com/) per la [traduzione (español)](?lan=es) spagnola
Grazie [Karim Naaji](http://karim.naaji.fr/) che a contribuito con il suo supporto, le sue buone idee e il suo codice.
Grazie a [Nicolas Barradeau](https://twitter.com/nicoptere) e a [Karim Naaji](http://karim.naaji.fr/) per la [traduzione (français)](?lan=fr) francese
Grazie a tutti coloro i quali hanno creduto in questo progetto e [contribuito con correzioni](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) o donazioni.
Grazie a [Andrea Rovescalli](https://www.earove.info) per la [traduzione](?lan=it) italiana
Grazie a tutti coloro i quali hanno creduto in questo progetto e [contribuito con correzioni](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) o donazioni.
## Come ottenere i nuovi capitoli?
Iscriviti alla newsletter o [seguici su Twitter](https://twitter.com/bookofshaders)
<form style="border:1px solid #ccc;padding:3px;text-align:center;" action="https://tinyletter.com/thebookofshaders" method="post" target="popupwindow" onsubmit="window.open('https://tinyletter.com/thebookofshaders', 'popupwindow', 'scrollbars=yes,width=800,height=600');return true"><a href="https://tinyletter.com/thebookofshaders"><p><label for="tlemail">Inserisci il tuo indirizzo di posta elettronica</label></p></a><p><input type="text" style="width:140px" name="email" id="tlemail" /></p><input type="hidden" value="1" name="embed"/><input type="submit" value="Iscriviti" /><p><a href="https://tinyletter.com" target="_blank"></a></p></form>
<form style="border:1px solid #ccc;padding:3px;text-align:center;" action="https://tinyletter.com/thebookofshaders" method="post" target="popupwindow" onsubmit="window.open('https://tinyletter.com/thebookofshaders', 'popupwindow', 'scrollbars=yes,width=800,height=600');return true"><a href="https://tinyletter.com/thebookofshaders"><p><label for="tlemail">Enter your email address</label></p></a><p><input type="text" style="width:140px" name="email" id="tlemail" /></p><input type="hidden" value="1" name="embed"/><input type="submit" value="Subscribe" /><p><a href="https://tinyletter.com" target="_blank"></a></p></form>

View File

@ -1,7 +1,7 @@
<canvas id="custom" class="canvas" data-fragment-url="examples/moon.frag" data-textures="examples/images/moon-texture.jpg" width="350px" height="350px"></canvas>
<canvas id="custom" class="canvas" data-fragment-url="src/moon/moon.frag" data-textures="src/moon/moon.jpg" width="350px" height="350px"></canvas>
# The Book of Shaders
[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/) 
[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/)、[Jen Lowe](http://jenlowe.net/)
この本はフラグメントシェーダーについてのガイドブックです。難解で複雑なフラグメントシェーダーの世界を、一歩一歩わかりやすくご案内します。
@ -34,8 +34,9 @@
* Generative designs
* [ランダム](10/?lan=jp)
* [Noise未訳](11/)
* Fractional brownian motion
* [Noise](11/?lan=jp)
* [Cellular noise](12/)
* [Fractional brownian motion](13/)
* Fractals
* Image processing:
@ -63,7 +64,7 @@
* [Appendix:](appendix/) Other ways to use this book
* [How can I navigate this book offline?](appendix/)
* [How to run the examples on a RaspberryPi?](appendix/)
* [How to run the examples on a Raspberry Pi?](appendix/)
* [How to print this book?](appendix/)
* [Examples Gallery](examples/)
@ -74,9 +75,9 @@
[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/)1982年、アルゼンチン、ブエスアイレス生 はニューヨーク在住のアーティスト/開発者です。有機的なものと人工的なもの、アナログとデジタル、個人と集団の狭間を探求し、プログラミングコードを表現手段としてより良い共存のあり方を模索しています。
パトリシオは心理療法psychotherapyと表現療法expressive art therapyに精通しており、パーソンズ美術大学でデザイン&テクロジーのMFAMaster of Fine Arts - 美術系の修士に相当)を取得しています。現在は[Mapzen](https://mapzen.com/)でグラフィックエンジニアとしてオープンソースのマッピングツールの開発に携わっています。
Patricioは心理療法psychotherapyと表現療法expressive art therapyに精通しており、パーソンズ美術大学でデザイン&テクロジーのMFAMaster of Fine Arts - 美術系の修士に相当)を取得しています。現在は[Mapzen](https://mapzen.com/)でグラフィックエンジニアとしてオープンソースのマッピングツールの開発に携わっています。
<div class="header"><a href="https://twitter.com/patriciogv" target="_blank">Twitter</a> - <a href="https://github.com/patriciogonzalezvivo" target="_blank">GitHub</a> - <a href="https://vimeo.com/patriciogv" target="_blank">Vimeo</a> - <a href="https://www.flickr.com/photos/106950246@N06/" target="_blank"> Flickr</a></div>
<div class="header"> <a href="http://patriciogonzalezvivo.com/" target="_blank">WebSite</a> - <a href="https://twitter.com/patriciogv" target="_blank">Twitter</a> - <a href="https://github.com/patriciogonzalezvivo" target="_blank">GitHub</a> - <a href="https://vimeo.com/patriciogv" target="_blank">Vimeo</a> - <a href="https://www.flickr.com/photos/106950246@N06/" target="_blank"> Flickr</a></div>
## 訳者について

View File

@ -60,7 +60,7 @@
* [Appendix:](appendix/) Other ways to use this book
* [How can I navigate this book offline?](appendix/)
* [How to run the examples on a RaspberryPi?](appendix/)
* [How to run the examples on a Raspberry Pi?](appendix/)
* [How to print this book?](appendix/)
* [Examples Gallery](examples/)

View File

@ -29,8 +29,8 @@ This is a gentle step-by-step guide through the abstract and complex universe of
* Generative designs
* [Random](10/)
* [Noise](11/)
* Cellular noise
* Fractional brownian motion
* [Cellular noise](12/)
* [Fractional brownian motion](13/)
* Fractals
* Image processing:
@ -57,7 +57,7 @@ This is a gentle step-by-step guide through the abstract and complex universe of
* [Appendix:](appendix/) Other ways to use this book
* [How can I navigate this book offline?](appendix/00/)
* [How to run the examples on a RaspberryPi?](appendix/01/)
* [How to run the examples on a Raspberry Pi?](appendix/01/)
* [How to print this book?](appendix/02/)
* [How can I collaborate?](appendix/03/)
* [An introduction for those coming from JS](appendix/04/) by [Nicolas Barradeau](http://www.barradeau.com/)
@ -94,6 +94,8 @@ Thanks [Nahuel Coppero (Necsoft)](http://hinecsoft.com/) for the Spanish [transl
Thanks [Nicolas Barradeau](https://twitter.com/nicoptere) and [Karim Naaji](http://karim.naaji.fr/) for the French [translation (français)](?lan=fr)
Thanks [Andrea Rovescalli](https://www.earove.info) for the Italian [translation (italiano)](?lan=it)
Thanks to everyone who has believed in this project and [contributed with fixes](https://github.com/patriciogonzalezvivo/thebookofshaders/graphs/contributors) or donations.
## Get new chapters

33
appendix/00/README-it.md Normal file
View File

@ -0,0 +1,33 @@
## Come posso consultare questo libro offline?
Diciamo che si dispone di un lungo viaggio e si desidera usarlo per imparare da soli alcuni shaders. In questo caso è possibile effettuare una copia locale di questo libro sul computer ed eseguire un server locale.
Per questo è necessario solo Python 2.6 e un client git. Sui computer MacOS e Raspberry Pi, Python è installato di default, ma è comunque necessario installare un client git. Per fare ciò:
Su **MacOSX** siate sicuri di avere installato [homebrew](http://brew.sh/) e quindi sul terminale fate:
```bash
brew update
brew upgrade
brew install git
```
Su **Raspberry Pi** è necessario fare:
```bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git-core
```
Una volta che avete installato tutto, non vi resta che fare:
```bash
cd ~
git clone --recursive https://github.com/patriciogonzalezvivo/thebookofshaders.git
cd thebookofshaders
git submodule foreach git pull
php -S localhost:8000
```
Quindi aprite il browser e inserite [```http://localhost:8000/```](http://localhost:8000/)

View File

@ -2,7 +2,7 @@
Lets say you have a long trip and you want to use it to teach yourself some shaders. In that case you can make a local copy of this book on your computer and run a local server.
For that you only need Python 2.6 and a git client. On MacOS and RaspberryPi computers Python is installed by default but you still need to install a git client. For that:
For that you only need Python 2.6 and a git client. On MacOS and Raspberry Pi computers Python is installed by default but you still need to install a git client. For that:
In **MacOSX** be sure to have [homebrew](http://brew.sh/) installed and then on your terminal do:
@ -12,7 +12,7 @@ brew upgrade
brew install git
```
On **RaspberryPi** you need to do:
On **Raspberry Pi** you need to do:
```bash
sudo apt-get update

23
appendix/01/README-it.md Normal file
View File

@ -0,0 +1,23 @@
## Come posso eseguire gli esempi su un Raspberry Pi?
Alcuni anni fa, non era del tutto ovvio che tutti disponessero di un computer con una GPU. Ora, nonostante la maggior parte dei computer abbia una carta grafica, non tutti i corsi o classi possono permettersene uno.
Grazie al [progetto Raspberry Pi](http://www.raspberrypi.org/) una nuova generazione di computer piccoli ed economici (circa 35euro ciascuno) ha cominciato a diffondersi nelle aule scolastiche. Ancora più importante ai fini di questo libro, il [Raspberry Pi](http://www.raspberrypi.org/) viene fornito con una scheda GPU Bradcom decente a cui si può accedere direttamente dalla console. Ho creato uno [strumento flessibile per programmare GLSL live chiamato **glslViewer**](https://github.com/patriciogonzalezvivo/glslViewer) capace di far funzionare tutti gli esempi di questo libro. Questo programma è anche capace di aggiornare automaticamente le modifiche che l'utente fa quando le salva. Cosa significa? è possibile modificare lo shader e ogni volta che lo si salva, lo shader sarà ricompilato e visualizzato per voi.
Facendo una copia locale del repository di questo libro (vedi paragrafo precedente) e con [```glslViewer``` installato](https://github.com/patriciogonzalezvivo/glslViewer), gli utenti possono eseguire gli esempi con ```glslviewer```. Inoltre usando il flag ```-l``` si può visualiizare l'esempio in un angolo dello schermo mentre lo si modifica con un qualsiasi editor di testo (come ```nano```, ```pico```, ```vi```, ```vim``` or ```emacs```). Questo funziona anche quando l'utente è collegato tramite ssh/sftp.
Per installare e configurare tutto ciò sul Raspberry Pi, dopo l'installazione del sistema operativo e il login, digitate i seguenti comandi:
```bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git-core
cd ~
git clone http://github.com/patriciogonzalezvivo/glslViewer.git
cd glslViewer
make
make install
cd ~
git clone https://github.com/patriciogonzalezvivo/thebookofshaders.git
cd thebookofshaders
```

View File

@ -1,12 +1,12 @@
## How to run the examples on a RaspberryPi?
## How to run the examples on a Raspberry Pi?
A few years ago, taking for granted that everybody have a computer with a GPU was a long shot. Now, most computers have a graphic unit, but is a high bar for a requirement in for example a course or class.
A few years ago, assuming that everybody has a computer with a graphical processing unit was a long shot. Now, most computers have a GPU, but it's still a high bar for a requirement in a workshop or class, for example.
Thanks to the [RaspberryPi project](http://www.raspberrypi.org/) a new type of small and cheap generation of computers (arround $35 each) has found its way into classrooms. More importantly for the purposes of this book, the [RaspberryPi](http://www.raspberrypi.org/) comes with a decent Bradcom GPU card that can be accessed directly from the console. I made a [flexible GLSL live coding tool call **glslViewer**](https://github.com/patriciogonzalezvivo/glslViewer) that runs all the examples on this book. This program also is hable to update automatically the changes the user makes when they save it. What that means? you can edit the shader and every time you save it, the shader will be re-compile and rendered for you.
Thanks to the [Raspberry Pi Foundation](http://www.raspberrypi.org/) a new type of small and cheap generation of computers (around $35 each) has found its way into classrooms. More importantly for the purposes of this book, the [Raspberry Pi](http://www.raspberrypi.org/) comes with a decent Broadcom GPU that can be accessed directly from the console. I made a [flexible GLSL live coding tool call **glslViewer**](https://github.com/patriciogonzalezvivo/glslViewer) that runs all the examples in this book. This program also has the ability to update automatically when the user saves a change to their code. What does this mean? You can edit the shader and every time you save it, the shader will be re-compile and render for you.
By making a local copy of the repository of this book (see the above section) and having [```glslViewer``` installed](https://github.com/patriciogonzalezvivo/glslViewer), users can run the examples with ```glslviewer```. Also by using the ```-l``` flag they can render the example on a corner of the screen while they modify it with any text editor (like ```nano```, ```pico```, ```vi```, ```vim``` or ```emacs```). This also works if the user is connected through ssh/sftp.
By making a local copy of the repository of this book (see the above section) and having [```glslViewer``` installed](https://github.com/patriciogonzalezvivo/glslViewer), users can run the examples with ```glslviewer```. Also by using the ```-l``` flag they can render the example in a corner of the screen while they modify it with any text editor (like ```nano```, ```pico```, ```vi```, ```vim``` or ```emacs```). This also works if the user is connected through ssh/sftp.
To install and set this all up on the RaspberryPi after installing the OS and logging in, type the following commands:
To install and set this all up on the Raspberry Pi after installing the OS and logging in, type the following commands:
```bash
sudo apt-get update

66
appendix/02/README-it.md Normal file
View File

@ -0,0 +1,66 @@
## Come posso stampare questo libro?
Diciamo che non si vuole navigare o interagire con gli esempi e si desidera solo un buon vecchio libro di testo che si può leggere sulla spiaggia o sul vostro tragitto verso la città. In questo caso è possibile stampare questo libro.
#### Installare glslViewer
Per la stampa di questo libro è necessario in primo luogo trasformarlo. Per questo è necessario [```glslViewer```](https://github.com/patriciogonzalezvivo/glslViewer) uno strumento console per gli shader che compilerà e trasformare gli esempi in immagini.
Su **MacOSX** siate sicuri di avere installato [homebrew](http://brew.sh/) e quindi sul terminale digitate:
```bash
brew update
brew upgrade
brew tap homebrew/versions
brew install glfw3
cd ~
git clone http://github.com/patriciogonzalezvivo/glslViewer.git
cd glslViewer
make
make install
```
Su **Raspberry Pi** è necessario fare:
```bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install git-core
cd ~
git clone http://github.com/patriciogonzalezvivo/glslViewer.git
cd glslViewer
make
make install
```
#### Installare Latex Engine e Pandoc
Per trasformare i capitoli Markdown in Latex e poi in un file PDF useremo Xetex Latex Engine e Pandoc.
Su **MacOSX**:
Scarica e Installa [basictex & MacTeX-Additions](http://www.tug.org/mactex/morepackages.html) e poi installa [Pandoc](http://johnmacfarlane.net/pandoc/) facendo:
```bash
brew install pandoc
```
Su **Raspberry Pi**:
```bash
sudo apt-get install texlive-xetex pandoc
```
#### Trasforma il libro in un pdf e stampalo
Ora che avete tutto ciò che serve, è il momento di clonare la [repository di questo libro](https://github.com/patriciogonzalezvivo/thebookofshaders) e compilare il libro.
A tale scopo aprite il terminale e digitate:
```bash
cd ~
git clone https://github.com/patriciogonzalezvivo/thebookofshaders.git
cd thebookofshaders
make
```
Se tutto va bene, si vedrà un file ```book.pdf``` che potete leggere sul vostro dispositivo preferito o stampare.

View File

@ -21,7 +21,7 @@ make
make install
```
On **RaspberryPi** you need to do:
On **Raspberry Pi** you need to do:
```bash
sudo apt-get update
@ -46,7 +46,7 @@ Download and Install [basictex & MacTeX-Additions](http://www.tug.org/mactex/mor
brew install pandoc
```
On **RaspberryPi**:
On **Raspberry Pi**:
```bash
sudo apt-get install texlive-xetex pandoc

63
appendix/03/README-it.md Normal file
View File

@ -0,0 +1,63 @@
## Come posso collaborare a questo libro?
Grazie per voler collaborare! Ci sono vari modi per poterlo fare:
- Tradurre i contenuti
- Migliorare la [sezione ```glossario/```](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/glossary)
- Modificare i contenuti
- Condividere i vostri esempi di shaders attraverso[l'editor on-line](http://editor.thebookofshaders.com/)
### Tradurre i contenuti
Questo libro è scritto nel [linguaggio Markdown](https://daringfireball.net/projects/markdown/syntax) quindi è molto facile da modificare e lavorare su di esso.
1. Iniziate andando alla [repository di GitHub ```github.com/patriciogonzalezvivo/thebookofshaders```](https://github.com/patriciogonzalezvivo/thebookofshaders). Date un'occhiata ai file e alle cartelle al suo interno. Si noti che il contenuto è presente nei file ```README.md``` e negli altri con lettere maiuscole come:```TITLE.md```, ```SUMMARY.md```, ecc. Si noti inoltre che le traduzioni sono contenute in file che terminano con due lettere che fanno riferimento alla lingua che sono tradotte, es .: ```README-jp.md```, ```README-es.md```, ecc.
2. Biforcare ("Fork") la repository e clonatela ("Clone") sul vostro computer.
3. Duplicate il contenuto dei file da tradurre. Ricordatevi di aggiungere ai file su cui si sta lavorando le due lettere che fanno riferimento alla lingua che si sta traducendo.
4. Traducete linea per linea i contenuti (vedi **Note di traduzione**).
5. Testate le pagine tradotte (vedi **Test**).
6. Inviate ("Push") i vostri commit alla biforcazione ("Fork") della vostra repository su GitHub, per poi fare un [Pull Request](https://help.github.com/articles/about-pull-requests/)
#### Note di traduzione
Non cancellate o modificate gli esempi integrati alla pagina, che assomigliano a questo codice:
```html
<div class="codeAndCanvas" data="grid-making.frag"></div>
```
oppure
```html
<div class="simpleFunction" data="y = mod(x,2.0);"></div>
```
#### Testare
Iniziate l'esecuzione di un server locale PHP all'interno della cartella locale:
```bash
php -S localhost:8000
```
Poi, nel tuo browser aprite la pagina ```localhost:8000```, andate al capitolo che state traducendo e aggiungete ```?lan=``` seguito dal codice della lingua in cui state traducendo.
Per esempio se si sta traducendo il capitolo ```03``` in francese, starete lavorando sul file```03/README-fr.md``` e lo si può testare andando alla pagina: ```http://localhost:8000/03/?lan=fr```
### Migliorare la sezione glossario
Questa sezione è in fase di sviluppo. Siamo lieti di ascoltare le vostre idee su come rendere uno strumento intuitivo per tutti. Inviaci un messaggio a [@bookofshaders](https://twitter.com/bookofshaders).
### Modifica il contenuto
Siamo tutti esseri umani. Se vedete qualcosa, ditelo e fate un Pull Request oppure aprite un problema su GitHub. Grazie!
### Condividete i vostri esempi di shaders
Vedrete un sacco di link verso [l'editor on-line](http://editor.thebookofshaders.com/) e verso delle sue istanze integrate alla pagina.
Una volta che si scrive un codice che vi rende orgoglioso, fate clic su "Esporta" (o sull' icona ```⇪```) e quindi copiate l' "URL verso il codice..." ("URL to code..."). Inviatelo a [@bookofshaders](https://twitter.com/bookofshaders) o a [@kyndinfo](https://twitter.com/kyndinfo). Non vediamo l'ora di vederlo e aggiungerlo alla [sezione galleria di esempi](https://thebookofshaders.com/examples/).

View File

@ -1,17 +1,17 @@
## How can I collaborate with this book?
Thanks for be willing to collaborate! There are plenty of ways you can:
Thanks for being willing to collaborate! There are plenty of ways you can:
- Translating content
- Improving the [```glossary/``` section](https://github.com/patriciogonzalezvivo/thebookofshaders/tree/master/glossary)
- Editing content
- Sharing your shaders examples trough [the on-line editor](http://editor.thebookofshaders.com/) to
- Sharing your shaders examples through [the on-line editor](http://editor.thebookofshaders.com/) to
### Translating content
This book is wrote in [Markdown language](https://daringfireball.net/projects/markdown/syntax) so it's very easy to edit and work on it.
This book is written in [Markdown language](https://daringfireball.net/projects/markdown/syntax) so it's very easy to edit and work on it.
1. Start by going to [github's repository at ```github.com/patriciogonzalezvivo/thebookofshaders```](https://github.com/patriciogonzalezvivo/thebookofshaders). Take a look the files and folders inside it. You will note that the content is on the ```README.md``` and others files with capital letters like: ```TITLE.md```, ```SUMMARY.md```, etc. Also note that translations are hosted on files ending in two letters referencing the language they are on, ex.: ```README-jp.md```, ```README-es.md```, etc.
1. Start by going to [github's repository at ```github.com/patriciogonzalezvivo/thebookofshaders```](https://github.com/patriciogonzalezvivo/thebookofshaders). Take a look at the files and folders inside it. You will note that the content is in the ```README.md``` and other files with capital letters like: ```TITLE.md```, ```SUMMARY.md```, etc. Also note that translations are hosted in files with names ending in two letters referencing the language they are for, ex.: ```README-jp.md```, ```README-es.md```, etc.
2. Fork the repository and clone it in your computer.
@ -25,7 +25,7 @@ This book is wrote in [Markdown language](https://daringfireball.net/projects/ma
#### Translating notes
Do not erase or modify things the embebed examples, that looks like this:
Do not erase or modify things the embedded examples, that looks like this:
```html
<div class="codeAndCanvas" data="grid-making.frag"></div>
@ -45,13 +45,13 @@ Start running a local PHP server inside the local repository folder:
php -S localhost:8000
```
Then in your browser search for ```localhost:8000``` go to the chapter you are translating and add ```?lan=``` followed by the to letters your use to mark the language you are translating to.
Then in your browser search for ```localhost:8000``` go to the chapter you are translating and add ```?lan=``` followed by the two letters you used to mark the language you are translating to.
For examples if you are translate the chapter ```03``` to french you had been working the file ```03/README-fr.md``` and you can test it by going to: ```http://localhost:8000/03/?lan=fr```
For example, if you are translating the chapter ```03``` to french you had been working with the file ```03/README-fr.md``` and you can test it by going to: ```http://localhost:8000/03/?lan=fr```
### Improving the glossary section
This section is under development. We are happy to listen to your ideas on how to make it a friendly tools for all. Send us a message to [@bookofshaders](https://twitter.com/bookofshaders).
This section is under development. We are happy to listen to your ideas on how to make it a friendly tool for all. Send us a message to [@bookofshaders](https://twitter.com/bookofshaders).
### Editing content
@ -59,6 +59,6 @@ We are all humans. If you see something say something and make a Pull Request or
### Sharing your shaders examples
You will see a lot of links to [the on-line editor](http://editor.thebookofshaders.com/) and embebed instances of it.
You will see a lot of links to [the on-line editor](http://editor.thebookofshaders.com/) and embedded instances of it.
Once you code something that makes you proud, click the "Export" (or the ```⇪``` icon) and then copy the "URL to code...". Send it to [@bookofshaders](https://twitter.com/bookofshaders) or [@kyndinfo](https://twitter.com/kyndinfo). We are looking forward to see it and add it to [the example gallery section](https://thebookofshaders.com/examples/).

View File

@ -89,7 +89,7 @@ If the conditional branching is a valid option on the CPU, [the parallel nature]
Using conditionals is even discouraged most of the time, the book explains a couple of alternative techniques to solve this.
#### type casting
As [Aragorn](https://en.wikipedia.org/wiki/Aragorn) put it, "One does not simply combine Typed primitives". Unlike JavaScript, GLSL will not allow you to perform operations between variables of different types.
As [Boromir](https://en.wikipedia.org/wiki/Boromir) put it, "One does not simply combine Typed primitives". Unlike JavaScript, GLSL will not allow you to perform operations between variables of different types.
This for instance:
```glsl

View File

@ -2,7 +2,7 @@
1. [How can I navigate this book off-line?](00/)
2. [How to run the examples on a RaspberryPi?](01/)
2. [How to run the examples on a Raspberry Pi?](01/)
3. [How to print this book?](02/)

View File

@ -97,18 +97,29 @@ img {
color: #999;
}
.header .subtitle {
.toc-header {
font-size: 16px;
line-height: 16px;
margin-top: 24px;
margin-bottom: 24px;
text-align: right;
color: #999;
}
.header .subtitle a{
.header .subtitle {
}
.header .subtitle a,
.toc-header .subtitle a {
font-size: 1.3em;
font-style: italic;
text-decoration: none;
border: 0!important;
}
.header a{
.header a,
.toc-header a {
font-size: 0.8em;
font-style: italic;
text-decoration: none;
@ -228,7 +239,7 @@ code {
margin-left: auto;
margin-right: auto;
max-width: 700px;
}
.simpleFunction .CodeMirror {
@ -359,4 +370,3 @@ code {
font-style: italic;
text-align: right;
}

View File

@ -1,4 +1,4 @@
<?php
<?php
$path = ".";
$subtitle = "";
$README = "README";
@ -12,13 +12,14 @@
}
include("header.php");
include("toc-header.php");
echo '<div id="content">';
include($path."/src/parsedown/Parsedown.php");
$Parsedown = new Parsedown();
echo $Parsedown->text(file_get_contents($README.'.md'));
echo '</div>';
include("footer.php");
?>
?>

3
toc-header.php Normal file
View File

@ -0,0 +1,3 @@
<div class="toc-header">
<p> <a href="?lan=jp">日本</a> - <a href="?lan=ch">中文版</a> - <a href="?lan=kr">한국어</a> - <a href="?lan=es">Español</a> - <a href="?lan=fr">Français</a> - <a href="?lan=it">Italiano</a> - <a href=".">English</a></p>
</div>