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.)
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.
**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.
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.
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, [RaspberryPi](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.
**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).
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).
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 [RaspberryPi](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).
Pour en savoir plus, [cliquez ici](https://github.com/patriciogonzalezvivo/glslViewer).
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, [RaspberryPi](https://www.raspberrypi.org/) e browser, senza la necessità di dover cambiare il vostro codice.
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, [RaspberryPi](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.
**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.
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, [RaspberryPi](https://www.raspberrypi.org/) and browsers without the need of changing your code.
**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.
**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.
@ -10,7 +10,7 @@ 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).
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 [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).
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.
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.
Dopo di che si osservino le due righe commentate. La prima interpola ogni valore random in modo lineare.
@ -39,16 +39,16 @@ Dopo di che si osservino le due righe commentate. La prima interpola ogni valore
y = mix(rand(i), rand(i + 1.0), f);
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.
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?
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.
Ora provate a decommentare la riga seguente, che utilizza una interpolazione [```smoothstep()```](../glossary/?search=smoothstep) invece di una lineare.
```glsl
```glsl
y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
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).
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
```glsl
float u = f * f * (3.0 - 2.0 * f ); // curva cubica personalizzata
float u = f * f * (3.0 - 2.0 * f ); // curva cubica personalizzata
@ -182,7 +182,7 @@ Nel seguente codice è possibile rimuovere il commento alla linea 44 per vedere
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)).
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)).
<divclass="simpleFunction"data="
<divclass="simpleFunction"data="
// Curva Cubica di Hermite. Identica alla funzione SmoothStep()
// Curva Cubica di Hermite. Identica alla funzione SmoothStep()
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.
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);
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?
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
```glsl
y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
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
```glsl
float u = f * f * (3.0 - 2.0 * f ); // custom cubic curve
float u = f * f * (3.0 - 2.0 * f ); // custom cubic curve
@ -154,7 +154,7 @@ For you to practice:
## Improved Noise
## 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)).
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)).
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:
<divclass="simpleFunction"data="
<divclass="simpleFunction"data="
float amplitud = 1.;
float amplitude = 1.;
float frequency = 1.;
float frequency = 1.;
y = amplitud * sin(x * frequency);
y = amplitude* sin(x * frequency);
"></div>
"></div>
* Try changing the values of the frequency and amplitud to understand how they behave.
* Try changing the values of the frequency and amplitude to understand how they behave.
* Using shaping functions try changing the amplitud overtime.
* Using shaping functions, try changing the amplitud overtime.
* Using shaping function try changing the frequency overtime.
* Using shaping functions, try changing the frequency overtime.
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.
<divclass="simpleFunction"data="
<divclass="simpleFunction"data="
float amplitud = 1.;
float amplitude = 1.;
float frequency = 1.;
float frequency = 1.;
y = amplitud * sin(x * frequency);
y = sin(x * frequency);
float t = 0.01*(-u_time*130.0);
float t = 0.01*(-u_time*130.0);
y += sin(x*2.1 + t)*4.5;
y += sin(x*frequency*2.1 + t)*4.5;
y += sin(x*1.72 + t*1.121)*4.0;
y += sin(x*frequency*1.72 + t*1.121)*4.0;
y += sin(x*2.221 + t*0.437)*5.0;
y += sin(x*frequency*2.221 + t*0.437)*5.0;
y += sin(x*3.1122+ t*4.269)*2.5;
y += sin(x*frequency*3.1122+ t*4.269)*2.5;
y *= 0.06;
y *= amplitude*0.06;
"></div>
"></div>
* Experiment by changing their values.
* Experiment by changing the frequency and amplitude for the additional waves.
* Is it possible to cancel two waves? how that will look like?
* 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?
* 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:
<divclass="simpleFunction"data="//Properties
<divclass="simpleFunction"data="//Properties
const int octaves = 1;
const int octaves = 1;
@ -44,39 +46,39 @@ float lacunarity = 2.0;
float gain = 0.5;
float gain = 0.5;
//
//
// Initial values
// Initial values
float amplitud = 0.5;
float amplitude = 0.5;
float frequency = x;
float frequency = 1.;
//
//
// Loop of octaves
// Loop of octaves
for (int i = 0; i <octaves;i++){
for (int i = 0; i <octaves;i++){
	y += amplitud * noise(frequency);
	y += amplitude * noise(frequency*x);
	frequency *= lacunarity;
	frequency *= lacunarity;
	amplitud *= gain;
	amplitude *= gain;
}"></div>
}"></div>
* Progressively change the number of octaves to iterate from 1 to 2, 4, 8 and 10. See want happens.
* Progressively change the number of octaves to iterate from 1 to 2, 4, 8 and 10. See what happens.
* With over 4 octaves try changing the lacunarity value.
* Whenyou have more than 4 octaves, try changing the lacunarity value.
* Also with over 4 octaves change the gain value and see what happens.
* 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:
* 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
* Modify the lacunarity of the fBm on line 47
* Explore by changing the gain on line 48
* 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)
![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
```glsl
for (int i = 0; i <OCTAVES;i++){
for (int i = 0; i <OCTAVES;i++){
value += amplitud * abs(snoise(st));
value += amplitude * abs(snoise(st));
st *= 2.;
st *= 2.;
amplitud *= .5;
amplitud *= .5;
}
}
@ -84,7 +86,7 @@ for (int i = 0; i < OCTAVES; i++) {
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
### 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.
[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)
![ 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.
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.
パトリシオは心理療法(psychotherapy)と表現療法(expressive art therapy)に精通しており、パーソンズ美術大学でデザイン&テクノロジーのMFA(Master of Fine Arts - 美術系の修士に相当)を取得しています。現在は[Mapzen](https://mapzen.com/)でグラフィックエンジニアとしてオープンソースのマッピングツールの開発に携わっています。
Patricioは心理療法(psychotherapy)と表現療法(expressive art therapy)に精通しており、パーソンズ美術大学でデザイン&テクノロジーのMFA(Master of Fine Arts - 美術系の修士に相当)を取得しています。現在は[Mapzen](https://mapzen.com/)でグラフィックエンジニアとしてオープンソースのマッピングツールの開発に携わっています。
Let’s 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.
Let’s 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 RaspberryPi 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:
In **MacOSX** be sure to have [homebrew](http://brew.sh/) installed and then on your terminal do:
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 (around $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 [RaspberryPi](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 RaspberryPi after installing the OS and logging in, type the following commands:
Designing motion in a fragment shader is not straight forward and can be a bit tedious since it is not an animation tool after all. Here are some convenient tools and examples for controlling easing and timing, drawing shapes, and combining all these to create a nice sequence of motion. The first five examples introduce many useful functions that you can use as building blocks for your design. Following examples demonstrate how you can combine these tool to design complex animations.
Designing motion in a fragment shader is not straight forward and can be a bit tedious since it is not an animation tool after all. Here are some convenient tools and examples for controlling easing and timing, drawing shapes, and combining all these to create a nice sequence of motion. The first five examples introduce many useful functions that you can use as building blocks for your design. Following examples demonstrate how you can combine these tool to design complex animations.
Exercises:
* Can you draw different waves using different easing functions, then animate circles following the waves?
* Animate two circles. Can you express difference between different materials through motion? How a metal ball and a plastic ball behave differently?
* Design your character(an animal, monster, spaceship, etc.) by combining shapes and animate it.
* Speed up or down your character animation. Can you make it five times faster or slower than the original?
* Add a new scene to the "wipes" example. How can you make it easy so that you don't have to adjust the timing of all subsequent parts manually?
* The examples here are not necessarily optimized, especially the last one. Try reducing the number of calculation as much as possible. Many functions are running even when the elements they draw are not on-screen. How can you avoid this?