Merge remote-tracking branch 'refs/remotes/patriciogonzalezvivo/master'

pull/116/head
MITI67 8 years ago
commit be4d255b33

@ -41,7 +41,7 @@ Alternativamente, dependiendo cuales sean tus necesidades puedes:
- [Crear una versión offline del libro](https://thebookofshaders.com/appendix/) - [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/) - [Crear un PDF del libro para imprimir.](https://thebookofshaders.com/appendix/)

@ -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/) - [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/) - [créer un PDF du livre pour l'imprimer](https://thebookofshaders.com/appendix/)

@ -48,7 +48,7 @@ Chrome、FirefoxやSafariなどWebGLの使える今時のブラウザーとイ
- [Make an off-line version of this book](https://thebookofshaders.com/appendix/) - [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/) - [Make a PDF of the book to print](https://thebookofshaders.com/appendix/)

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

@ -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/) - [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/) - [Make a PDF of the book to print](https://thebookofshaders.com/appendix/)

@ -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.) 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.

@ -1,7 +1,7 @@
## exécuter vos shaders ## 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. 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. **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 [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). Pour en savoir plus, [cliquez ici](https://github.com/patriciogonzalezvivo/glslViewer).
```bash ```bash

@ -1,6 +1,6 @@
## Eseguite il vostro shader ## 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, [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, [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. **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.

@ -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を使うとシェーダーを単体で、とても簡単に走らせることができます。
もしこれらのフレームワークを使わずにブラウザー以外でシェーダーを試したい場合は、[glslViewer](https://github.com/patriciogonzalezvivo/glslViewer)をダウンロードしてコンパイルしてください。 ```html
このプログラムは本書のサンプルのために特別に設計されたもので、MacOSまたはRasberryPIの上でターミナルから直接実行することできます。 <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)をご覧ください.
![](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**を使う ### **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"```と書かれたスクリプトに注目してください。ここに、この本に登場するシェーダーをコピーして実行することができます。 下記はシェーダーをThree.jsで使うために必要なHTMLとJavascriptのサンプルです。```id="fragmentShader"```と書かれたスクリプトに注目してください。ここに、この本に登場するシェーダーをコピーして実行することができます。
@ -50,7 +82,8 @@
uniforms = { uniforms = {
u_time: { type: "f", value: 1.0 }, 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( { var material = new THREE.ShaderMaterial( {
@ -69,6 +102,11 @@
onWindowResize(); onWindowResize();
window.addEventListener( 'resize', onWindowResize, false ); 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 ) { 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``` と名前を付けてください。 [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; PShader shader;
void setup() { void setup() {

@ -1,6 +1,6 @@
## Running your shader ## 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 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 [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 ```bash
glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -s 1 -o yourOutputImage.png glslViewer yourShader.frag yourInputImage.png —w 500 -h 500 -s 1 -o yourOutputImage.png

@ -31,7 +31,7 @@ y = rand(i); //rand() è spiegata nel capitolo precedente
//y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f)); //y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
"></div> "></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. 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
<div class="codeAndCanvas" data="simplex-grid.frag"></div> <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)). 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=" <div class="simpleFunction" data="
// Curva Cubica di Hermite. Identica alla funzione SmoothStep() // Curva Cubica di Hermite. Identica alla funzione SmoothStep()

@ -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)); //y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
"></div> "></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. 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)).
<div class="simpleFunction" data=" <div class="simpleFunction" data="
// Cubic Hermite Curve. Same as SmoothStep() // Cubic Hermite Curve. Same as SmoothStep()

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

@ -2,41 +2,43 @@
## Fractal Brownian Motion ## 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=" <div class="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 over time.
* Using shaping function try changing the frequency overtime. * 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=" <div class="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:
<div class="simpleFunction" data="// Properties <div class="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++) {
&#9;y += amplitud * noise(frequency); &#9;y += amplitude * noise(frequency*x);
&#9;frequency *= lacunarity; &#9;frequency *= lacunarity;
&#9;amplitud *= gain; &#9;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. * When you 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:
<div class='codeAndCanvas' data='2d-fbm.frag'></div> <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 * 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++) {
<a href="../edit.php#13/turbulence.frag"><img src="turbulence-long.png" width="520px" height="200px"></img></a> <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 ```glsl
n = abs(n); // create creases 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> <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 ### 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.
<div class='codeAndCanvas' data='clouds.frag'></div> <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.

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

@ -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 * [Apéndice:](appendix/) Otras formas de usar este libro
* [¿Cómo puedo ver el libro offline?](appendix/) * [¿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/) * [¿Cómo imprimir este libro?](appendix/)
* [Galería de ejemplos](examples/) * [Galería de ejemplos](examples/)

@ -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 * [Appendice:](appendix/) Autres manières d'utiliser ce livre
* [Comment puis-je consulter ce livre hors-ligne?](appendix/) * [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/) * [Comment imprimer ce livre?](appendix/)
* [Galerie d'exemples](examples/) * [Galerie d'exemples](examples/)

@ -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 # 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 * Generative designs
* [ランダム](10/?lan=jp) * [ランダム](10/?lan=jp)
* [Noise未訳](11/) * [Noise](11/?lan=jp)
* Fractional brownian motion * [Cellular noise](12/)
* [Fractional brownian motion](13/)
* Fractals * Fractals
* Image processing: * Image processing:
@ -63,7 +64,7 @@
* [Appendix:](appendix/) Other ways to use this book * [Appendix:](appendix/) Other ways to use this book
* [How can I navigate this book offline?](appendix/) * [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/) * [How to print this book?](appendix/)
* [Examples Gallery](examples/) * [Examples Gallery](examples/)
@ -74,9 +75,9 @@
[Patricio Gonzalez Vivo](http://patriciogonzalezvivo.com/)1982年、アルゼンチン、ブエスアイレス生 はニューヨーク在住のアーティスト/開発者です。有機的なものと人工的なもの、アナログとデジタル、個人と集団の狭間を探求し、プログラミングコードを表現手段としてより良い共存のあり方を模索しています。 [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>
## 訳者について ## 訳者について

@ -60,7 +60,7 @@
* [Appendix:](appendix/) Other ways to use this book * [Appendix:](appendix/) Other ways to use this book
* [How can I navigate this book offline?](appendix/) * [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/) * [How to print this book?](appendix/)
* [Examples Gallery](examples/) * [Examples Gallery](examples/)

@ -12,7 +12,7 @@ brew upgrade
brew install git brew install git
``` ```
Su **RaspberryPi** è necessario fare: Su **Raspberry Pi** è necessario fare:
```bash ```bash
sudo apt-get update sudo apt-get update

@ -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. 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: 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 brew install git
``` ```
On **RaspberryPi** you need to do: On **Raspberry Pi** you need to do:
```bash ```bash
sudo apt-get update sudo apt-get update

@ -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 (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 [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 ```bash
sudo apt-get update sudo apt-get update

@ -20,7 +20,7 @@ make
make install make install
``` ```
Su **RaspberryPi** è necessario fare: Su **Raspberry Pi** è necessario fare:
```bash ```bash
sudo apt-get update sudo apt-get update
@ -45,7 +45,7 @@ Scarica e Installa [basictex & MacTeX-Additions](http://www.tug.org/mactex/morep
brew install pandoc brew install pandoc
``` ```
Su **RaspberryPi**: Su **Raspberry Pi**:
```bash ```bash
sudo apt-get install texlive-xetex pandoc sudo apt-get install texlive-xetex pandoc

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

@ -2,7 +2,7 @@
1. [How can I navigate this book off-line?](00/) 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/) 3. [How to print this book?](02/)

@ -97,18 +97,29 @@ img {
color: #999; color: #999;
} }
.toc-header {
font-size: 16px;
line-height: 16px;
margin-top: 24px;
margin-bottom: 24px;
text-align: right;
color: #999;
}
.header .subtitle { .header .subtitle {
} }
.header .subtitle a{ .header .subtitle a,
.toc-header .subtitle a {
font-size: 1.3em; font-size: 1.3em;
font-style: italic; font-style: italic;
text-decoration: none; text-decoration: none;
border: 0!important; border: 0!important;
} }
.header a{ .header a,
.toc-header a {
font-size: 0.8em; font-size: 0.8em;
font-style: italic; font-style: italic;
text-decoration: none; text-decoration: none;
@ -284,6 +295,7 @@ code {
} }
.glslGallery_item{ .glslGallery_item{
vertical-align: top;
width: 242px; width: 242px;
margin: 8px; margin: 8px;
} }
@ -294,6 +306,7 @@ code {
} }
.glslGallery_item canvas.glslGallery_canvas{ .glslGallery_item canvas.glslGallery_canvas{
vertical-align: top;
max-width: 242px; max-width: 242px;
} }
@ -357,4 +370,3 @@ code {
font-style: italic; font-style: italic;
text-align: right; text-align: right;
} }

