adding Sawako to jp credits

pull/28/head
Patricio Gonzalez Vivo 9 years ago
commit 44a7174986

@ -37,7 +37,7 @@
## GLSLとは
GLSLはopenGL Shading Languageの略で、標準化されたシェーダー言語のつです。これ以降の章ではこの言語を扱います。他にもハードやOSによって異なるシェーダー言語があります。
GLSLはopenGL Shading Languageの略で、標準化されたシェーダー言語の1つです。これ以降の章ではこの言語を扱います。他にもハードやOSによって異なるシェーダー言語があります。
ここからは[クロノスグループ](https://www.khronos.org/opengl/)によって策定されたOpenGLの仕様に基づいて話を進めます。OpenGLの歴史を知っておくと奇妙な訳注プログラミング、言語仕様上の慣習を理解する助けになるかもしれません。[openglbook.com/chapter-0-preface-what-is-opengl.html](http://openglbook.com/chapter-0-preface-what-is-opengl.html)に軽く目を通しておくと良いでしょう。
## なぜシェーダーは厄介だと思われているのか

@ -14,15 +14,15 @@
2. 最終的なピクセルの色は、予約語として確保されたグローバル変数、```gl_FragColor```に割り当てられます。
3. このCによく似た言語には```gl_FragColor```のような組み込みの「変数」や「関数」、「型」があります。このサンプルでは浮動小数点精度を持つ4次元ベクトル```vec4```型が使われています。またこの後、```vec3```、```vec2```のような型や、おなじみの```float```、```int```、```bool```なども登場します。
3. このCによく似た言語には```gl_FragColor```のような組み込みの「変数」や「関数」、「型」があります。このサンプルでは浮動小数点精度を持つ4次元ベクトル ```vec4``` 型が使われています。またこの後、```vec3```、```vec2``` のような型や、おなじみの ```float```、```int```、```bool``` なども登場します。
4. ```vec4```型をよく見ると、4つの引数はそれぞれ赤RedGreen、青Blue、透過度Alphaの各チャンネルに対応していることが分かるでしょう。またこれらの値が正規化されているnormalized、つまり```0.0```から```1.0```の値をとることも読み取れます。後ほど、値が正規化されていると変数間の写像に便利であることを学びます。
4. ```vec4```型をよく見ると、4つの引数はそれぞれ赤RedGreen、青Blue、透過度Alphaの各チャンネルに対応していることが分かるでしょう。またこれらの値が正規化されているnormalized、つまり ```0.0``` から ```1.0``` の値をとることも読み取れます。後ほど、値が正規化されていると変数間の写像に便利であることを学びます。
5. プリプロセッサマクロが使えるのも、このサンプルから読み取れるもう一つの大事な「C言語的」特徴です。マクロはコンパイルの前に処理されます。マクロを使うとグローバル変数を定義```#define```)したり、```#ifdef```と```#endif```を使って場合分けを行うことができます。全てのマクロの命令はハッシュタグ(```#```)で始まります。コンパイルの直前には全ての```#define```の呼び出しが置き換えられ、```#ifdef```や```#ifndef```といった条件文のチェックが行なわれます。上のサンプルでは、```GL_ES```が定義されているときにだけ2行目のコードを挿入します。```GL_ES```は多くの場合、モバイル機器やブラウザー上でコンパイルされたことを意味します。
5. プリプロセッサマクロが使えるのも、このサンプルから読み取れるもう一つの大事な「C言語的」特徴です。マクロはコンパイルの前に処理されます。マクロを使うとグローバル変数を定義```#define```)したり、```#ifdef``` ```#endif``` を使って場合分けを行うことができます。全てのマクロの命令はハッシュタグ(```#```)で始まります。コンパイルの直前には全ての ```#define``` の呼び出しが置き換えられ、```#ifdef``` ```#ifndef``` といった条件文のチェックが行なわれます。上のサンプルでは、```GL_ES``` が定義されているときにだけ2行目のコードを挿入します。```GL_ES``` は多くの場合、モバイル機器やブラウザー上でコンパイルされたことを意味します。
6. 浮動小数点型はシェーダーに不可欠で、その精度はとても重要な意味を持ちます。精度が低いとレンダリングが速くなる代わりに品質が下がります。もしこだわりたければ、GLSLでは浮動小数点を使うそれぞれの変数ごとに精度を指定できます。一行目の```precision mediump float;```は、全ての浮動小数点型の変数に中レベルの精度を指定しています。より低い精度(```precision lowp float;```)や高い精度(```precision highp float;```)を選ぶこともできます。
6. 浮動小数点型はシェーダーに不可欠で、その精度はとても重要な意味を持ちます。精度が低いとレンダリングが速くなる代わりに品質が下がります。もしこだわりたければ、GLSLでは浮動小数点を使うそれぞれの変数ごとに精度を指定できます。一行目の ```precision mediump float;``` は、全ての浮動小数点型の変数に中レベルの精度を指定しています。より低い精度(```precision lowp float;```)や高い精度(```precision highp float;```)を選ぶこともできます。
7. 最後に、そしておそらく一番大切なことですが、GLSLの仕様では変数の自動的な型変換は保証されていません。どういうことでしょう。メーカーは色々な方法でグラフィックカードを高速化しようとしますが、同時に最低限の仕様を満たす必要があります。自動的な型変換はこの最低限の仕様には含まれていません。上のサンプルでは```vec4```型は浮動小数点精度を持っているので、```float```型の値が割り当てられることになっています。コードの一貫性を保ち、真っ白な画面で何時間もデバッグするのを避けるために、浮動小数点型の値には小数点(```.```)を使うことを習慣にしましょう。下記のようなコードはうまく動くとは限りません。
7. 最後に、そしておそらく一番大切なことですが、GLSLの仕様では変数の自動的な型変換は保証されていません。どういうことでしょう。メーカーは色々な方法でグラフィックカードを高速化しようとしますが、同時に最低限の仕様を満たす必要があります。自動的な型変換はこの最低限の仕様には含まれていません。上のサンプルでは ```vec4``` 型は浮動小数点精度を持っているので、```float``` 型の値が割り当てられることになっています。コードの一貫性を保ち、真っ白な画面で何時間もデバッグするのを避けるために、浮動小数点型の値には小数点(```.```)を使うことを習慣にしましょう。下記のようなコードはうまく動くとは限りません。
訳注gl_FragColorはGLSL1.3から非推奨になりました。以降のバージョンでは開発者が自由に名前をつけることができます。この本のサンプルは1.2以前のバージョンで書かれているため、gl_FragColorを出力用の変数として用います
@ -40,7 +40,7 @@ void main() {
* 6行目をコメントアウトして好きな値を関数に割り当ててみましょう。
* 特定の色を返す別の関数を用意して```main()```関数の中で使ってみましょう。ヒント:下記のコードは赤色を返す関数です。
* 特定の色を返す別の関数を用意して ```main()``` 関数の中で使ってみましょう。ヒント:下記のコードは赤色を返す関数です。
```glsl
vec4 red(){
@ -54,4 +54,4 @@ vec4 red(){
vec4 color = vec4(vec3(1.0,0.0,1.0),1.0);
```
この章のサンプルはさほど面白くはありませんが、キャンバス上のピクセルを全て同じ色に変える最も基礎的な例です。この後に続く章ではピクセルの色を2種類の入力、空間画面上のピクセルの位置と時間ページがロードされてから経過した秒数を使って変化させる方法を学びます。
この章のサンプルはさほど面白くはありませんが、キャンバス上のピクセルを全て同じ色に変える最も基礎的な例です。この後に続く章ではピクセルの色を2種類の入力、空間画面上のピクセルの位置と時間ページがロードされてから経過した秒数を使って変化させる方法を学びます。

@ -2,7 +2,7 @@
ここまで、GPUが沢山のスレッドを並列に処理する様子を見てきました。それぞれのスレッドは画像の各部分への色の割り当てを受け持っています。シェーダーではスレッド間の情報のやりとりを行うことはできませんが、CPUからそれぞれのスレッドに入力を送ることはできます。グラフィックカードは全てのスレッドにまったく同じ入力を、読み取り専用で送るように設計されています。それぞれのスレッドは同じデータを受け取り、それを書き換えることはできません。訳注英語の”uniform”には均一な、一様な、という意味があります
これらの入力は```uniform```変数と呼ばれGLSLでサポートされているほとんどの型が使えます。サポートされている型には ```float```、```vec2```、```vec3```、```vec4```、```mat2```、```mat3```、```mat4```、```sampler2D```、```samplerCube```などがあります。
これらの入力は ```uniform``` 変数と呼ばれGLSLでサポートされているほとんどの型が使えます。サポートされている型には ```float```、```vec2```、```vec3```、```vec4```、```mat2```、```mat3```、```mat4```、```sampler2D```、```samplerCube``` などがあります。
uniform変数はシェーダーの冒頭、浮動小数点精度の設定の後に型指定付きで定義します。
```glsl
@ -15,7 +15,7 @@ uniform vec2 u_mouse; // mouse position in screen pixels
uniform float u_time; // Time in seconds since load
```
uniform変数はCPUとGPUの間の小さな架け橋だと考えることができます。変数の名前は実装次第で変わりますが、この本のサンプルでは一貫して```u_time```(シェーダーが開始してから経過した秒数)、```u_resolution```(シェーダーが描画する領域の大きさ)、```u_mouse```描画領域の中のマウスの位置を渡すことにします。ここでは変数の種類を示すためにuniform変数の名前は```u_```で始めるという慣例に従っていますが、他の場所では異なる名前が使われているのも見かけることでしょう。
uniform変数はCPUとGPUの間の小さな架け橋だと考えることができます。変数の名前は実装次第で変わりますが、この本のサンプルでは一貫して```u_time```(シェーダーが開始してから経過した秒数)、```u_resolution```(シェーダーが描画する領域の大きさ)、```u_mouse```描画領域の中のマウスの位置を渡すことにします。ここでは変数の種類を示すためにuniform変数の名前は ```u_``` で始めるという慣例に従っていますが、他の場所では異なる名前が使われているのも見かけることでしょう。
例えば[ShaderToy.com](https://www.shadertoy.com/)では同じ意味を持つuniform変数に下記の名前が付けられています。
@ -31,7 +31,7 @@ uniform float iGlobalTime; // shader playback time (in seconds)
<div class="codeAndCanvas" data="time.frag"></div>
GPUの驚くべき機能の一つとして、角度や三角関数、指数関数などがハードウェア上で高速に処理されることが挙げられます。サポートされる関数には [```sin()```](../glossary/?search=sin)、 [```cos()```](../glossary/?search=cos)、[```tan()```](../glossary/?search=tan)、 [```asin()```](../glossary/?search=asin)、[```acos()```](../glossary/?search=acos)、 [```atan()```](../glossary/?search=atan)、[```pow()```](../glossary/?search=pow)、 [```exp()```](../glossary/?search=exp)、[```log()```](../glossary/?search=log)、 [```sqrt()```](../glossary/?search=sqrt)、[```abs()```](../glossary/?search=abs)、 [```sign()```](../glossary/?search=sign)、[```floor()```](../glossary/?search=floor)、 [```ceil()```](../glossary/?search=ceil)、[```fract()```](../glossary/?search=fract)、 [```mod()```](../glossary/?search=mod)、[```min()```](../glossary/?search=min)、 [```max()```](../glossary/?search=max)、[```clamp()```](../glossary/?search=clamp)などがあります。
GPUの驚くべき機能の1つには、角度や三角関数、指数関数などがハードウェア上で高速に処理されることが挙げられます。サポートされる関数には [```sin()```](../glossary/?search=sin)、 [```cos()```](../glossary/?search=cos)、[```tan()```](../glossary/?search=tan)、 [```asin()```](../glossary/?search=asin)、[```acos()```](../glossary/?search=acos)、 [```atan()```](../glossary/?search=atan)、[```pow()```](../glossary/?search=pow)、 [```exp()```](../glossary/?search=exp)、[```log()```](../glossary/?search=log)、 [```sqrt()```](../glossary/?search=sqrt)、[```abs()```](../glossary/?search=abs)、 [```sign()```](../glossary/?search=sign)、[```floor()```](../glossary/?search=floor)、 [```ceil()```](../glossary/?search=ceil)、[```fract()```](../glossary/?search=fract)、 [```mod()```](../glossary/?search=mod)、[```min()```](../glossary/?search=min)、 [```max()```](../glossary/?search=max)、[```clamp()```](../glossary/?search=clamp) などがあります。
さて、また上のコードで色々と実験をしてみましょう。
@ -39,15 +39,15 @@ GPUの驚くべき機能の一つとして、角度や三角関数、指数関
* 変化のスピードを上げて、点滅がなくなりひとつの色に見えるまで速くしてみましょう。
* つのチャンネルrgbの変化の頻度を別々に変えて、面白いパターンを作ってみましょう。
* 3つのチャンネルrgbの変化の頻度を別々に変えて、面白いパターンを作ってみましょう。
## gl_FragCoord
デフォルトの出力として```vec4 gl_FragColor```を使うことができるのと同様に、GLSLにはデフォルトの入力として画面上の「フラグメント」、つまりピクセルの位置を表す```vec4 gl_FragCoord```が用意されています。```vec4 gl_FragCoord```を使うとスレッドが描画領域内のどこで作業をしているかを知ることができます。この```gl_FragCoord```はスレッドごとに異なる値を持っているためuniform変数とは呼ばず、代わりにvarying変数と呼びます。
デフォルトの出力として ```vec4 gl_FragColor``` を使うことができるのと同様に、GLSLにはデフォルトの入力として画面上の「フラグメント」、つまりピクセルの位置を表す ```vec4 gl_FragCoord``` が用意されています。```vec4 gl_FragCoord``` を使うとスレッドが描画領域内のどこで作業をしているかを知ることができます。この ```gl_FragCoord```はスレッドごとに異なる値を持っているためuniform変数とは呼ばず、代わりにvarying変数と呼びます。
<div class="codeAndCanvas" data="space.frag"></div>
上のサンプルではフラグメントの座標を描画領域全体のサイズで割ることによって正規化しています。こうすると座標値の範囲が```0.0```から```1.0```の間に収まるため、簡単にx座標とy座標の値をrとgのチャンネルに対応させることができます。
上のサンプルではフラグメントの座標を描画領域全体のサイズで割ることによって正規化しています。こうすると座標値の範囲が ```0.0``` から ```1.0``` の間に収まるため、簡単にx座標とy座標の値をrとgのチャンネルに対応させることができます。
シェーダーの世界ではデバッグに使える手段は限られています。判別しやすい色を変数の値に割り当てて確認するのは数少ない方法の一つです。GLSLのコーディングは時としてガラス瓶の中に船の模型を組み立てるのに似ています。どちらも同じくらい難しいですが、結果は美しく達成感があるものです。
@ -55,13 +55,13 @@ GPUの驚くべき機能の一つとして、角度や三角関数、指数関
それでは、サンプルが理解できているか確かめてみましょう。
* 座標```(0.0,0.0)```が描画領域のどこを指すかわかりますか?
* 座標 ```(0.0,0.0)``` が描画領域のどこを指すかわかりますか?
* ```(1.0,0.0)```、```(0.0,1.0)```、```(0.5,0.5)```、```(1.0,1.0)```はどうでしょう?
* ```(1.0,0.0)```、```(0.0,1.0)```、```(0.5,0.5)```、```(1.0,1.0)``` はどうでしょう?
* ```u_mouse```の使い方はわかりますか? ```u_mouse```の値は正規化されていないことに注意してください。この変数を使って色を変化させることはできますか?
* ```u_mouse``` の使い方はわかりますか? ```u_mouse``` の値は正規化されていないことに注意してください。この変数を使って色を変化させることはできますか?
* ```u_time```と```u_mouse```の座標を使って色のパターンを自由に変化させてみましょう。
* ```u_time``` ```u_mouse``` の座標を使って色のパターンを自由に変化させてみましょう。
さて、課題を終えたところで、このシェーダーの力を他にどこで使うことができるのか興味が湧いているのではないでしょうか。
次の章ではオリジナルのシェーダーをthree.js、Processing、openFrameworkで使う方法について説明します。

@ -8,7 +8,7 @@
### **Three.js**を使う
謙虚で才気あふれる[リカルド・カベロ](https://twitter.com/mrdoob)Ricardo Cabello aka 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"```と書かれたスクリプトに注目してください。ここに、この本に登場するシェーダーをコピーして実行することができます。
@ -92,7 +92,7 @@
### **Processing**を使う
[ベン・フライ](http://benfry.com/) Ben Fryと[ケイシー・リース](http://reas.com/) Casey Reasが2001年に開発を始めた[Processing](https://processing.org/) はコーディングを始めるのに最適な、驚くほどシンプルでパワフルな開発環境です(少なくとも私にとってはそうでした)。[アンドレアス・コルブリ](https://codeanticode.wordpress.com/) Andres Colubriは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
PShader shader;
@ -113,7 +113,7 @@ void draw() {
}
```
シェーダーを2.1以前のバージョンで使うには、最初に```#define PROCESSING_COLOR_SHADER```を追加する必要があります。つまり以下の様なプログラムになります。
シェーダーを2.1以前のバージョンで使うには、最初に ```#define PROCESSING_COLOR_SHADER``` を追加する必要があります。つまり以下の様なプログラムになります。
```glsl
#ifdef GL_ES
@ -136,8 +136,7 @@ Processingでシェーダーを使う方法についてより詳しく知りた
### **openFrameworks**を使う
誰にでも落ち着ける場所があるものです。私にとっては今でも[openFrameworks](http://openframeworks.cc/)のコミュニティがそうです。このC++のフレームワークは、openGLやその他のC++のライブラリをラップして使いやすくしてくれます。様々な意味でProcessingに似ていますが、C++のコンパイラを扱う分だけ明らかに複雑です。openFrameworksはProcessingと同様に```data```フォルダー以下のシェーダーのファイルを検索します。サンプルを```shader.frag```にコピーして読み込むようにしてください。
誰にでも落ち着ける場所があるものです。私にとっては今でも[openFrameworks](http://openframeworks.cc/)のコミュニティがそうです。このC++のフレームワークは、openGLやその他のC++のライブラリを内包して使いやすくしてくれます。様々な意味でProcessingに似ていますが、C++のコンパイラを扱う分だけ明らかに複雑です。openFrameworksはProcessingと同様に ```data``` フォルダー以下のシェーダーのファイルを検索します。サンプルを ```shader.frag``` にコピーして読み込むようにしてください。
```cpp
void ofApp::draw(){
@ -152,4 +151,4 @@ void ofApp::draw(){
}
```
openFrameworksでシェーダーを使う方法についてより詳しく知りたい場合は[ジョシュア・ノーブル](https://processing.org/tutorials/pshader/)の[素晴らしいチュートリアル](http://openframeworks.cc/tutorials/graphics/shaders.html) を参照してください。
openFrameworksでシェーダーを使う方法についてより詳しく知りたい場合は[Joshua Noble](https://processing.org/tutorials/pshader/)の[素晴らしいチュートリアル](http://openframeworks.cc/tutorials/graphics/shaders.html) を参照してください。

@ -7,33 +7,33 @@
![ベスト・キッド1984](mr_miyagi.jpg)
私たちにとってミヤギさんの壁に当たるものは、下記に示すコードの枠組みです。この枠組みを使って、正規化されたx座標の値を2種類の方法で目に見えるようにしてみます。1つめの方法では色の明るさを使い黒から白への綺麗なグラデーションを見てください、2つめでは緑色の線を描画しますここではx座標の値をそのままy座標に割り当てています。plot関数のことは今はあまり気にしないでください。すぐ後で詳しく説明します。
私たちにとってミヤギさんの壁に当たるものは、下記に示すコードの枠組みです。この枠組みを使って、正規化されたx座標の値を2種類の方法で目に見えるようにしてみます。1つめの方法では色の明るさを使い黒から白への綺麗なグラデーションを見てください、2つめでは緑色の線を描画しますここではx座標の値をそのままy座標に割り当てています```plot``` 関数のことは今はあまり気にしないでください。すぐ後で詳しく説明します。
<div class="codeAndCanvas" data="linear.frag"></div>
上記のサンプルの20行目と26行目を見てください。
```vec3```型のコンストラクタに値を1つだけ渡すと、コンストラクタは3つの色のチャンネルに同じ値を割りてようとしているのだと解釈します。一方で```vec4```は三次元のベクトルともう1つの値ここではalpha、つまり透明度で初期化されています。
```vec3``` 型のコンストラクタに値を1つだけ渡すと、コンストラクタは3つの色のチャンネルに同じ値を割りてようとしているのだと解釈します。一方で ```vec4``` は三次元のベクトルともう1つの値ここではalpha、つまり透明度で初期化されています。
このコードがミヤギさんの壁です。よく観察して理解しておくことが大切です。この0.0から1.0の空間には何度も立ち帰ることになるでしょう。そしてあなたはいずれ、色と形を操る技をマスターするのです。
このコードがミヤギさんの壁です。よく観察して理解しておくことが大切です。この 0.0 から 1.0 の空間には何度も立ち帰ることになるでしょう。そしてあなたはいずれ、色と形を操る技をマスターするのです。
このサンプルのx座標とy座標または明るさの1対1の対応は線形補間と呼ばれています。
ここから私たちは数学的な関数を使って線を形作っていくことになります。例えばxを5乗すれば曲線を作ることができます。
訳注ここではx=0.0からx=1.0の間のグラフが一次方程式で書ける、つまりグラフが直線になることを指して線形補完 * Liniear Interpolation*という言葉が使われています。参考:[Wikipedia: 線形補間](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E8%A3%9C%E9%96%93)。このの章の原文ではInterpolateという単語が複数回登場しますが、厳密な使い方ではない箇所もあるため以下では「補完」という訳語はあてませんでした。興味がある方はコンピュータグラフィックスやアニメーションの世界で補完関数 *Interpolator* がどのように使われているか調べてみましょう。)
(訳注:ここでは x=0.0 から x=1.0 の間のグラフが一次方程式で書ける、つまりグラフが直線になることを指して線形補完 * Liniear Interpolation*という言葉が使われています。参考:[Wikipedia: 線形補間](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E8%A3%9C%E9%96%93)。このの章の原文ではInterpolateという単語が複数回登場しますが、厳密な使い方ではない箇所もあるため以下では「補完」という訳語はあてませんでした。興味がある方はコンピュータグラフィックスやアニメーションの世界で補完関数 *Interpolator* がどのように使われているか調べてみましょう。)
<div class="codeAndCanvas" data="expo.frag"></div>
面白いでしょう? 19行目の指数```5.0```)を他の数に変えてみましょう。例えば値を```20.0```, ```2.0```, ```1.0```, ```0.0```, ```0.2```, ```0.02```に変えてみます。この値と指数の関係を理解しておくととても役立ちます。この例のように数学的な関数を様々な場面で用いると、コードを表現豊かに操ることができます。鍼で気の流れを操るようにデータの流れを操るのです。
面白いでしょう? 19行目の指数```5.0```)を他の数に変えてみましょう。例えば値を ```20.0```, ```2.0```, ```1.0```, ```0.0```, ```0.2```, ```0.02``` に変えてみます。この値と指数の関係を理解しておくととても役立ちます。この例のように数学的な関数を様々な場面で用いると、コードを表現豊かに操ることができます。鍼で気の流れを操るようにデータの流れを操るのです。
GLSLには多くのネイティブ関数が用意されており、[```pow()```](../glossary/?search=pow)はその中の1つです。ほとんどのネイティブ関数はハードウェアのレベルで高速に処理されるので、適切に使えばより速いコードを書くことができます。
GLSLには多くのネイティブ関数が用意されており、[```pow()```](../glossary/?search=pow) はその中の1つです。ほとんどのネイティブ関数はハードウェアのレベルで高速に処理されるので、適切に使えばより速いコードを書くことができます。
19行目の指数関数を[```exp(st.x) - 1.0```](../glossary/?search=exp), [```log(st.x - 1.0)```](../glossary/?search=log), [```sqrt(st.x)```](../glossary/?search=sqrt)など他の関数で置き換えてみましょう。
19行目の指数関数を [```exp(st.x) - 1.0```](../glossary/?search=exp), [```log(st.x - 1.0)```](../glossary/?search=log), [```sqrt(st.x)```](../glossary/?search=sqrt) など他の関数で置き換えてみましょう。
### StepとSmoothstep
GLSLには他にも、値を変化させるのに使うことができるネイティブ関数があります。これらもまたハードウェアで高速に処理されます。
[```step()```](../glossary/?search=step) 関数は2つのパラメーターを受け取ります。1つめは境界または閾値で、2つめはこの関数によってチェックされる値です。境界より小さい値には全て```0.0```を返し、境界以上の値には```1.0```を返します。
[```step()```](../glossary/?search=step) 関数は2つのパラメーターを受け取ります。1つめは境界または閾値で、2つめはこの関数によってチェックされる値です。境界より小さい値には全て ```0.0``` を返し、境界以上の値には ```1.0``` を返します。
下記のコードの20行目の閾値を変えて試してみてください。
@ -43,14 +43,14 @@ GLSLには他にも、値を変化させるのに使うことができるネイ
<div class="codeAndCanvas" data="smoothstep.frag"></div>
上記の例の12行目では、[```smoothstep()```](../glossary/?search=smoothstep)が```plot()```関数の中で緑色の線を描画するために使われていますね。この関数をx軸に沿って見ていくと、それぞれの点で特定のyの値に対して急激に高い値を返しています。どうなっているのでしょう。```plot```関数は2つの [```smoothstep()```](../glossary/?search=smoothstep)を組み合わせてこれを実現しています。下記の関数を見てください。上の20行目をこの関数で置き換えて、結果を```plot```関数のグラフを垂直に切った断面だと考えてみましょう。背景が線のように見えるでしょう?
上記の例の12行目では、[```smoothstep()```](../glossary/?search=smoothstep) ```plot()``` 関数の中で緑色の線を描画するために使われていますね。この関数をx軸に沿って見ていくと、それぞれの点で特定のyの値に対して急激に高い値を返しています。どうなっているのでしょう。```plot``` 関数は2つの [```smoothstep()```](../glossary/?search=smoothstep) を組み合わせてこれを実現しています。下記の関数を見てください。上の20行目をこの関数で置き換えて、結果を ```plot``` 関数のグラフを垂直に切った断面だと考えてみましょう。背景が線のように見えるでしょう?
```glsl
float y = smoothstep(0.2,0.5,st.x) - smoothstep(0.5,0.8,st.x);
```
訳注おまけ。plot関数を理解するには引き算の片側を消して```smoothstep(0.2,0.5,st.x)```もしくは```smoothstep(0.5,0.8,st.x)```だけにしてみるのも良いと思います。2つのグラフの位置が少しずれていて、引き算をすると真ん中だけが残されるのが分かりますね。20行目の```smoothstep( pct-0.02, pct, st.y) -
smoothstep( pct, pct+0.02, st.y)```でも同じことを試してみましょう。)
(訳注:おまけ。```plot``` 関数を理解するには引き算の片側を消して ```smoothstep(0.2,0.5,st.x)``` もしくは ```smoothstep(0.5,0.8,st.x)``` だけにしてみるのも良いと思います。2つのグラフの位置が少しずれていて、引き算をすると真ん中だけが残されるのが分かりますね。20行目の ```smoothstep( pct-0.02, pct, st.y) -
smoothstep( pct, pct+0.02, st.y)``` でも同じことを試してみましょう。)
### サインとコサイン
@ -69,21 +69,21 @@ GLSLには他にも、値を変化させるのに使うことができるネイ
下記を試して何が起きるか見てみましょう。
* ```sin```を計算する前に時間の値(```u_time```)をxに足してみましょう。x座標に沿った動きを身につけましょう。
* ```sin``` を計算する前に時間の値(```u_time```をxに足してみましょう。x座標に沿った動きを身につけましょう。
* ```sin```を計算する前に、xに```PI```を掛けてみましょう。波の幅が縮まり、xが2進むごとにyが1サイクル上下するのを確認しましょう。
* ```sin``` を計算する前に、xに ```PI``` を掛けてみましょう。波の幅が縮まり、xが 2 進むごとにyが1サイクル上下するのを確認しましょう。
* ```sin```を計算する前に時間の値(```u_time```)をxに掛けてみましょう。周波数が次第に増えて波の幅が狭くなっていく様子を見てください。u_timeが既に大きくなりすぎていてグラフが読めないほどになってしまっているかもしれないので注意してください。訳注もしグラフが線ではなく黒い靄のようなイズになってしまう場合は、一度ページをリロードしてからもう一度試してください。u_timeはページを読み込んでからの累積時間なので、ここまで読み進める間にかなり大きな値になっている可能性があります
* ```sin```を計算する前に時間の値```u_time```をxに掛けてみましょう。周波数が次第に増えて波の幅が狭くなっていく様子を見てください。u_timeが既に大きくなりすぎていてグラフが読めないほどになってしまっているかもしれないので注意してください。訳注もしグラフが線ではなく黒い靄のようなイズになってしまう場合は、一度ページをリロードしてからもう一度試してください。u_timeはページを読み込んでからの累積時間なので、ここまで読み進める間にかなり大きな値になっている可能性があります
* ```sin(x)```に1.0を足してみましょう。値が0.0から2.0の間に収まるように波の位置が上にずれる様子を見てください。
* ```sin(x)``` 1.0 を足してみましょう。値が 0.0 から 2.0 の間に収まるように波の位置が上にずれる様子を見てください。
* ```sin(x)```に2.0を掛けてみましょう。振幅が倍になります。
* ```sin(x)``` 2.0 を掛けてみましょう。振幅が倍になります。
* ```sin(x)```の絶対値([```abs()```](../glossary/?search=abs))を計算してください。弾むボールの軌跡のように見えるでしょう。
* ```sin(x)``` の絶対値([```abs()```](../glossary/?search=abs))を計算してください。弾むボールの軌跡のように見えるでしょう。
* ```sin(x)```の値から少数部分だけを取り出してみましょう([```fract()```](../glossary/?search=fract))。
* ```sin(x)``` の値から少数部分だけを取り出してみましょう([```fract()```](../glossary/?search=fract))。
* [```sin(x)```](../glossary/?search=sin)の値を超える最小の整数([```ceil()```](../glossary/?search=ceil))と、それより小さい最大の整数([```floor()```](../glossary/?search=floor)を足して、1と-1だけからなるデジタル波を作ってみましょう。
* [```sin(x)```](../glossary/?search=sin) の値を超える最小の整数([```ceil()```](../glossary/?search=ceil))と、それより小さい最大の整数([```floor()```](../glossary/?search=floor)を足して、1 -1 だけからなるデジタル波を作ってみましょう。
### 便利な関数あれこれ
@ -115,7 +115,7 @@ GLSLには他にも、値を変化させるのに使うことができるネイ
スパイスや珍しい食材を集めるシェフのように、デジタルアーティストやクリエィティブコーダーは自らシェイピング関数に取り組むのが大好きです。
[Iñigo Quiles](http://www.iquilezles.org/)は便利な関数の[素晴らしいコレクション](http://www.iquilezles.org/www/articles/functions/functions.htm)を持っています。 [この記事](http://www.iquilezles.org/www/articles/functions/functions.htm)をまず読んでから、下記にあるGLSLへ翻訳を見てみましょう。浮動小数点の数値に「.小数点」を追加したり、Cの関数をGLSL特有の関数名で置き換える、例えば```powf()```の代わりに```pow()```を使うなどの細かな変更点に注意してください。
[Iñigo Quiles](http://www.iquilezles.org/)は便利な関数の[素晴らしいコレクション](http://www.iquilezles.org/www/articles/functions/functions.htm)を持っています。 [この記事](http://www.iquilezles.org/www/articles/functions/functions.htm)をまず読んでから、下記にあるGLSLへ翻訳したバージョンを見てみましょう。浮動小数点の数値に「.小数点」を追加したり、Cの関数をGLSL特有の関数名で置き換える、例えば ```powf()``` の代わりに ```pow()``` を使うなどの細かな変更点に注意してください。
* [Impulse](../edit.html#05/impulse.frag)
* [Cubic Pulse](../edit.html#05/cubicpulse.frag)
@ -131,7 +131,7 @@ GLSLには他にも、値を変化させるのに使うことができるネイ
#### 演習
[Kynd](http://www.kynd.info/log/)が作った[数式の表](www.flickr.com/photos/kynd/9546075099/)を見てください。数値と関数をどのように組み合わせて、0.0から1.0の間で値をコントロールしているかを読み取りましょう。実際に関数を置き換えて練習してください。鍛える程にあなたのカラテは強くなります。
[Kynd](http://www.kynd.info/log/)が作った[数式の表](www.flickr.com/photos/kynd/9546075099/)を見てください。数値と関数をどのように組み合わせて、0.0 から 1.0 の間で値をコントロールしているかを読み取りましょう。実際に関数を置き換えて練習してください。鍛える程にあなたのカラテは強くなります。
![Kynd - www.flickr.com/photos/kynd/9546075099/ (2013)](kynd.png)

@ -2,7 +2,7 @@
![Paul Klee - Color Chart (1931)](klee.jpg)
GLSLのベクトル型について話す機会がまだあまりありませんでした。先に進む前にこれらの変数についてもっと学んでおくことが大事です。ここで色について考えることはベクトル型をより良く理解するためのとても良い題材になります。
GLSLのベクトル型について、まだあまり話す機会がありませんでした。先に進む前にこれらの変数についてもっと学んでおくことが大事です。ここで色について考えることはベクトル型をより良く理解するためのとても良い題材になります。
オブジェクト指向のプログラミングに慣れている方であれば、ここまでベクトルの中のデータに、C言語の ```struct``` やその種の構造体と同様の方法でアクセスしてきたことに気づいたでしょう。
@ -13,7 +13,7 @@ red.y = 0.0;
red.z = 0.0;
```
色をx, y, zで表して定義するのは分かりにくいし誤解を招きそうですね。そのため、ベクトル型の変数では同じ情報に違う名前を使ってアクセスできるようになっています。```.x``` ```.y``` ```.z``` の代わりに ```.r``` ```.g``` ```.b``` もしくは ```.s``` ```.t``` ```.p``` を使うことができるのです(```.s``` ```.t``` ```.p``` は通常、テクスチャ空間の座標を示すのに使われます。これについては後の章で学びます)。ベクトル型のデータにはまた、 ```[0]``` ```[1]``` ```[2]``` といったインデックスを使ってアクセスすることもできます。
色をx, y, zで表して定義するのは分かりにくいし誤解を招きそうですね。そのため、ベクトル型の変数では同じ情報に違う名前を使ってアクセスできるようになっています。```.x``` ```.y``` ```.z``` の代わりに ```.r``` ```.g``` ```.b``` もしくは ```.s``` ```.t``` ```.p``` を使うことができるのです(```.s``` ```.t``` ```.p``` は通常、テクスチャ空間の座標を示すのに使われます。これについては後の章で学びます)。ベクトル型のデータにはまた、 ```[0]``` ```[1]``` ```[2]``` といったインデックスを使ってアクセスすることもできます。
下記のコードでは同じデータにアクセスするための全て方法を示しています。
@ -72,7 +72,7 @@ Robert Pennerは[イージング関数](http://easings.net/)と呼ばれる、
### グラデーションで遊ぶ
[```mix()```](../glossary/?search=mix)関数には幅広い使い道があります。3つ目の引数として単に ```float``` で割合を指定する代わりに、最初の2つの引数に対応する型の値を渡すことができます。上記のサンプルでは ```vec3``` を使いました。こうすることで ```r```, ```g```, ```b``` のそれぞれのチャンネルを個別のパーセンテージで混ぜ合わせることができます。
[```mix()```](../glossary/?search=mix) 関数には幅広い使い道があります。3つ目の引数として単に ```float``` で割合を指定する代わりに、最初の2つの引数に対応する型の値を渡すことができます。上記のサンプルでは ```vec3``` を使いました。こうすることで ```r```, ```g```, ```b``` のそれぞれのチャンネルを個別のパーセンテージで混ぜ合わせることができます。
![](mix-vec.jpg)
@ -106,7 +106,7 @@ x軸を色相、y軸を明度に割り当てると色のスペクトルを作る
### HSBと極座標
HSBはもともとデカルト座標xとyではなく、極座標中心からの角度と距離で色を示す仕組みです。私たちのHSB関数を極座標に対応させるには、ピクセル座標を元に、描画領域の中心からの角度と距離を求めなくてはなりません。そのためには [```length()```](../glossary/?search=length)関数と [```atan(y,x)```](../glossary/?search=atan)関数を使います。 ```atan(y,x)``` は一般的な言語で使われている ```atan2(y,x)``` のGLSL版です。
HSBはもともとデカルト座標xとyではなく、極座標中心からの角度と距離で色を示す仕組みです。私たちのHSB関数を極座標に対応させるには、ピクセル座標を元に、描画領域の中心からの角度と距離を求めなくてはなりません。そのためには [```length()```](../glossary/?search=length) 関数と [```atan(y,x)```](../glossary/?search=atan) 関数を使います。 ```atan(y,x)``` は一般的な言語で使われている ```atan2(y,x)``` のGLSL版です。
ベクトルや三角関数を扱う際には ```vec2```, ```vec3``` や ```vec4``` を、それらが色を表している場合でもベクトルと見なします。私たちは色とベクトルを同等に扱います。そして、このフレキシブルな考え方が様々なことを実現する支えになるのを目の当たりにするでしょう。
@ -145,7 +145,7 @@ HSBはもともとデカルト座標xとyではなく、極座標中心
![William Home Lizars - Red, blue and yellow spectra, with the solar spectrum (1834)](spectrums.jpg)
* 下の画像を見てください。カラーピッカーで使われている色の輪をよく見ると、サンプルコードとは違う[RYB色空間](https://en.wikipedia.org/wiki/RYB_color_model)に基づく色のスペクトルが使われていることに気づくでしょう(訳注:もちろんこれはアプリケーション次第です。必ずこうなっているとは限りません)。例えば赤の反対は緑のはずですが、サンプルコードではシアンになっています。これを修正して下の画像とまったく同じに見えるようにする方法を考えられるでしょうか(ヒント:シェイピング関数を使うチャンスです)。
* 下の画像を見てください。カラーピッカーで使われている色の輪をよく見ると、サンプルコードとは違う[RYB色空間](https://en.wikipedia.org/wiki/RYB_color_model)に基づく色のスペクトルが使われていることに気づくでしょう(訳注:これはアプリケーション次第です。必ずこうなっているとは限りません)。例えば赤の反対は緑のはずですが、サンプルコードではシアンになっています。これを修正して下の画像とまったく同じに見えるようにする方法を考えられるでしょうか(ヒント:シェイピング関数を使うチャンスです)。
![](colorwheel.png)

@ -0,0 +1,240 @@
## 形について
![Alice Hubbard, Providence, United States, ca. 1892. Photo: Zindman/Freemont.](froebel.jpg)
ついにこの時が来ました。私たちはこの瞬間のために技を磨いてきたのです。あなたはGLSLの基礎の大部分、値の型と関数について学びました。シェイピング関数も繰り返し練習してきました。今こそ学んだ全てを掛け合わせる時です。この挑戦を受けて立ちましょう。この章では並列処理ならではの方法でシンプルな形を描く方法を学びます。
### 長方形
数学の授業で使ったような方眼紙があって、そこに正方形を描く宿題が出たと想像してください。紙のサイズは10×10で正方形は8×8にする必要があります。あなたならどうしますか。
![](grid_paper.jpg)
一番上と下の行、左右両端の列を除いてすべてを塗りつぶせばよいですね。
これがシェーダーになんの関係があるのでしょう。方眼紙の小さな正方形1つ1つはスレッドピクセルです。それぞれの小さな正方形は自分の位置を、チェス盤上の行と列のように把握しています。以前の章で私たちは x と y を赤と緑の色のチャンネルに割り当てました。また 0.0 から 1.0 の間の狭い二次元の領域を使う方法も学んできました。描画領域の中央に正方形を描くのに、これらの知識をどう活かせばよいでしょうか。
描画する範囲についての ```if``` 文を使った疑似コードから始めてみましょう。基本的な考え方は方眼紙の宿題ととてもよく似ています。
```glsl
if ( (X GREATER THAN 1) AND (Y GREATER THAN 1) )
paint white
else
paint black
```
方針がまとまったところで、 ```if``` 文を [```step()```](../glossary/?search=step) に置き換えて、10×10のマス目の代わりに 0.0 から 1.0 に正規化された値を使ってみましょう。
```glsl
uniform vec2 u_resolution;
void main(){
vec2 st = gl_FragCoord.xy/u_resolution.xy;
vec3 color = vec3(0.0);
// Each result will return 1.0 (white) or 0.0 (black).
float left = step(0.1,st.x); // Similar to ( X greater than 0.1 )
float bottom = step(0.1,st.y); // Similar to ( Y greater than 0.1 )
// The multiplication of left*bottom will be similar to the logical AND.
color = vec3( left * bottom );
gl_FragColor = vec4(color,1.0);
}
```
[```step()```](../glossary/?search=step) 関数は、 x か y が 0.1 より小さくなるピクセルを黒(```vec3(0.0)```)に、他のすべてのピクセルを白(```vec3(1.0)```)に変えてくれます。```left``` と ```bottom``` の掛け算は ```AND``` 演算の役割をして、両方ともの値が 1.0 だった場合にのみ 1.0 を返します。結果として描画領域の下側と左側に2本の黒い線が引かれることになります。
![](rect-01.jpg)
このコードではそれぞれの軸(左側と下側)に対して同じ構造を繰り返しています。[```step()```](../glossary/?search=step) に1つずつ値を渡す代わりに、2つの値を一度に渡せば数行分のコードを節約することができます。下記を見てください。
```glsl
vec2 borders = step(vec2(0.1),st);
float pct = borders.x * borders.y;
```
ここまでではまだ2本の辺左側と下側しか描けていません。もう2本にも手をつけましょう。
<div class="codeAndCanvas" data="rect-making.frag"></div>
コメントを外すと、```st``` 座標を反転させてから同じ [```step()```](../glossary/?search=step) 関数を繰り返す様子が見られます。こうすると ```vec2(0.0,0.0)``` が右上の角になります。紙をひっくり返して作業を繰り返すのと同じことをデジタルに行っているわけです。
![](rect-02.jpg)
18行目と22行目で全ての辺の値が掛け合わされていることに注目してください。これは下記のように書くこともできます。
```glsl
vec2 bl = step(vec2(0.1),st); // bottom-left
vec2 tr = step(vec2(0.1),1.0-st); // top-right
color = vec3(bl.x * bl.y * tr.x * tr.y);
```
面白いでしょう。[```step()```](../glossary/?search=step) を使いこなし、掛け算を使って論理演算をして、さらに座標をひっくり返すとこんなことができるのです。
さらに先に進む前に下記の課題に挑戦しましょう。
* 長方形の大きさと縦横比を変えてみましょう。
* 同じコードを元に [```step()```](../glossary/?search=step) の代わりに [```smoothstep()```](../glossary/?search=smoothstep) を使ってみましょう。値を調節するとぼやけた境界線からスムーズな枠線まで変化させることができます。
* [```floor()```](../glossary/?search=floor) を使ってみましょう。
* 課題の中から気に入ったコードを選び、それを関数に変えて再利用できるようにしましょう。効率的でフレキシブルな関数を考えましょう。
* 長方形を塗りつぶすのではなく、枠線だけを描く関数を作ってください。
* どうすれば1つの描画領域の異なる位置に、複数の長方形を配置することができると思いますか。良い方法を考え出せたら[モンドリアン](http://en.wikipedia.org/wiki/Piet_Mondrian)の絵のようなパターンを作ってみせてください。
![Piet Mondria - Tableau (1921)](mondrian.jpg)
### 円
方眼紙の上やデカルト座標系で長方形を描くのは簡単です。しかし円を描くには別のアプローチが必要です。しかもシェーダーではそれぞれのピクセルごとに処理するアルゴリズムを用いなければなりません。1つの方法は [```step()```](../glossary/?search=step) 関数を使って円が描けるように、空間座標を置き換えることです。
どうすればいいのでしょう。数学の教室に戻って、方眼紙の上にコンパスを半径の長さに開いたところから始めましょう。片方の端を円の中心に置いて1回転させて円の淵をなぞります。
![](compass.jpg)
シェーダーでは方眼のマス目の1つ1つがピクセルに対応します。方眼紙とコンパスからシェーダーに置き換えるということは、それぞれのピクセルスレッドに対して円の内側にあるかどうかを問い合わせることを意味します。これは円の中心からピクセルまでの距離を計算することで行うことができます。
![](circle.jpg)
距離を計算するには幾つかの方法があります。最も簡単なのは [```distance()```](../glossary/?search=distance) 関数を使うことです。この関数は内部的に2つの点の差を取りその [```length()```](../glossary/?search=length) を計算します(今回のケースではピクセルの座標と描画領域の中心対象にします)。```length()``` 関数は[ピタゴラスの定理](https://ja.wikipedia.org/wiki/%E6%96%9C%E8%BE%BA)のショートカットで内部的に平方根([```sqrt()```](../glossary/?search=sqrt))を使います。
![](hypotenuse.png)
[```distance()```](../glossary/?search=distance), [```length()```](../glossary/?search=length), [```sqrt()```](../glossary/?search=sqrt) のいずれかを使って中心までの距離を計算することができます。下記のコードにはこれら3つの関数が全て含まれていますが、当然ながら全く同じ結果になります。
* コメントを付け替えて、違う方法を使っても同じ結果が得られることを確かめましょう。
<div class="codeAndCanvas" data="circle-making.frag"></div>
このサンプルでは中心からの距離をピクセルの明るさに割り当てました。中心に近いピクセルほど値が低く(暗く)なります。中心( ```vec2(0.5, 0.5)``` からの距離は最大でルート2の半分にしかならないため一番明るいところでも真っ白にはなりません。このサンプルをよく見て考えてみてください。訳注原文では最大の距離は0.5はとなっていますが誤りです。中心から描画領域の角までの距離はルート2の半分です。
* 何か気づいたことはありますか。
* これをどう使えば円が描けるでしょう。
* コードを書き換えて円形のグラデーションの全体が描画領域に収まるようにしてください。
### ディスタンスフィールド
上のサンプルは、暗い色ほど標高が高いことを示した、高低差を表す地図だと考えることもできます。このグラデーションは円錐のようなものを表しています。円錐の頂上に立ったところを想像してください。円錐の縁までの距離は 1.0 です訳注原文では0.5となっていますが、明るさが1.0に
なるところを縁と考えると 1.0 です)。これはどの方角でも同じです。どこで円錐を「輪切りに」するかを決めることで、大きさの違う円を得ることができます。
![](distance-field.jpg)
要するにここでは空間を中心からの距離に基づいて解釈し直すことによって形を作っています。この手法はディスタンスフィールドと呼ばれ、フォントのアウトラインから3Dグラフィクスまで様々な用途に使われています。
(訳注distance field の適当な訳語が見当たらなかったのでカタカナで「ディスタンスフィールド」とします。おおざっぱに、点や図形からの距離を空間上にマップしたものだと考えてください。)
下記の課題に挑戦しましょう。
* [```step()```](../glossary/?search=step) を使って、0.5 以上を全て白に、それ以外を黒にしてください。
* 背景と図形の色を反転させてください。
* 円の縁を滑らかにしてみましょう。[```smoothstep()```](../glossary/?search=smoothstep) を使って色々な値を試してください。
* うまくできたら後で再利用できるように関数として定義してください。
* 円に色をつけてください。
* 心臓の鼓動のように円を伸縮させるアニメーションを作ることはできますか。(前章のアニメーションを参考にしましょう。)
* 円を移動させることはできますか。円を別の場所に動かして、さらにもう1つの円を別の場所に描くことはできますか。
* 様々な演算や関数を使って、複数のディスタンスフィールドを組み合わせると何が起きるでしょう。
```glsl
pct = distance(st,vec2(0.4)) + distance(st,vec2(0.6));
pct = distance(st,vec2(0.4)) * distance(st,vec2(0.6));
pct = min(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
pct = max(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
```
* これらのテクニックを使った作品を3つ作ってください。アニメーションにできればさらに素敵です。
#### 便利な道具箱
平方根([```sqrt()```](../glossary/?search=sqrt))や、それに依存した関数はどれもコンピュータの処理能力に負荷をかける可能性があります。下記は円形のディスタンスフィールドを作る別の方法で、平方根の代わりに内積([```dot()```](../glossary/?search=dot) )を使います。
<div class="codeAndCanvas" data="circle.frag"></div>
### ディスタンスフィールドの便利な性質
![Zen garden](zen-garden.jpg)
ディスタンスフィールドを使うと、ほぼどんなものでも描くことができます。もちろん形が複雑なほどより計算式がもより複雑になりますが、一旦ある形のディスタンスフィールドを作り出すための式を手に入れれば、複数の形を組み合わせたり、縁をぼかしたり何重にも線を引いたり様々なエフェクトをかけたりすることはとても簡単にできます。そのため下記の例に見られるようにディスタンスフィールドはフォントのレンダリングによく使われています。
* [Mapbox GL Labels](https://www.mapbox.com/blog/text-signed-distance-fields/)
* [Matt DesLauriers](https://twitter.com/mattdesl)
* [Material Design Fonts](http://mattdesl.svbtle.com/material-design-on-the-gpu)
* [Chapter 7 of iPhone 3D Programming, OReilly](http://chimera.labs.oreilly.com/books/1234000001814/ch07.html#ch07_id36000921)
下記のコードをみてください
<div class="codeAndCanvas" data="rect-df.frag"></div>
まず座標系を中心に動かして半分の大きさに縮小することで値が -1 から 1の間に収まるようにします訳注16行目の式の ```2.``` と ```1.``` を書き換えて見ると理解の助けになります。24行目では [```fract()```](../glossary/?search=fract) 関数を使ってディスタンスフィールドが作り出すパターンが見やすいように視覚化しています。ディスタンスフィールドは禅寺の庭
のような繰り返しの模様を作り出します。
19行目のディスタンスフィールドを作り出す式を見てみましょう。4つの象限すべてで ```vec3(.3)```、つまり ```(.3,.3)``` までの
距離を計算しています([```abs()```](../glossary/?search=abs) を使って座標を絶対値にしてから距離を求めています)。
20行目のコメントを外すと 0 との [```min()```](../glossary/?search=min) を使って、4つの点への距離を組み合わせた場合を見ることができます。これは新く面白いパターンを作り出します。
さて21行目のコメントを外して見ましょう。[```max()```](../glossary/?search=max) を使っていること以外は同じです。結果は角丸の四角形になります。ディスタンスフィールドの輪は中心から遠ざかるほど半径が大きくなっていることに注目しましょう。
27行目から29行目までのコメントを順番に外して、ディスタンスフィールドを使ってパターンを作る様々な方法を学びましょう。
### 極座標を使った図形
![Robert Mangold - Untitled (2008)](mangold.jpg)
色についての章では下記の式を使って、それぞれのピクセルについて半径と角度を計算し、デカルト座標を極座標に変換しました。
```glsl
vec2 pos = vec2(0.5)-st;
float r = length(pos)*2.0;
float a = atan(pos.y,pos.x);
```
本章の前半ではこの式の一部を利用して円を描きました。[```length()```](../glossary/?search=length)を使って中心からそれぞれのピクセルまでの距離を計算したのですね。ディスタンスフィールドのことを知った今、我々は極座標を使って図形を描く新たな手法について学ぶことができます。
この手法は少し用途が限られますがとてもシンプルです。様々な異なる図形を描くために、角度に対する半径の大きさをいろいろと変化させます。どのように変化させるのでしょう。そうです、シェイピング関数を使います。
下記の2つのサンプルでは、同じ関数がデカルト座標と極座標21行目から25行目の両方で使われているのが分かるでしょう。一方の座標系ともう片方の座標系との関係に注意しながら、コメントを1つつ外してください。
<div class="simpleFunction" data="y = cos(x*3.);
//y = abs(cos(x*3.));
//y = abs(cos(x*2.5))*0.5+0.3;
//y = abs(cos(x*12.)*sin(x*3.))*.8+.1;
//y = smoothstep(-.5,1., cos(x*10.))*0.2+0.5;"></div>
<div class="codeAndCanvas" data="polar.frag"></div>
下記を試してみましょう。
* 図形をアニメーションにしてください。
* 異なるシェイピング関数を組み合わせて図形の中に穴を開けてください。花や雪の結晶、歯車などを描いてみましょう。
* シェイピング関数の章で使った ```plot()``` 関数を利用して輪郭線だけを描いてください。
### 技を掛け合わせる
さて [```atan()```](../glossary/?search=atan)を使い、角度に対する半径の大きさを変化させて図形を描く方法について学びました。次は ```atan()``` をディスタンスフィールドと組み合わせて、すべての技を駆使する方法を学びます。
この方法では多角形の辺の数を元に極座標を使ってディスタンスフィールドを構成します。[Andrew Baldwin](https://twitter.com/baldand)による、[下記のコード](http://thndl.com/square-shaped-shaders.html)をご覧ください。
<div class="codeAndCanvas" data="shapes.frag"></div>
* このサンプルを使って、ピクセルの位置と描きたい図形の頂点の数を入力とし、ディスタンスフィールドの値を返す関数を作ってください。
* [```min()```](../glossary/?search=min) と [```max()```](../glossary/?search=max) を使ってディスタンスフィールドを組み合わせてみましょう。
* 幾何学的なロゴをなにか1つ選んでディスタンスフィールドを使って再現してみましょう。
おめでとうございます。これで山を乗り越えました。[Processing](https://processing.org/)を使えばシンプルな形を描くのは簡単なことですが、ここで学んだ方法は違います。シェーダーの世界では形を描くのにもひねくれたやり方をしなくてはなりませんし、新しいコーディングの考え方に慣れるのは大変なことです。一息入れて、学んだ概念を頭に馴染ませましょう。
図形の描きかたを学んだので、新しいアイデアが頭の中に浮かんでくることでしょう。次の章ではこれらを移動、回転、そして拡大・縮小させる方法を学びます。これで図形を様々に組み合わせることができるようになります。

@ -0,0 +1,103 @@
## 二次元行列
<canvas id="custom" class="canvas" data-fragment-url="matrix.frag" width="700px" height="200px"></canvas>
### 平行移動
前の章では図形を描く方法を学びました。この章では描いた図形を動かしてみましょう。秘訣は座標系自体を動かしてしまうことです。これはそれぞれのフラグメント(ピクセル)の位置を格納する変数 ```st``` にベクトルを加えれば簡単に実現することができます。
![](translate.jpg)
説明するよりも実際に見た方が簡単です。自分自身で試してみましょう。
* 下記のコードの35行目のコメントを外して、空間全体が動いている様子を見てみましょう。
<div class="codeAndCanvas" data="cross-translate.frag"></div>
下記の課題に挑戦してみましょう。
* ```u_time``` とシェイピング関数を使って、小さな十字に面白い動きをさせてください。なにか気になる動き方の例を探して、同じように十字を動かしてみましょう。寄せて返す波や、振り子、弾むボール、加速する自動車、自転車が止まるところなど、まずは現実世界のできごとを記録してみるのも良いかもしれません。
### 回転
物体を回転させるにはやはり空間全体を動かす必要があります。そのためには[行列matrix](https://ja.wikipedia.org/wiki/%E8%A1%8C%E5%88%97)を使います。行列とは行(横方向)と列(縦方向)に並べられた数字の集まりです。決められたルールに従ってベクトルに行列を掛け合わせることで、ベクトルの値をある法則に沿って変化させることができます。
[![行列 - Wikipedia](matrixes.png)](https://ja.wikipedia.org/wiki/%E8%A1%8C%E5%88%97)
GLSLはネイティブで二次元、三次元、四次元の行列をサポートしています。[```mat2```](../glossary/?search=mat2)2×2、[```mat3```](../glossary/?search=mat3) 3×3、[```mat4```](../glossary/?search=mat4) 4×4がそれぞれ対応します。GLSLはまた行列の掛け算```*```
や行列に特化した関数([```matrixCompMult()```](../glossary/?search=matrixCompMult))もサポートします.
行列の性質をうまく使うと、特定の作用を生み出すことができます。例えば行列を使ってベクトルを平行移動させることができます。
![](3dtransmat.png)
さらに興味深いことに、行列は座標系を回転させるためにも使うことができます。
![](rotmat.png)
二次元の回転行列を作り出す下記のコードを見てみましょう。この関数は二次元ベクトルについての上記の[公式](https://ja.wikipedia.org/wiki/%E5%9B%9E%E8%BB%A2%E8%A1%8C%E5%88%97)に従って ```vec2(0.0)``` を中心に座標を回転させます。
```glsl
mat2 rotate2d(float _angle){
return mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle));
}
```
これまでに学んだ描画方法を思い出してみると、この関数は本当に欲しいものとはちょっと違います。私たちの十字は描画領域の中心に相当する( ```vec2(0.5)``` )に描かれています。そのため、空間を回転させる前に図形を中心から ```vec2(0.0)``` まで移動させてやる必要があります。移動させたらその場で空間を回転させ、またもとの場所に戻してやります。
![](rotate.jpg)
コードで示すと下記のようになります。
<div class="codeAndCanvas" data="cross-rotate.frag"></div>
下記の課題に挑戦してみましょう。
* 上記のコードの45行目のコメントを外して何が起きるかに注目してください。
* 37行目と39行目、回転の前後にある平行移動をコメントアウトして、結果を観察しましょう。
* 平行移動についての課題で作った作品を、回転を使ってさらに改善してみましょう。
### 拡大・縮小
ここまでは行列を使って物体を空間の中で平行移動させたり回転させたりする様子より正確には、座標系全体を変形させることで物体を動かしたり回転させる様子を見てきました。3DモデリングのソフトウェアやProcessingのpushやpopなどの行列関数を使ったことがあれば、行列を使って物体の大きさを拡大・縮小できることもご存知でしょう。
![](scale.png)
上記の公式に従えば、二次元の拡大・縮小を行う行列を作ることができます。
```glsl
mat2 scale(vec2 _scale){
return mat2(_scale.x,0.0,
0.0,_scale.y);
}
```
<div class="codeAndCanvas" data="cross-scale.frag"></div>
下記の課題に挑戦して理解を深めましょう。
* 上記のコードの42行目のコメントを外して空間座標が拡大・縮小していることを確認しましょう。
* 37行目と39行目、拡大・縮小の前後にある平行移動をコメントアウトして、結果を見てみましょう。
* 回転行列と拡大・縮小を行う行列を組み合わせてみましょう。順番が重要なので注意してください。行列同士を掛け合わせてから最後にベクトルを掛けるようにします。
* 様々な図形の描き方、回転、拡大・縮小のやり方を身につけたので、今度はそれらを組み合わせてより複雑なものを構成してみましょう。[架空のUIやヘッドマウントディスプレイの画面](https://www.pinterest.com/patriciogonzv/huds/)をデザインして組み立ててみます。[Ndel](https://www.shadertoy.com/user/ndel)が作成したSharderToyのサンプルを参考にしてください。
<iframe width="800" height="450" frameborder="0" src="https://www.shadertoy.com/embed/4s2SRt?gui=true&t=10&paused=true" allowfullscreen></iframe>
### その他の行列の用途: YUVカラー
[YUV](https://ja.wikipedia.org/wiki/YUV)は人間の知覚できる範囲を考慮して色成分の帯域を減らすことのできる、写真やビデオのアナログエンコーディングで用いられる色空間です。
下記のコードは色を1つのモードから別のモードに変換する、GLSLでの行列演算の面白い使い道の例です。
<div class="codeAndCanvas" data="yuv.frag"></div>
見てのとおり色をベクトルとして扱い行列を掛け合わせています。このようにして色の値を「動かす」ことができるのです。
この章では行列を使ってベクトルを移動、回転、拡大・縮小する方法を学びました。これらの変形は、前章で学んだ図形を組み合わせてより複雑な図を作成するのに欠かせない技術です。次の章ではこれまで学んだことを全て活かして、規則に基づいた美しいパターンを作成します。コードによる反復と変化の楽しさを発見しましょう。

@ -0,0 +1,124 @@
## パターン
シェーダーのプログラムはピクセルごとに並列で処理されるので、同じ形を何度も繰り返したとしても計算の回数は一定に留まります。そのためフラグメントシェーダーはタイルのような繰り返しのパターンに特に適しています。
[ ![Nina Warmerdam - The IMPRINT Project (2013)](warmerdam.jpg) ](../edit.html#09/dots5.frag)
この章ではこれまでに学んだことを応用して、描画領域のなかで繰り返しを行います。前章で行ったのと同様に、空間座標に対して掛け算を行い、0.0 から 1.0 の間に掛かれた図形がグリッド状に反復されるようにします。
*「グリッドは人間の直感と創意が働く枠組み、構築と解体のためのフレームワークを提供します。自然界のカオスの中に、規則的なパターンは対比と秩序の兆しをもたらしてくれます。
草創期の陶芸品の模様からローマ時代の浴場の幾何学的なモザイクまで、長い間人々はグリッドを用い生活を豊かに彩ってきました。」*[*10 PRINT*, Mit Press, (2013)](http://10print.org/)
(訳注:そのまま訳すのが難しい文章だったため、本人に意図を確認して言葉を補いました。)
まず [```fract()```](../glossary/?search=fract) 関数を思い出しましょう。この関数はつまるところ 1 の剰余 [```mod(x,1.0)```](../glossary/?search=mod))と同等です。言い換えれば [```fract()```](../glossary/?search=fract) は小数点以下の部分の数を返してくれます。正規化された座標(```st```)は既に 0.0 から 1.0 の間に収まっているので、下記のようなコードは意味を成しません。
```glsl
void main(){
vec2 st = gl_FragCoord.xy/u_resolution;
vec3 color = vec3(0.0);
st = fract(st);
color = vec3(st,0.0);
gl_FragColor = vec4(color,1.0);
}
```
しかしここで、正規化された座標系を例えば3倍に拡大すると、0 から 1 までの滑らかに変化する値の繰り返しを3つ得ることができます。1つ目は 0 から 1 までの値、2つ目は 1 から 2 までの値の少数部分、3つ目は 2 から 3 までの値の少数部分です。
<div class="codeAndCanvas" data="grid-making.frag"></div>
さて、27行目のコメントを外して分割されたそれぞれの空間の中に何か描いてみましょう。xとyを等しく拡大しているので空間のアスペクト比は変わらず、期待した通りの形が描かれます。
下記の課題を幾つか試して理解を深めましょう。
* 空間に対して違う数をかけてみましょう。少数部分を持つ数を試したり、xとyに違う数を掛けてみましょう。
* このタイリングのテクニックを再利用可能な関数にしてみましょう。
* 空間を3行3列に分割します。スレッドがどの行と列にいるのかを知る方法を考えて、表示する図形を変えてください。Tic-tac-toe×ゲームを描いてみましょう。
### パターンの中で行列を適用する
それぞれの分割された空間は、これまで使ってきたのと同じ正規化された座標系をただ小さくしたものになっているので、行列変換をそれぞれの空間内での平行移動や回転、拡大・縮小に使うことができます。
<div class="codeAndCanvas" data="checks.frag"></div>
* このパターンをアニメーションにする面白いアイデアを考えてください。色、形、動きの変化について考えましょう。3種類の異なるアニメーションを作成してください。
* 異なる形を組み合わせてより複雑なパターンを作ってみましょう。
<a href="../edit.html#09/diamondtiles.frag"><canvas id="custom" class="canvas" data-fragment-url="diamondtiles.frag" width="520px" height="200px"></canvas></a>
* 異なるパターンのレイヤーを重ねてオリジナルの[タータンチェック](https://www.google.com/search?q=scottish+patterns+fabric&tbm=isch&tbo=u&source=univ&sa=X&ei=Y1aFVfmfD9P-yQTLuYCIDA&ved=0CB4QsAQ&biw=1399&bih=799#tbm=isch&q=Scottish+Tartans+Patterns)のパターンを作ってください。
[ ![Vector Pattern Scottish Tartan By Kavalenkava](tartan.jpg) ](http://graphicriver.net/item/vector-pattern-scottish-tartan/6590076)
### パターンをずらす
ブロックの壁を模したパターンを作りたいとします。壁を観察すると、1行おきにブロック半個分だけx座標がずれていることに気づくでしょう。
![](brick.jpg)
xをずらす必要があるかを決めるには、まず現在のスレッドが偶数行と奇数行のどちらに当たるのかを知る必要があります。
スレッドが偶数行か奇数行かを求めるには、2.0 の剰余([```mod()```](../glossary/?search=mod) )を、拡大した座標系に対して用い結果が 1.0 を下回るかどうかを見ます。下記のコードの最後の2行のコメントを外してみましょう。
<div class="simpleFunction" data="y = mod(x,2.0);
// y = mod(x,2.0) < 1.0 ? 0. : 1. ;
// y = step(1.0,mod(x,2.0));"></div>
訳注このサンプルではxは 0.0 から 1.0 ではなく -4 から 4 の範囲にすでに拡大されています。コメントを外すとxの整数部分が奇数になる、つまり ```mod(x, 2.0)``` が 1.0 以上になる場合にだけyが 1.0 になります。)
見てのとおり、2.0 の剰余([```mod()```](../glossary/?search=mod))が 1.0
を下回るかどうかの判定には、[三項演算子](https://ja.wikipedia.org/wiki/%E6%9D%A1%E4%BB%B6%E6%BC%94%E7%AE%97%E5%AD%90)2行目を使うか、 [```step()```](../glossary/?search=step) 3行目) を使ってより高速に処理を行うこともできます。グラフィックカードがどのように最適化されていて、どのようにコードをコンパイルするのかを知るのは難しいことですが、組み込み関数はそうでない関数に比べて高速に処理されると考えてまず問題ありません。組み込み関数が使える場合には必ず使うようにしましょう。
偶奇判定の式ができたので、これでタイルの奇数行をずらしてブロックらしく見せることができます。下記のコードの14行目の関数で、奇数行かどうかを判定して ```x``` をブロック半個分ずらしています。この行の [```step()```](../glossary/?search=step) は偶数行に対して ```0.0``` を返します。ブロック半個分の ```0.5``` をかけると結果は ```0.0```です。奇数行に対しては ```1.0``` を返すので ```0.5``` を掛けた結果、座標系をx軸方向に ```0.5``` だけ移動させることになります。
32行目のコメントを外してみましょう。こうすると座標系のアスペクト比が引き伸ばされて現代のブロックの比率になります。40行目のコメントを外すと座標系の様子が赤と緑で示されるのを見ることができます。
<div class="codeAndCanvas" data="bricks.frag"></div>
* このサンプルを、時間とともにブロックがずれていくアニメーションにしてください。
* 偶数行が左に、奇数行が右に動くアニメーションを作りましょう。
* 行方向ではなく列方向に対して同じ効果を適応することはできますか。
* ```x``` と ```y``` をずらしてこんなパターンを作ってみましょう。
<a href="../edit.html#09/marching_dots.frag"><canvas id="custom" class="canvas" data-fragment-url="marching_dots.frag" width="520px" height="200px"></canvas></a>
## トルシェタイル
マス目が偶数行と奇数行(または列)どちらに当たるかの判定方法を学んだので、デザイン要素を場所に応じて再利用することができます。
同じデザイン要素が4種類の方法で使われる、[トルシェタイル](http://en.wikipedia.org/wiki/Truchet_tiles)を例として考えてみましょう。
![](truchet-00.png)
タイルごとのパターンを変えることによって、複雑なデザインを無限に組み立てることができます。
![](truchet-01.png)
```rotateTilePattern()``` に注目してください。この関数は空間を4つのマス目に分割しそれぞれに回転の角度を割り当てます。
<div class="codeAndCanvas" data="truchet.frag"></div>
* 69行目から72行目までのコメントをつけたり外したり、行をコピーしたりして新しいデザインを作りましょう。
* 黒と白の三角を他のデザイン要素、例えば半円や回転する正方形、線などに変えてみましょう。
* 要素が位置に応じて回転して配置される、新しいパターンを作成してください。
* 要素の場所によって他の属性(訳注:例えば色)を変化させるパターンを作ってください。
* 必ずしも繰り返しのパターンではないもので、この項で学んだ原則を使える例を考えてください(例:八卦の組み合わせの一覧)。
<a href="../edit.html#09/iching-01.frag"><canvas id="custom" class="canvas" data-fragment-url="iching-01.frag" width="520px" height="200px"></canvas></a>
## 自分でルールを作る
規則によるパターン作りは、再利用可能な最小の要素を見つける頭の体操です。この行為自体は古くからあるもので、私たちの種はグリッドとパターンを織物や床をはじめ様々なものを装飾するために長い間利用してきました。曲がりくねった古代ギリシャの模様から中国の格子模様まで、反復と変化の楽しみは私たちの想像力をかきたててきました。装飾的なパターン([例1](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) [例2](https://www.pinterest.com/patriciogonzv/paterns/))をゆっくりと眺めて、予測可能な規則正しさと、驚きにあふれた変化とカオスの間の微妙な線を芸術家やデザイナー達が渡り歩いてきた様子を見てみましょう。アラブの幾何学的なパターンから、アフリカの生地のデザインまで、学ぶべき大きな世界がそこにあります。
![Franz Sales Meyer - A handbook of ornament (1920)](geometricpatters.png)
この章で「アルゴリズムで絵を描く」のセクションは終わりです。続く章では多少の無秩序さをシェーダーに持ち込んでデザインを生成する方法について学びます。

@ -33,11 +33,11 @@ void main(void){
// Apply the brick tiling
st = brickTile(st,5.0);
color = vec3(box(st,vec2(0.9)));
// Uncomment to see the space coordinates
// color = vec3(st,0.0);
gl_FragColor = vec4(color,1.0);
gl_FragColor = vec4(color,1.0);
}

@ -35,7 +35,7 @@ void main(void){
vec3 color = vec3(0.0);
// Divide the space in 4
st = tile(st,4.);
st = tile(st,4.);
// Use a matrix to rotate the space 45 degrees
st = rotate2D(st,PI*0.25);
@ -44,5 +44,5 @@ void main(void){
color = vec3(box(st,vec2(0.7),0.01));
// color = vec3(st,0.0);
gl_FragColor = vec4(color,1.0);
gl_FragColor = vec4(color,1.0);
}

@ -0,0 +1,118 @@
# Generative designs
# ジェネラティブデザイン
It is not a surprise that after so much repetition and order the author is forced to bring some chaos.
*いいまわし検討* so much な繰り返しと秩序の後では[筆者|作者]がいくらかの混沌を持ち込まざるを得なくなるとしても驚くには値しません。
## Random
## ランダム
[![Ryoji Ikeda - test pattern (2008) ](ryoji-ikeda.jpg) ](http://www.ryojiikeda.com/project/testpattern/#testpattern_live_set)
(訳注:池田亮司を「ランダム」でくくることに抵抗があるという意見を各方面からいただきましたが、翻訳なのでそのままにしておきます。)
Randomness is a maximal expression of entropy. How can we generate randomness inside the seemingly predictable and rigid code environment?
ランダムはエントロピーが最大になった状態を表します。一見規則正く厳格なコードの世界、どのようにしてランダムな要素を生成することができるのでしょうか。
Let's start by analyzing the following function:
下記の関数を検討することから始めましょう。
<div class="simpleFunction" data="y = fract(sin(x)*1.0);"></div>
Above we are extracting the fractional content of a sine wave. The [```sin()```](../glossary/?search=sin) values that fluctuate between ```-1.0``` and ```1.0``` have been chopped behind the floating point, returning all positive values between ```0.0``` and ```1.0```. We can use this effect to get some pseudo-random values by "breaking" this sine wave into smaller pieces. How? By multiplying the resultant of [```sin(x)```](../glossary/?search=sin) by larger numbers. Go ahead and click on the function above and start adding some zeros.
ここではサイン波から小数点部分を取り出しています。```-1.0``` から ```1.0``` の間を往復する [```sin()```](../glossary/?search=sin) の値から、```0.0``` から ```1.0``` の間の正の値だけが残るように小数点の後ろだけを切り取っています。サイン波を細かな部分に分割することで擬似的にランダムな値を得るために、これを応用することができます。どういうことでしょう。[```sin(x)```](../glossary/?search=sin) の結果の値に大きな数を掛けます。上の関数をクリックして 0 を幾つか書き加えてみましょう。
By the time you get to ```100000.0``` ( and the equation looks like this: ```y = fract(sin(x)*100000.0)``` ) you aren't able to distinguish the sine wave any more. The granularity of the fractional part has corrupted the flow of the sine wave into pseudo-random chaos.
```100000.0``` に至る頃には(式は ```y = fract(sin(x)*100000.0)``` のようになります)もうサインカーブには見えなくなっているでしょう。小数点部分は非常に細かくなり、サイン波の流れるカーブは潰されて混沌とした擬似的なランダム状態を作り出しています。
## Controlling chaos
## カオスを制御する
Using random can be hard; it is both too chaotic and sometimes not random enough. Take a look at the following graph. To make it, we are using a ```rand()``` function which is implemented exactly like we describe above.
乱数を使いこなすのは易しいことではありません。無秩序すぎることも、十分にランダムでないこともあります。下記のグラフを見てください。このグラフは、上での述べた通りの方法で実装した ```rand()``` 関数を使って作られています。
Taking a closer look, you can see the [```sin()```](../glossary/?search=sin) wave crest at ```-1.5707``` and . I bet you now understand why - it's where the maximum and minimum of the sine wave happens.
よく見ると [```sin()```](../glossary/?search=sin) の描く波が ```-1.5707``` と ```-1.5707``` で頂点を迎えています。お分かりですね。これは波が最大値と最小値になる場所です。*talking about "crests" doesn't make much sense here. Better mention the tiny gaps around +PI/2 and -PI/2 and explain why this happens, i.e. these are where the crest of the sine curve are?*
If look closely at the random distribution, you will note that the there is some concentration around the middle compared to the edges.
乱数の分布に注目すると、端にくらべて中央に値が集中しているのが分かるでしょう。
<div class="simpleFunction" data="y = rand(x);
//y = rand(x)*rand(x);
//y = sqrt(rand(x));
//y = pow(rand(x),5.);"></div>
A while ago [Pixelero](https://pixelero.wordpress.com) published an [interesting article about random distribution](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/). I've added some of the functions he uses in the previous graph for you to play with and see how the distribution can be changed. Uncomment the functions and see what happens.
以前に[Pixelero](https://pixelero.wordpress.com)は[ランダムな分布についての興味深い記事](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/)を公開しました。上記のグラフにこの記事から幾つかの関数を加えておいたので、どのように値の分布が変化するか試してみてください。関数のコメントを外して何が起こるか見てみましょう。
If you read [Pixelero's article](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/), it is important to keep in mind that our ```rand()``` function is a deterministic random, also known as pseudo-random. Which means for example ```rand(1.)``` is always going to return the same value. [Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/) makes reference to the ActionScript function ```Math.random()``` which is non-deterministic; every call will return a different value.
[Pixeleroの記事](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/)を読むときには、ここで作った ```rand()``` 関数は擬似ランダムとも呼ばれる、決定的(結果の値が一意に定まる)乱数だということを覚えておくことが重要です。これはつまり、例えば ```rand(1.)``` は常に同じ値を返すということです。[Pixelero](https://pixelero.wordpress.com/2008/04/24/various-functions-and-various-distributions-with-mathrandom/)が引き合いに出しているのはActionScriptの ```Math.random()``` で、これは非決定的な、つまり毎回異なる値を返す関数です。
## 2D Random
Now that we have a better understanding of randomness, it's time to apply it in two dimensions, to both the ```x``` and ```y``` axis. For that we need a way to transform a two dimensional vector into a one dimensional floating point value. There are different ways to do this, but the [```dot()```](../glossary/?search=dot) function is particulary helpful in this case. It returns a single float value between ```0.0``` and ```1.0``` depending on the alignment of two vectors.
<div class="codeAndCanvas" data="2d-random.frag"></div>
Take a look at lines 13 to 15 and notice how we are comparing the ```vec2 st``` with another two dimensional vector ( ```vec2(12.9898,78.233)```).
* Try changing the values on lines 14 and 15. See how the random pattern changes and think about what we can learn from this.
* Hook this random function to the mouse interaction (```u_mouse```) and time (```u_time```) to understand better how it works.
## Using the chaos
Random in two dimensions looks a lot like TV noise, right? It's a hard raw material to use to compose images. Let's learn how to make use of it.
Our first step is to apply a grid to it; using the [```floor()```](../glossary/?search=floor) function we will generate an integer table of cells. Take a look at the following code, especially lines 22 and 23.
<div class="codeAndCanvas" data="2d-random-mosaic.frag"></div>
After scaling the space by 10 (on line 21), we separate the integers of the coordinates from the fractional part. We are familiar with this last operation because we have been using it to subdivide a space into smaller cells that go from ```0.0``` to ```1.0```. By obtaining the integer of the coordinate we isolate a common value for a region of pixels, which will look like a single cell. Then we can use that common integer to obtain a random value for that area. Because our random function is deterministic, the random value returned will be constant for all the pixels in that cell.
Uncomment line 29 to see that we preserve the floating part of the coordinate, so we can still use that as a coordinate system to draw things inside each cell.
Combining these two values - the integer part and the fractional part of the coordinate - will allow you to mix variation and order.
Take a look at this GLSL port of the famouse ```10 PRINT CHR$(205.5+RND(1)); : GOTO 10``` maze generator.
<div class="codeAndCanvas" data="2d-random-truchet.frag"></div>
Here I'm using the random values of the cells to draw a line in one direction or the other using the ```truchetPattern()``` function from the previous chapter (lines 41 to 47).
You can get another interesting pattern by uncommenting the block of lines between 50 to 53, or animate the pattern by uncommenting lines 35 and 36.
## Master Random
[Ryoji Ikeda](http://www.ryojiikeda.com/), Japanese electronic composer and visual artist, has mastered the use of random; it is hard not to be touched and mesmerized by his work. His use of randomness in audio and visual mediums is forged in such a way that it is not annoying chaos but a mirror of the complexity of our technological culture.
<iframe src="https://player.vimeo.com/video/76813693?title=0&byline=0&portrait=0" width="800" height="450" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
Take a look at [Ikeda](http://www.ryojiikeda.com/)'s work and try the following exercises:
* Make rows of moving cells (in opposite directions) with random values. Only display the cells with brighter values. Make the velocity of the rows fluctuate over time.
<a href="../edit.html#10/ikeda-00.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-00.frag" width="520px" height="200px"></canvas></a>
* Similarly make several rows but each one with a different speed and direction. Hook the position of the mouse to the threshold of which cells to show.
<a href="../edit.html#10/ikeda-03.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-03.frag" width="520px" height="200px"></canvas></a>
* Create other interesting effects.
<a href="../edit.html#10/ikeda-04.frag"><canvas id="custom" class="canvas" data-fragment-url="ikeda-04.frag" width="520px" height="200px"></canvas></a>
Using random aesthetically can be problematic, especially if you want to make natural-looking simulations. Random is simply too chaotic and very few things look ```random()``` in real life. If you look at a rain pattern or a stock chart, which are both quite random, they are nothing like the random pattern we made at the begining of this chapter. The reason? Well, random values have no correlation between them what so ever, but most natural patterns have some memory of the previous state.
In the next chapter we will learn about noise, the smooth and *natural looking* way of creating computational chaos.

@ -0,0 +1,221 @@
![NASA / WMAP science team](mcb.jpg)
## Noise
## ノイズ
It's time for a break! We have been playing with all this random functions that looks like TV white noise, our head is still spinning around thinking on shaders, and our eyes are tired. Time to get out for a walk!
We feel the air in our skin, the sun in our face. The world is such a vivid and rich place. Colors, textures, sounds. While we walk we can't avoid noticing the surface of the roads, rocks, trees and clouds.
![](texture-00.jpg)
![](texture-01.jpg)
![](texture-02.jpg)
![](texture-03.jpg)
![](texture-04.jpg)
![](texture-05.jpg)
![](texture-06.jpg)
The stochasticity of this textures could be call "random", but definitely they don't look like the random we were playing before. The “real world” is such a rich and complex place! So, how can we approximate to this level of variety computationally?
This was the question [Ken Perlin](https://mrl.nyu.edu/~perlin/) was trying to solve arround 1982 when he was commissioned with the job of generating a "more realistic" textures for a new disney movie call "Tron". In response to that he came up with an elegant *oscar winner* noise algorithm. No biggie.
![Disney - Tron (1982)](tron.jpg)
The following is not the clasic Perlin noise algorithm, but is a good starting point to understand how to generate *smooth random* aka *noise*.
<div class="simpleFunction" data="
float i = floor(x); // integer
float f = fract(x); // fraction
y = rand(i);
//y = mix(rand(i), rand(i + 1.0), f);
//y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
"></div>
In this lines we are doing something similar than the previus chapters, We are subdividing a continus floating value (```x````) in integers (```i```) using [```floor()```](.../glossary/?search=floor) and obtaining a random (```rand()```) number for each integer. At the same time we are storing the fractional part of each section using [```fract()```](.../glossary/?search=fract) and storing it on the ```f``` variable.
After that you will also see, two commented lines. The first one interpolates each random value linearly.
```glsl
y = mix(rand(i), rand(i + 1.0), f);
```
Go ahead and uncomment this line an see how that looks. We use the [```fract()```](.../glossary/?search=fract) value store in `f` to [```mix()```](.../glossary/?search=mix) the two random values.
At this point on the book, we learned that we can do better than a linear interpolation. Right?
Now try uncommenting the following line, which use a [```smoothstep()```](.../glossary/?search=smoothstep) interpolation instead of a linear one.
```glsl
y = mix(rand(i), rand(i + 1.0), smoothstep(0.,1.,f));
```
After uncommenting it, notice how the transition between the peaks got smooth. On some noise implementations you will find that some programers prefere to code their own cubic curves (like the following formula) instead of using the [```smoothstep()```](.../glossary/?search=smoothstep).
```glsl
float u = f * f * (3.0 - 2.0 * f ); // custom cubic curve
y = mix(rand(i), rand(i + 1.0), u); // using it in the interpolation
```
The *smooth random* is a game changer for graphical engeneers, it provides the hability to generate images and geometries with an organic feeling. Perlin's Noise Algorithm have been reimplemented over and over in different lenguage and dimensions for all kind of creative uses to make all sort of mesmerizing pieces.
![Robert Hodgin - Written Images (2010)](robert_hodgin.jpg)
Now is your turn:
* Make your own ```float noise(float x)``` function.
* Use the noise funtion to animate a shape by moving it, rotating it or scaling it.
* Make an animated composition of several shapes 'dancing' together using noise.
* Construct "organic-looking" shapes using the noise function.
* Once you have your "creature", try to develop further this into a character by assigning it a particular movement.
## 2D Noise
![](02.png)
Now that we know how to do noise in 1D, is time to port it to 2D. For that instead of interpolating between two points of a line (```fract(x)``` and ```fract(x)+1.0```) we are going to interpolate between the four coorners of a square area of a plane(```fract(st)```, ```fract(st)+vec2(1.,0.)```, ```fract(st)+vec2(0.,1.)``` and ```fract(st)+vec2(1.,1.)```).
![](01.png)
Similarly if we want to obtain 3D noise we need to interpolate between the eight coorners of a cube. This technique it's all about interpolating values of random. That's why is call **value noise**.
![](04.jpg)
Similarly to the previus example this interpolation is not liner but cubic, which smoothly interpolates any points inside our squared grid
![](05.jpg)
Take a look to the following noise function.
<div class="codeAndCanvas" data="2d-noise.frag"></div>
We start by scaling the space by 5 (line 45) in order. Then inside the noise function we subdived the space in cells similarly that we have done before. We store the integer position of the cell together with fractional inside values. We use the integer position to calculate the four corners corinates and obtain a random value for each one (lines 23-26). Then, finally in line 35 we interpolate 4 random values of the coorners using the fractional value we store before.
Now is your turn, try the following excersices:
* Change the multiplier of line 45. Try to animate it.
* At what level of zoom the noise start looking like random again?
* At what zoom level the noise is imperceptible.
* Try to hook up this noise function to the mouse coordinates.
* What if we treat the gradient of the noise as a distance field? Make something interesing with it.
* Now that you achieve some control over order and chaos, is time to use that knowledge. Make a composition of rectangles, colors and noise that resemble some of the complexity of the texture of the following painting made by [Mark Rothko](http://en.wikipedia.org/wiki/Mark_Rothko).
![Mark Rothko - Three (1950)](rothko.jpg)
## Using Noise on generative designs
As we saw, noise algorithms was original designed to give a natural *je ne sais quoi* to digital textures. So far all the implementations in 1D and 2D we saw, were interpolation between values reason why is usually call **Value Noise**, but there are more...
[ ![Inigo Quilez - Value Noise](value-noise.png) ](../edit.html#11/2d-vnoise.frag)
As you discovery on the previus excercises this type of noise tends to look "block", as a solution to this effect in 1985, again, [Ken Perlin](https://mrl.nyu.edu/~perlin/) develop another implementation of the algorithm call **Gradient Noise**. In it Ken figure out how to interpolate **random gradients** instead of values. This gradients where the result of 2D noise function that returns directions (represented by a ```vec2```) instead of single values (```float```). Click in the foolowing image to see the code and how it works.
[ ![Inigo Quilez - Gradient Noise](gradient-noise.png) ](../edit.html#11/2d-gnoise.frag)
Take a minute to look to these two examples by [Inigo Quilez](http://www.iquilezles.org/) and pay attention on the differences between [value noise](https://www.shadertoy.com/view/lsf3WH) and [gradient noise](https://www.shadertoy.com/view/XdXGW8).
As a painter that understand how the pigments of their paints works, the more we know about noise implementations the better we will learn how to use it. The following step is to find interesting way of combine and use it.
For example, if we use a two dimensional noise implementation to rotate the space where strign lines are render, we can produce the following swirly effect that looks like wood. Again you can click on the image to see how the code looks like
[ ![Wood texture](wood.png) ](../edit.html#11/wood.frag)
```glsl
pos = rotate2d( noise(pos) ) * pos; // rotate the space
pattern = lines(pos,.5); // draw lines
```
Another way to get interesting patterns from noise is to treat it like a distance field and apply some of the tricks described on the [Shapes chapter](../07/).
[ ![Splatter texture](splatter.png) ](../edit.html#11/splatter.frag)
```glsl
color += smoothstep(.15,.2,noise(st*10.)); // Black splatter
color -= smoothstep(.35,.4,noise(st*10.)); // Holes on splatter
```
A third way of using the noise function is to modulate a shapes, this also requires some of the techniques we learn on the [chapter about shapes](../07/)
<a href="../edit.html#11/circleWave-noise.frag"><canvas id="custom" class="canvas" data-fragment-url="circleWave-noise.frag" width="300px" height="300"></canvas></a>
For you to practice:
* What other generative pattern can you make? What about granite? marble? magma? water? Find three pictures of textures you are interested and implement them algorithmically using noise.
* Use noise to modulate a shapes.
* What about using noise for motion? Go back to the [Matrix chapter](../08/) and use the translation example that move a the "+" around to apply some *random* and *noise* movements to it.
* Make a generative Jackson Pollock
![Jackson Pollock - Number 14 gray (1948)](pollock.jpg)
## Simplex Noise
For Ken Perlin the success of his algorithm wasn't enough. He thought it could performance better. In Siggraph 2001 he presented the "simplex noise" in wich he achive the following improvements over the previus one:
* An algorithm with lower computational complexity and fewer multiplications.
* A noise that scales to higher dimensions with less computational cost.
* A noise without directional artifacts
* A noise with well-defined and continuous gradients that can be computed quite cheaply
* An algorithm that is easy to implemnt in hardware
Yeah, right? I know what you are thinking... "Who is this man?". Yes, his work is fantastic! But seriusly, How he did that? Well we saw how for two dimensions he was interpolating 4 points (coorners of a square); also we can correctly preasume that for [three (see an implementation here)](../edit.html#11/3d-noise.frag) and four dimensions we need to interpolate 8 and 16 points. Right? In other words for N dimensions you need to smoothly interpolate 2 to the N points (2^N). But Ken smartly notice that although the obvious choice for a space-filling shape is a squar, the actually simpliest shape in 2D is the equilateral triangle. So he start by replace the squared grid (we finnaly learn how to use) for a simplex grid of equilateral triangles.
![](simplex-grid-00.png)
The simplex shape for N dimensions is a shape with N + 1 corners. In other words one less corner to compute in 2D, 4 less coorners in 3D and 11 less coorners in 4D! That's a huge improvement!
So then, in two dimension the interpolation happens, similarly than regular noise, by interpolating the values of the corners of a section. But, in this particular case, because we are using a simplex grid, we just need to interpolate the sum of only 3 coornes ( contributors).
![](simplex-grid-01.png)
How the simplex grid works? In another brillant and elegant move, the simplex grid can be obtain by subdividing the cells of a regular 4 corners grid into two isoceles triangles and then skewing it unitl each triangle is equilateral.
![](simplex-grid-02.png)
Then, as [Stefan Gustavson describe in this paper](http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf): _"...by looking at the integer parts of the transformed coordinates (x,y) for the point we want to evaluate, we can quickly determine which cell of two simplices that contain the point. By also compareing the magnitudes of x and y, we can determine whether the points is in the upper or the lower simplex, and traverse the correct three corners points."_.
On the following code you can uncomment the line 44 to see how the grid is skew and then line 47 to see how a simplex grid can be constructed. Note how on line 22 we are subdiving the skewed squared on two equilateral triangles just buy detecting if ```x > y``` ("lower" triangle) or ```y > x``` ("upper" triangle).
<div class="codeAndCanvas" data="simplex-grid.frag"></div>
Other improvements introduce by Perlin in the **Simplex Noise**, is the replacement of the Cubic Hermite Curve ( _f(x) = 3x^2-2x^3_ , wich is identical to the (.../glossary/?search=smoothstep) function ) for a Quintic Hermite Curve ( _f(x) = 6x^5-15x^4+10x^3_ ). This makes both ends of the curve more "flat" and by gracefully stiching with the next one. On other words you get more continuos transition between the cells. You can watch this by uncommenting the second formula on the following graph example (or by see the [two equations side by side here](https://www.desmos.com/calculator/2xvlk5xp8b)).
<div class="simpleFunction" data="
// Cubic Hermine Curve. Same as SmoothStep()
y = x*x*(3.0-2.0*x);
// Quintic Hermine Curve
//y = x*x*x*(x*(x*6.-15.)+10.);
"></div>
Note how the ends of the curve changes. You can read more about this in [on words of Ken it self in this paper](http://mrl.nyu.edu/~perlin/paper445.pdf).
All this improvements result on a master peach of algorithms known as **Simplex Noise**. The following is an GLSL implementation of this algorithm made by Ian McEwan (and presented in [this paper](http://webstaff.itn.liu.se/~stegu/jgt2012/article.pdf)) which is probably over complicated for educational porposes because have been higly optimized, but you will be happy to click on it and see that is less cryptic than you expect.
[ ![Ian McEwan of Ashima Arts - Simplex Noise](simplex-noise.png) ](../edit.html#11/2d-snoise-clear.frag)
Well enought technicalities, is time for you to use this resource in your own expressive way:
* Contemplate how each noise implementation looks. Imagine them as a raw material. Like a marble rock for a sculptor. What you can say about about the "feeling" that each one have? Squinch your eyes to trigger your imagination, like when you want to find shapes on a cloud, What do you see? what reminds you off? How do you imagine each noise implementation could be model into? Following your guts try to make it happen on code.
* Make a shader that project the ilusion of flow. Like a lava lamp, ink drops, watter, etc.
<a href="../edit.html#11/lava-lamp.frag"><canvas id="custom" class="canvas" data-fragment-url="lava-lamp.frag" width="520px" height="200px"></canvas></a>
* Use Signed Noise to add some texture to a work you already made.
<a href="../edit.html#11/iching-03.frag"><canvas id="custom" class="canvas" data-fragment-url="iching-03.frag" width="520px" height="520px"></canvas></a>
In this chapter we have introduce some control over the chaos. Is not an easy job! Becoming a noise-bender-master takes time and efford.
On the following chapters we will see some "well-know" techniques to perfect your skills and get more out of your noise to design quality generative content with shaders. Until then enjoy some time outside contemplating nature and their intricate patterns. Your hability to observe need's equal (or probably more) dedication than your making skills. Go outside and enjoy the rest of day!
<p style="text-align:center; font-style: italic;">"Talk to the tree, make friends with it." Bob Ross
</p>

@ -28,9 +28,9 @@
* アルゴリズムで絵を描く
* [シェイピング関数](05/?lan=jp)
* [色について](06/?lan=jp)
* [Shapes未訳](07/)
* [Matrices未訳](08/)
* [Patterns未訳](09/)
* [形について](07/?lan=jp)
* [二次元行列](08/?lan=jp)
* [パターン](09/?lan=jp)
* Generative designs
* [Random未訳](10/)

@ -77,7 +77,7 @@ Thanks to my wife [Jen Lowe](http://www.datatelling.com/), for her unconditional
Thanks [Scott Murray](http://alignedleft.com/) for the inspiration and advice.
Thanks [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) for the [Japanese translation (日本語訳)](?lan=jp)
Thanks [Kenichi Yoneda (Kynd)](https://twitter.com/kyndinfo) and [Sawako](https://twitter.com/sawakohome) for the [Japanese translation (日本語訳)](?lan=jp)
Thanks [Karim Naaji](http://karim.naaji.fr/) for contributing with support, good ideas and code.

@ -31,6 +31,7 @@ h1, h2, h3 {
}
h3 {
margin-top: 56px;
margin-bottom: 5px;
}

Loading…
Cancel
Save