@ -1,5 +1,6 @@
<?php <?php
error_reporting(0);
$path = '..'; $path = '..';
$subtitle = ': Gallery'; $subtitle = ': Gallery';
$language = ''; $language = '';
@ -14,7 +15,6 @@
include('../chap-header.php'); include('../chap-header.php');
echo '<div id="content">'; echo '<div id="content">';
include($path.'/src/parsedown/Parsedown.php'); include($path.'/src/parsedown/Parsedown.php');
$Parsedown = new Parsedown(); $Parsedown = new Parsedown();
@ -22,26 +22,32 @@
if (empty($_GET)) { if (empty($_GET)) {
// Load all the chapters // Load all the chapters
$dirs = array_filter(glob('../??/'), 'is_dir'); $dirs = array_filter(glob('../*/'), 'is_dir');
foreach ($dirs as &$folder) { foreach ($dirs as &$folder) {
$chp = ''; $chp = '';
preg_match("/\.\.\/(\d\d)\//", $folder, $matches); preg_match("/\.\.\/(.+)\//", $folder, $matches);
if (count($matches) > 0) { if (count($matches) > 0) {
$chp = $matches[1]; $chp = $matches[1];
} }
if (file_exists($folder.'TITLE'.$language.'.md') and file_exists($folder.'SUMMARY'.$language.'.md')) { if (file_exists($folder.'TITLE'.$language.'.md') and file_exists($folder.'SUMMARY'.$language.'.md')) {
if (file_exists($folder.'README.md')) {
echo '<a href="'.$folder.'">'; echo '<a href="'.$folder.'">';
echo $Parsedown->text(file_get_contents($folder.'TITLE'.$language.'.md')); echo $Parsedown->text(file_get_contents($folder.'TITLE'.$language.'.md'));
echo '</a>'; echo '</a>';
} else {
echo $Parsedown->text(file_get_contents($folder.'TITLE'.$language.'.md'));
}
if (file_exists($folder.'SUMMARY'.$language.'.md')) { if (file_exists($folder.'SHORT_SUMMARY'.$language.'.md')) {
echo $Parsedown->text(file_get_contents($folder.'SHORT_SUMMARY'.$language.'.md'));
} else if (file_exists($folder.'SUMMARY'.$language.'.md')) {
echo $Parsedown->text(file_get_contents($folder.'SUMMARY'.$language.'.md')); echo $Parsedown->text(file_get_contents($folder.'SUMMARY'.$language.'.md'));
} }
$shaders = array_reverse(glob($folder.'*.frag')); $shaders = array_reverse(glob($folder.'*.frag'));
$shadersTotal = min(count($shaders), 3); $shadersTotal = min(count($shaders), 3);
if ($shadersTotal > 0) { if ($shadersTotal > 0) {
echo '<div class="glslGallery" data="'; echo '<div class="glslGallery" data="';
for ($i = 0; $i < $shadersTotal; $i++) { for ($i = 0; $i < $shadersTotal; $i++) {
@ -52,14 +58,29 @@
} }
echo '" data-properties="clickRun:editor,hoverPreview:false,showAuthor:false,openFrameIcon:false"></div>'; echo '" data-properties="clickRun:editor,hoverPreview:false,showAuthor:false,openFrameIcon:false"></div>';
} }
if (file_exists($folder.'featured_examples.php') and $shaderTotal == 0) {
if (file_exists($folder.'featured_examples.php') and file_exists('FEATURED'.$language.'.md')) { $featuredCode = file_get_contents($folder.'featured_examples.php');
preg_match_all("(\d+)", $featuredCode, $ids);
if (count($ids) > 0) {
echo '<div class="glslGallery" data="';
$numIds = min(count($ids[0]), 3);
for ($i = 0; $i < $numIds; $i++) {
echo $ids[0][$i];
if ($i < $numIds - 1) {
echo ",";
}
}
echo '" data-properties="clickRun:editor,hoverPreview:false,showAuthor:false,openFrameIcon:false"></div>';
$shadersTotal = count($ids[0]);
}
} else if (file_exists($folder.'featured_examples.php') and file_exists('FEATURED'.$language.'.md')) {
include($folder.'featured_examples.php'); include($folder.'featured_examples.php');
$shadersTotal += 3; $shadersTotal += 3;
} }
if (count($shaders) > 3 or $shadersTotal > 3) { if (count($shaders) > 3 or $shadersTotal > 3) {
echo '<p class="more"><a href="/examples/?chapter='.$chp.'">more</a></p>'; echo '<p class="more"><a href="../examples/?chapter='.$chp.'">more</a></p>';
} }
} }
} }
@ -90,7 +111,9 @@
if (file_exists($folder.'featured_examples.php') and file_exists('FEATURED'.$language.'.md')) { if (file_exists($folder.'featured_examples.php') and file_exists('FEATURED'.$language.'.md')) {
if ($shadersTotal != 0) {
echo $Parsedown->text(file_get_contents('FEATURED'.$language.'.md')); echo $Parsedown->text(file_get_contents('FEATURED'.$language.'.md'));
}
include($folder.'featured_examples.php'); include($folder.'featured_examples.php');
} }
} }

@ -13,6 +13,7 @@
include("header.php"); include("header.php");
include("toc-header.php");
echo '<div id="content">'; echo '<div id="content">';
include($path."/src/parsedown/Parsedown.php"); include($path."/src/parsedown/Parsedown.php");

@ -0,0 +1,6 @@
*[kynd](http://www.kynd.info) Sep 9, 2016*
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.

@ -0,0 +1,17 @@
*[kynd](http://www.kynd.info) Sep 9, 2016*
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?

@ -0,0 +1 @@
# MotionToolKit

@ -0,0 +1 @@
<div class="glslGallery" data="160909064320,160909064357,160909064458,160909064528,160909041106,160909064609,160909064651,160909064723,160909064802,160909064829,160909065019,160909065049,160909065147" data-properties="clickRun:editor,hoverPreview:false"></div>

@ -1 +1 @@
Subproject commit 3b02fadfa9a7ff9218382f8ad2334628dad4b742 Subproject commit 22050b571c923a702761844c91d26dfbbd841750

@ -262,7 +262,7 @@ function nextPage() {
window.location.href = url; window.location.href = url;
} }
window.onload = function(){ window.addEventListener("load", function(){
window.scrollTo(0, 0); window.scrollTo(0, 0);
styleCodeBlocks(); styleCodeBlocks();
loadGlslElements(); loadGlslElements();
@ -271,4 +271,4 @@ window.onload = function(){
setTimeout(function () { setTimeout(function () {
window.scrollTo(0, 0); window.scrollTo(0, 0);
}, 500); }, 500);
}; });

@ -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>
Loading…
Cancel
Save