08, 09 - drafted

This commit is contained in:
kynd 2015-12-19 12:50:59 -08:00
parent 0c66466e01
commit d323e99376
5 changed files with 468 additions and 11 deletions

View File

@ -150,50 +150,70 @@ Translating this to a shader where each square on the grid paper is a pixel impl
There are several ways to calculate that distance. The easiest one uses the [```distance()```](../glossary/?search=distance) function, which internally computes the [```length()```](../glossary/?search=length) of the difference between two points (in our case the pixel coordinate and the center of the canvas). The ```length()``` function is nothing but a shortcut of the [hypotenuse equation](http://en.wikipedia.org/wiki/Hypotenuse) that uses square root ([```sqrt()```](../glossary/?search=sqrt)) internally.
距離を計算するには幾つかの方法があります。最も簡単なのは [```distance()```](../glossary/?search=distance) 関数を使うことです。この関数は内部的に2つの点の差を取りその [```length()```](../glossary/?search=length) を計算します(今回のケースではピクセルの座標と描画領域の中心が対象です)。```length()``` 関数は [ピタゴラスの定理](https://ja.wikipedia.org/wiki/%E6%96%9C%E8%BE%BA)
距離を計算するには幾つかの方法があります。最も簡単なのは [```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)
You can use [```distance()```](../glossary/?search=distance), [```length()```](../glossary/?search=length) or [```sqrt()```](../glossary/?search=sqrt) to calculate the distance to the center of the billboard. The following code contains these three functions and the non-surprising fact that each one returns exactly same result.
[```distance()```](../glossary/?search=distance), [```length()```](../glossary/?search=length), [```sqrt()```](../glossary/?search=sqrt) のいずれかを使っって中心までの距離を計算することができます。下記のコードにはこれら3つの関数が全て含まれていますが、当然ながら全く同じ結果になります。
* Comment and uncomment lines to try the different ways to get the same result.
* コメントを付け替えて、違う方法を使っても同じ結果が得られることを確かめましょう。
<div class="codeAndCanvas" data="circle-making.frag"></div>
In the previous example we map the distance to the center of the billboard to the color brightness of the pixel. The closer a pixel is to the center, the lower (darker) value it has. Notice that the values don't get too high because from the center ( ```vec2(0.5, 0.5)``` ) the maximum distance barely goes over 0.5. Contemplate this map and think:
このサンプルでは中心からの距離をピクセルの明るさに割り当てました。中心に近いピクセルほど値が低く(暗く)なります。中心( ```vec2(0.5, 0.5)``` からの距離は最大でルート2の半分訳注原文で0.5はとなっていますが誤りです。)にしかならないため一番明るいところでも真っ白にはなりません。このサンプルをよく見て考えてみてください。
* What you can infer from it?
* 何か気づいたことはありますか。
* How we can use this to draw a circle?
* これをどう使えば縁が描けるでしょう。
* Modify the above code in order to contain the entire circular gradient inside the canvas.
* コードを書き換えて円形のグラデーションの全体が病領域に収まるようにしてください。
### Distance field
### ディスタンスフィールド
We can also think of the above example as an altitude map, where darker implies taller. The gradient shows us something similar to the pattern made by a cone. Imagine yourself on the top of that cone. The horizontal distance to the edge of the cone is 0.5. This will be constant in all directions. By choosing where to “cut” the cone you will get a bigger or smaller circular surface.
上のサンプルは、暗い色ほど標高が高いことを示した、高低差を表す地図だと考えることもできます。このグラデーションは円錐のようなものを表しています。円錐の頂上に立ったところを想像してください。円錐の縁までの距離は2分のルート2訳注原文では0.5となっています。)です。これはどの方角でも同じです。どこで円錐を「輪切りに」するかを決めることで、大きさの違う円を得ることができます。
![](distance-field.jpg)
Basically we are using a re-interpretation of the space (based on the distance to the center) to make shapes. This technique is known as a “distance field” and is used in different ways from font outlines to 3D graphics.
要するにここでは空間を中心からの距離に基づいて解釈し直すことによって形を作っています。この手法は ディスタンスフィールドと呼ばれ、フォントのアウトラインから3Dグラフィクスまで様々な用途に使われています。
(訳注distance field の適当な訳語が見当たらなかったのでカタカナで「ディスタンスフィールド」とします。おおざっぱに、点や図形からの距離を空間上にマップしたものだと考えてください。)
Try the following exercises:
下記の課題に挑戦しましょう。
* Use [```step()```](../glossary/?search=step) to turn everything above 0.5 to white and everything below to 0.0.
* [```step()```](../glossary/?search=step) を使って、0.5以上を超える全て白に、それ以外を黒にしてください。
* Inverse the colors of the background and foreground.
* 背景と図形の色を反転させてください。
* Using [```smoothstep()```](../glossary/?search=smoothstep), experiment with different values to get nice smooth borders on your circle.
* 円の縁を滑らかにしてみましょう。[```smoothstep()```](../glossary/?search=smoothstep) を使って色々な値を試してください。
* Once you are happy with an implementation, make a function of it that you can reuse in the future.
* うまくできたら後で再利用できるように関数として定義してください。
* Add color to the circle.
* 円に色をつけてください。
* Can you animate your circle to grow and shrink, simulating a beating heart? (You can get some inspiration from the animation in the previous chapter.)
* 心臓の鼓動のように円を伸縮させるアニメーションを作ることはできますか。(前章のアニメーションを参考にしましょう。)
* What about moving this circle? Can you move it and place different circles in a single billboard?
* 円を移動させることはできますか。円を別の場所に動かして、さらにもう1つの円を別の場所に描くことはできますか。
* What happens if you combine distances fields together using different functions and operations?
* 複数のディスタンスフィールドを色々なる演算や関数を使って組み合わせると何が起きるでしょう。
```glsl
pct = distance(st,vec2(0.4)) + distance(st,vec2(0.6));
@ -204,39 +224,68 @@ pct = pow(distance(st,vec2(0.4)),distance(st,vec2(0.6)));
```
* Make three compositions using this technique. If they are animated, even better!
* これらのテクニックを使った作品を3つ作ってください。アニメーションにできればさらに素敵です。
#### For your tool box
#### 便利な道具箱
In terms of computational power the [```sqrt()```](../glossary/?search=sqrt) function - and all the functions that depend on it - can be expensive. Here is another way to create a circular distance field by using [```dot()```](../glossary/?search=dot) product.
平方根([```sqrt()```](../glossary/?search=sqrt))や、それに依存した関数はどれもコンピュータの処理能力に負荷をかける可能性があります。下記は円形のディスタンスフィールドを作る別の方法で、平方根の代わりに内積([```dot()```](../glossary/?search=dot) )を使います。
<div class="codeAndCanvas" data="circle.frag"></div>
### Useful properties of a Distance Field
### ディスタンスフィールドの便利な性質
![Zen garden](zen-garden.jpg)
Distance fields can be used to draw almost everything. Obviously the more complex a shape is, the more complicated its equation will be, but once you have the formula to make distance fields of a particular shape it is very easy to combine and/or apply effects to it, like smooth edges and multiple outlines. Because of this, distance fields are popular in font rendering, like [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) and [as is describe on Chapter 7 of iPhone 3D Programming, OReilly](http://chimera.labs.oreilly.com/books/1234000001814/ch07.html#ch07_id36000921).
ディスタンスフィールドを使ってほとんどどんなものでも描くことができます。もちろん形が複雑なほどより複雑な計算式が必要ですが、一旦ある形のディスタンスフィールドを作り出すための式を手に入れたら、複数の形を組み合わせることや、縁をぼかしたり何重にも線を引い引いたりと様々なエフェクトをかけたりすることはとても簡単にできます。そのため下記の例に見られるようにディスタンスフィールドはフォントのレンダリングによく使われています。
* [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)
Take a look at the following code.
下記のコードをみてください
<div class="codeAndCanvas" data="rect-df.frag"></div>
We start by moving the coordinate system to the center and shrinking it in half in order to remap the position values between -1 and 1. Also on *line 24* we are visualizing the distance field values using a [```fract()```](../glossary/?search=fract) function making it easy to see the pattern they create. The distance field pattern repeats over and over like rings in a Zen garden.
まず座標系を中心に動かして半分の大きさに縮小することで値が -1 から 1の間に収まるようにします訳注16行目の式の 2.と 1.を書き換えて見ると理解の助けになります。24行目では [```fract()```](../glossary/?search=fract) 関数を使ってディスタンスフィールドの形が見やすいように視覚化しています。ディスタンスフィールドは禅寺の庭
のような繰り返しの模様を作り出します。
Lets take a look at the distance field formula on *line 19*. There we are calculating the distance to the position on ```(.3,.3)``` or ```vec3(.3)``` in all four quadrants (thats what [```abs()```](../glossary/?search=abs) is doing there).
19行目のディスタンスフィールドを作り出す式を見てみましょう。4つの象限すべてで ```vec3(.3)```、つまり ```(.3,.3)``` までの
距離を計算しています([```abs()```](../glossary/?search=abs) を使って座座標を絶対値にしてから距離を求めています)
If you uncomment *line 20*, you will note that we are combining the distances to these four points using the [```min()```](../glossary/?search=min) to zero. The result produces an interesting new pattern.
20行目のコメントを外すと [```min()```](../glossary/?search=min) を使って0と比べた最低値を求めることで4つの店への距離を組み合わせた場合を見ることができます。面白い新しい形を作り出します
Now try uncommenting *line 21*; we are doing the same but using the [```max()```](../glossary/?search=max) function. The result is a rectangle with rounded corners. Note how the rings of the distance field get smoother the further away they get from the center.
さて21行目のコメントを外して見ましょう。[```max()```](../glossary/?search=max) を使っていること以外は同じです。結果は角丸の四角形になります。ディスタンスフィールドの輪は中心から遠ざかるほど滑らかなグラデーションになっています。
Finish uncommenting *lines 27 to 29* one by one to understand the different uses of a distance field pattern.
27行目から29行目までのコメントを順番に外して、ディスタンスフィールドを使ってパターンを作る様々な方法を学びましょう。
### Polar shapes
### 極座標を使った図形
![Robert Mangold - Untitled (2008)](mangold.jpg)
In the chapter about color we map the cartesian coordinates to polar coordinates by calculating the *radius* and *angles* of each pixel with the following formula:
色についての章ではそれぞれのピクセルについて、下記の式を使って半径と角度を計算することでデカルト座標を極座標に変換しました。
```glsl
vec2 pos = vec2(0.5)-st;
float r = length(pos)*2.0;
@ -245,10 +294,17 @@ In the chapter about color we map the cartesian coordinates to polar coordinates
We use part of this formula at the beginning of the chapter to draw a circle. We calculated the distance to the center using [```length()```](../glossary/?search=length). Now that we know about distance fields we can learn another way of drawing shapes using polar coordinates.
本章の前半ではこの式の一部を利用して円を描きました。[```length()```](../glossary/?search=length)を使って中心からそれぞれのピクセルまでの距離を計算したのですね。ディスタンスフィールドのことを知った今、我々は極座標を使って図形を描く新たな手法について学ぶことができます。
This technique is a little restrictive but very simple. It consists of changing the radius of a circle depending on the angle to achieve different shapes. How does the modulation work? Yes, using shaping functions!
この手法は少し用途が限られますがとてもシンプルです。様々な異なる図形を描くために、角度に対する半径の大きさをいろいろと変化させます。どうやって変化させるのでしょう。そうです、シェイピング関数を使います。
Below you will find the same functions in the cartesian graph and in a polar coordinates shader example (between *lines 21 and 25*). Uncomment the functions one-by-one, paying attention the relationship between one coordinate system and the other.
下記の2つのサンプルでは、いくつかの同じ関数を、デカルト座標と極座標の両方で試すことができます。一方の座標系ともう片方の座標系との関係に注意しながら、コメントを1つづつ外してください。
<div class="simpleFunction" data="y = cos(x*3.);
//y = abs(cos(x*3.));
//y = abs(cos(x*2.5))*0.5+0.3;
@ -258,25 +314,48 @@ Below you will find the same functions in the cartesian graph and in a polar coo
<div class="codeAndCanvas" data="polar.frag"></div>
Try to:
下記を試してみましょう。
* Animate these shapes.
* 図形をアニメーションさせてください。
* Combine different shaping functions to *cut holes* in the shape to make flowers, snowflakes and gears.
* 異なるシェイピング関数を組み合わせて図形の中に穴を開けてください。花や雪の結晶、ギヤなどを描いてください。
* Use the ```plot()``` function we were using in the *Shaping Functions Chapter* to draw just the contour.
* シェイピング関数の章で使った ```plot()```関数を利用して輪郭線だけを描いてください。
### Combining powers
### 技を組み合わせる
Now that we've learned how to modulate the radius of a circle according to the angle using the [```atan()```](../glossary/?search=atan) to draw different shapes, we can learn how use ```atan()``` with distance fields and apply all the tricks and effects possible with distance fields.
さて [```atan()```](../glossary/?search=atan)を使って、角度に対する半径の大きさを変化させて図形を描く方法について学びました。次は ```atan()``` をディスタンスフィールドと組み合わせて、すべての技を駆使する方法を学びます。
The trick will use the number of edges of a polygon to construct the distance field using polar coordinates. Check out [the following code](http://thndl.com/square-shaped-shaders.html) from [Andrew Baldwin](https://twitter.com/baldand).
この方法では多角形の辺の数を元に極座標を使ってディスタンスフィールドを構成します。[Andrew Baldwin](https://twitter.com/baldand)による、[下記のコード](http://thndl.com/square-shaped-shaders.html)をご覧ください。
<div class="codeAndCanvas" data="shapes.frag"></div>
* Using this example, make a function that inputs the position and number of corners of a desired shape and returns a distance field value.
* このサンプルを使って、ピクセルの位置と書きたい図形の頂点の数を入力とし、ディスタンスフィールドの値を返す関数を作ってください。
* Mix distance fields together using [```min()```](../glossary/?search=min) and [```max()```](../glossary/?search=max).
* [```min()```](../glossary/?search=min) と [```max()```](../glossary/?search=max) を使ってディスタンスフィールドを組み合わせてみましょう。
* Choose a geometric logo to replicate using distance fields.
* 幾何学的なロゴをなにか1つ選んでディスタンスフィールドを使って再現してみましょう。
Congratulations! You have made it through the rough part! Take a break and let these concepts settle - drawing simple shapes in Processing is easy but not here. In shader-land drawing shapes is twisted, and it can be exhausting to adapt to this new paradigm of coding.
おめでとうございます。これで大変なところを乗り越えました。一息入れて、学んだことを頭のなかに落ち着けましょう。[Processing](https://processing.org/)を使えばシンプルな形を描くのは簡単なことですが、ここで学んだことは違います。シェーダーの世界では形を描くのにもひねくれたやり方をしなくてはなりませんし、新しいコーディングの考え方に慣れるのは疲れる仕事です。
Now that you know how to draw shapes I'm sure new ideas will pop into your mind. In the following chapter you will learn how to move, rotate and scale shapes. This will allow you to make compositions!

171
08/README-jp.md Normal file
View File

@ -0,0 +1,171 @@
## 2D Matrices
## 二次元行列
<canvas id="custom" class="canvas" data-fragment-url="matrix.frag" width="700px" height="200px"></canvas>
### Translate
### 平行移動
In the previous chapter we learned how to make some shapes - the trick to moving those shapes is to move the coordinate system itself. We can achieve that by simply adding a vector to the ```st``` variable that contains the location of each fragment. This causes the whole space coordinate system to move.
前の章では図形を描く方法を学びましたね。形を動かすには座標系自体を動かしてしまいます。これはそれぞれのフラグメント(ピクセル)の位置を格納する ```st``` 変数にベクトルを加えれば簡単に実現することができます。こうすることで座標系の全体を動かすことができるのです。
![](translate.jpg)
This is easier to see than to explain, so to see for yourself:
説明するよりも実際に見た方が簡単です。自分自身で試してみましょう。
* Uncomment line 35 of the code below to see how the space itself moves around.
* 下記のコードの35行目のコメントを外して、空間全体が動いているのを確認しましょう。
<div class="codeAndCanvas" data="cross-translate.frag"></div>
Now try the following exercise:
下記の課題に挑戦してみましょう。
* Using ```u_time``` together with the shaping functions move the small cross around in an interesting way. Search for a specific quality of motion you are interested in and try to make the cross move in the same way. Recording something from the "real world" first might be useful - it could be the coming and going of waves, a pendulum movement, a bouncing ball, a car accelerating, a bicycle stopping.
* ```u_time``` とシェイピング関数を使って小さな十字に面白い動きをさせてください。気になる動き方の例を探して、同じように十字を動かしてみましょう。寄せて返す波や、振り子、弾むボール、加速する自動車、自転車が止まるところなど、まずは現実世界のできごとを録画してみるのも良いかもしれません。
### Rotations
### 回転
To rotate objects we also need to move the entire space system. For that we are going to use a [matrix](http://en.wikipedia.org/wiki/Matrix_%28mathematics%29). A matrix is an organized set of numbers in columns and rows. Vectors are multiplied by matrices following a precise set of rules in order to modify the values of the vector in a particular way.
物体を回転させるにはやはり空間全体を動かす必要があります。そのためには[行列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 has native support for two, three and four dimensional matrices: [```mat2```](../glossary/?search=mat2) (2x2), [```mat3```](../glossary/?search=mat3) (3x3) and [```mat4```](../glossary/?search=mat4) (4x4). GLSL also supports matrix multiplication (```*```) and a matrix specific function ([```matrixCompMult()```](../glossary/?search=matrixCompMult)).
GLSLはネィテイブで二次元、三次元、四次元の行列をサポートしています。[```mat2```](../glossary/?search=mat2)2x2、[```mat3```](../glossary/?search=mat3) 3x3、[```mat4```](../glossary/?search=mat4) 4x4がそれぞれ対応します。GLSLはまた行列の掛け算```*```
や行列に特化した関数([```matrixCompMult()```](../glossary/?search=matrixCompMult))もサポートします.
Based on how matrices behave it's possible to construct matrices to produce specific behaviors. For example we can use a matrix to translate a vector:
行列の性質をうまく使うと、特定の振る舞いを作り出すことができます。例えば行列を使ってベクトルを平行移動させることができます。
![](3dtransmat.png)
More interestingly, we can use a matrix to rotate the coordinate system:
さらに興味深いことに行列は座標系を回転させるためにも使うことができます。
![](rotmat.png)
Take a look at the following code for a function that constructs a 2D rotation matrix. This function follows the above [formula](http://en.wikipedia.org/wiki/Rotation_matrix) for two dimentional vectors to rotate the coordinates around the ```vec2(0.0)``` point.
二次元の回転行列を作り出す下記のコードをご覧ください。この関数は二次元のベクトルについての上記の[公式](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));
}
```
According to the way we've been drawing shapes, this is not exactly what we want. Our cross shape is drawn in the center of the canvas which corresponds to the position ```vec2(0.5)```. So, before we rotate the space we need to move shape from the `center` to the ```vec2(0.0)``` coordinate, rotate the space, then finally move it back to the original place.
これまでに形を描いてきた方法に照らし合わせると、これは本当に欲しいものとはちょっと違います。私たちの十字はに相当する描画領域の中心( ```vec2(0.5)``` )に描かれています。そのため、空間を回転させる前に図形を中心から ```vec2(0.0)``` まで移動させてやる必要があります。移動させたらその場で空間を回転させ、またもとの場所に戻してやります。
![](rotate.jpg)
That looks like the following code:
コードで示すと下記のようになります。
<div class="codeAndCanvas" data="cross-rotate.frag"></div>
Try the following exercises:
下記の課題に挑戦してみましょう。
* Uncomment line 45 of above code and pay attention to what happens.
* 45行目のコメントを外して何が起きるかに注目してください。
* Comment the translations before and after the rotation, on lines 37 and 39, and observe the consequences.
* 37行目と39行目、回転の前後にある平行移動をコメントアウトして、結果を観察しましょう。
* Use rotations to improve the animation you simulated in the translation exercise.
平行移動についての課題で作った作品を回転を使ってさらに改善してみましょう。
### Scale
### 拡大・縮小
We've seen how matrices are used to translate and rotate objects in space. (Or more precisely to transform the coordinate system to rotate and move the objects.) If you've used 3D modeling software or the push and pop matrix functions in Processing, you will know that matrices can also be used to scale the size of an object.
ここまでは行列が物体を空間の中で平行移動させたり回転させたりする様子より正確には、行列が座標系全体を変形させることで物体を動かしたり回転させたる様子を見てきました。3Dモデリングに詳しい方やProcessingでpushやpopを使って行列を操作する方法に慣れていれば、行列を使って物体の大きさを拡大・縮小できることもご存知でしょう。
![](scale.png)
Following the previous formula, we can figure out how to make a 2D scaling matrix:
上に登場したの公式に従うと二次元の拡大・縮小を行う行列の作り方もわかります。
```glsl
mat2 scale(vec2 _scale){
return mat2(_scale.x,0.0,
0.0,_scale.y);
}
```
<div class="codeAndCanvas" data="cross-scale.frag"></div>
Try the following exercises to understand more deeply how this works.
下記の課題に挑戦し理解を深めましょう。
* Uncomment line 42 of above code to see the space coordinate being scaled.
* 上記のコードの42行目のコメントを外して空間座標が拡大・縮小していることを確認しましょう。
* See what happens when you comment the translations before and after the scaling on lines 37 and 39.
* 37行目と39行目、拡大・縮小の前後にある平行移動をコメントアウトして、結果を観察しましょう。
* Try combining a rotation matrix together with a scale matrix. Be aware that the order matters. Multiply by the matrix first and then multiply the vectors.
* 回転行列と拡大・縮小を行う行列を組み合わせてみましょう。順番が重要なので注意してください。行列どうしを掛け合わせてから最後にベクトルを掛けるようにします。
* Now that you know how to draw different shapes, and move, rotate and scale them, it's time to make a nice composition. Design and construct a [fake UI or HUD (heads up display)](https://www.pinterest.com/patriciogonzv/huds/). Use the following ShaderToy example by [Ndel](https://www.shadertoy.com/user/ndel) for inspiration and reference.
* 様々な図形の描き方、回転、拡大・縮小のやり方を身につけたので、今度はそれらを組み合わせてより複雑なものを構成してみましょう。[架空の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>
### Other uses for matrices: YUV color
### その他の行列の用途: YUVカラー
[YUV](http://en.wikipedia.org/wiki/YUV) is a color space used for analog encoding of photos and videos that takes into account the range of human perception to reduce the bandwidth of chrominance components.
[YUV](https://ja.wikipedia.org/wiki/YUV)は人間の知覚できる範囲を考慮して色成分の帯域を減した訳注Wikipediaの[https://ja.wikipedia.org/wiki/YUV#.E8.89.B2.E5.B7.AE.E6.88.90.E5.88.86.E3.82.92.E9.96.93.E5.BC.95.E3.81.8F.E6.96.B9.E6.B3.95](https://ja.wikipedia.org/wiki/YUV#.E8.89.B2.E5.B7.AE.E6.88.90.E5.88.86.E3.82.92.E9.96.93.E5.BC.95.E3.81.8F.E6.96.B9.E6.B3.95)の項を参照)、写真やビデオのアナログエンコーディングで用いられる色空間です。
The following code is an interesting opportunity to use matrix operations in GLSL to transform colors from one mode to another.
下記のコードはGLSLでの行列演算の面白い使い道として、色を1つのモードから別のモードに変換する例を示しています。
<div class="codeAndCanvas" data="yuv.frag"></div>
As you can see we are treating colors as vectors by multiplying them with matrices. In that way we “move” the values around.
ご覧のとおり色をベクトルとして扱い行列を掛け合わせています。このようにして色の値を「動かす」ことができるのです。
In this chapter we've learned how to use matrix transformations to move, rotate and scale vectors. These transformations will be essential for making compositions out of the shapes we learned about in the previous chapter. In the next chapter we'll apply all we've learned to make beautiful procedural patterns. You will find that coding repetition and variation can be an exciting practice.
この章では行列を使ってベクトルを移動、回転、拡大・縮小する方法を学びました。これらの変形は前章で学んだ図形の描き方を組み合わせて、より複雑な図形を作成するのに欠かせない技術です。次の章ではこれまで学んだことを全て生かして、規則に基づいた美しいパターンを作成します。コードによる繰り返しと変奏をお楽しみください。

207
09/README-jp.md Normal file
View File

@ -0,0 +1,207 @@
## Patterns
## パターン
Since shader programs are executed by pixel-by-pixel no matter how much you repeat a shape the number of calculations stays constant. This means that fragment shaders are particulary suitable for tile patterns.
シェーダーのプログラムはピクセルごとに処理するので同じ形を何度も繰り替えしたとしても計算の回数は一定に止まります。このことからフラグメントシェーダーはタイルのようなパターンに特に適していると言えます。
[ ![Nina Warmerdam - The IMPRINT Project (2013)](warmerdam.jpg) ](../edit.html#09/dots5.frag)
In this chapter we are going to apply what we've learned so far and repeat it along a canvas. Like in previous chapters, our strategy will be based on multiplying the space coordinates (between 0.0 and 1.0), so that the shapes we draw between the values 0.0 and 1.0 will be repeated to make a grid.
この章ではこれまでに学んだことを生かし、描画領域のなかで繰り返していきます。前章で行ったのと同様に、空間座標に対して掛け算を行い、0.0から1.0の間に掛かれた図形がグリッド状に繰り返されるようにします。
*"The grid provides a framework within which human intuition and invention can operate and that it can subvert. Within the chaos of nature, regular patterns provide a constrast and promise of order. From early patterns on pottery to geometric mosaics in Roman baths, people have long used grids to enhance their lives with decoration."* [*10 PRINT*, Mit Press, (2013)](http://10print.org/)
*「グリッドは人間の直感と創意が働くための枠組みを提供し、and that it can subvert
自然界のカオスの中に、規則的なパターンは対比と秩序の兆しをもたらします。
古くはローマの浴場にみられる幾何学的なモザイクのパターンから、人々はグリッドを用い生活を豊かに彩ってきました。」*[*10 PRINT*, Mit Press, (2013)](http://10print.org/)
First let's remember the [```fract()```](../glossary/?search=fract) function. It returns the fractional part of a number, making ```fract()``` in essence the modulo of one ([```mod(x,1.0)```](../glossary/?search=mod)). In other words, [```fract()```](../glossary/?search=fract) returns the number after the floating point. Our normalized coordinate system variable (```st```) already goes from 0.0 to 1.0 so it doesn't make sense to do something like:
まず [```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);
}
```
But if we scale the normalized coordinate system up - let's say by three - we will get three sequences of linear interpolations between 0-1: the first one between 0-1, the second one for the floating points between 1-2 and the third one for the floating points between 2-3.
しかしここで正規化された座標系を拡大すると ー例えば3倍にしてみましょうー 0から1までの滑らかに変化する値の繰り返しを3つ得ることができます。1つ目は0から1までの値、2つ目は2から3までの値の少数部分、3つめは2から3までの値の少数部分です。
<div class="codeAndCanvas" data="grid-making.frag"></div>
Now it's time to draw something in each subspace, by uncommenting line 27. (Because we are multiplying equally in x and y the aspect ratio of the space doesn't change and shapes will be as expected.)
ここで、27行目のコメントを外して分割されたそれぞれの空間の中に何か描いてみましょう。xとyを等しく拡大しているので空間のアスペクト比は変わらず、期待した通りの形が描かれます。
Try some of the following exercises to get a deeper understanding:
下記の課題を幾つか試して理解を深めましょう。
* Multiply the space by different numbers. Try with floating point values and also with different values for x and y.
* 空間にたいして違う数をかけてみましょう。少数部分を持つ数を試したり、xとyに違う数を掛けてみましょう。
* Make a reusable function of this tiling trick.
* このタイリングのテクニックを再利用可能な関数にしてみましょう。
* Divide the space into 3 rows and 3 columns. Find a way to know in which column and row the thread is and use that to change the shape that is displaying. Try to compose a tic-tac-toe match.
* 空間を3列3行に分割します。スレッドがどの列と行にいるのかを知る方法を考えて、表示する図形を変えてください。Tic-tac-toe×ゲームを描いてみましょう。
### Apply matrices inside patterns
### パターンの中で行列を適用する
Since each subdivision or cell is a smaller version of the normalized coordinate system we have already been using, we can apply a matrix transformation to it in order to translate, rotate or scale the space inside.
それぞれの分割された空間は、これまで使ってきたのと同じ正規化された座標系をただ小さくしたものになっているので、行列変換をそれぞれの空間内での平行移動や回転、拡大・縮小に使うことができます。
<div class="codeAndCanvas" data="checks.frag"></div>
* Think of interesting ways of animating this pattern. Consider animating color, shapes and motion. Make three different animations.
* このパターンをアニメーションさせる面白いアイデアを考えてください。色、形、動きについて考えましょう。3種類の異なるアニメーションを作成してください。
* Recreate more complicated patterns by composing different shapes.
* 異なる形を組み合わせてより複雑なパターンを作ってみましょう。
<a href="../edit.html#09/diamondtiles.frag"><canvas id="custom" class="canvas" data-fragment-url="diamondtiles.frag" width="520px" height="200px"></canvas></a>
* Combine different layers of patterns to compose your own [Scottish Tartan Patterns](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).
* 異なるパターンのレイヤーを重ねてオリジナルの[タータンチェック](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)
### Offset patterns
### パターンをずらす
So let's say we want to imitate a brick wall. Looking at the wall, you can see a half brick offset on x in every other row. How we can do that?
ブロックの壁を模したパターンを作りたいとします。壁を観察すると、1行おきにブロック半個分だけx座標がずれていることに気づくでしょう。
![](brick.jpg)
As a first step we need to know if the row of our thread is an even or odd number, because we can use that to determine if we need to offset the x in that row.
xをずらす必要があるかを決めるには、まず現在のスレッドが偶数行と奇数行のどちらに当たるのかを知る必要があります。
____we have to fix these next two paragraphs together____
To determine if our thread is in an odd or even row, we are going to use [```mod()```](../glossary/?search=mod) of ```2.0``` and then see if the result is under ```1.0``` or not. Take a look at the following formula and uncomment the two last lines.
スレッドが奇数行か複数行かを求めるには、```2.0``` の剰余([```mod()```](../glossary/?search=mod) を拡大した座標系に対して用い値が1.0を下回るかどうかを見ます。下記のコードの最後の2行のコメントを外して見ましょう。
訳注このサンプルではxは0.0から1.0ではなく-4から4の範囲にすでに拡大されています。コメントを外すとxの整数部分が奇数になる、つまり ```mod(x, 2.0)``` が1.0以上になる場合にだけyが1.0になります。)
<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>
As you can see we can use a [ternary operator](https://en.wikipedia.org/wiki/%3F:) to check if the [```mod()```](../glossary/?search=mod) of ```2.0``` is under ```1.0``` (second line) or similarly we can use a [```step()```](../glossary/?search=step) function which does that the same operation, but faster. Why? Although is hard to know how each graphic card optimizes and compiles the code, it is safe to assume that built-in functions are faster than non-built-in ones. Everytime you can use a built-in function, use it!
ご覧のとおり、``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行目) を使ってより高速に処理を行うことができます。グラフィックスカードがどのように最適化されていてどのようにコードをコンパイルするのかを知るのは難しいことですが、組み込み関数はそうでない関数に比べて高速に処理されると考えて問題ありません。組み込み関数が使える場合には必ず使うようにしましょう。
So now that we have our odd number formula we can apply an offset to the odd rows to give a *brick* effect to our tiles. Line 14 of the following code is where we are using the function to "detect" odd rows and give them a half-unit offset on ```x```. Note that for even rows, the result of our function is ```0.0```, and multiplying ```0.0``` by the offset of ```0.5``` gives an offset of ```0.0```. But on odd rows we multiply the result of our function, ```1.0```, by the offset of ```0.5```, which moves the ```x``` axis of the coordinate system by ```0.5```.
偶奇判定の式ができたので、これでタイルの奇数行ををブロックらしく見せることができます。下記のコードの14行目の関数で、奇数行かどうかを判定して ```x``` をブロック半個分ずらしています。この関数は偶数行に対して ```0.0``` を返します。ブロック半個分の ```0.5``` をかけると結果は ```0.0```です。奇数行に対しては ```1.0``` を返すので ```0.5``` を掛けた結果、座標系をx軸方向に ```0.5``` だけ移動させることになります。
Now try uncommenting line 32 - this stretches the aspect ratio of the coordinate system to mimic the aspect of a "modern brick". By uncommenting line 40 you can see how the coordinate system looks mapped to red and green.
32行目のコメントを外してみましょう。こうすると座標系のアスペクト比が引き伸ばされて現代のブロックの比率になります。40行目のコメントを外すと座標系の様子が赤と緑の色で示されるのを見ることができます。
<div class="codeAndCanvas" data="bricks.frag"></div>
* Try animating this by moving the offset according to time.
* このサンプルを、時間とともにブロックをずらしていくことでアニメーションさせてください。
* Make another animation where even rows move to the left and odd rows move to the right.
* 偶数行が左に、奇数行が右に動くアニメーションを作りましょう。
* Can you repeat this effect but with columns?
* 行方向ではなく列方向に対して同じ効果を適応するできますか。
* Try combining an offset on ```x``` and ```y``` axis to get something like this:
* ```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>
## Truchet Tiles
## トルシェタイル
Now that we've learned how to tell if our cell is in an even or odd row or column, it's possible to reuse a single design element depending on its position. Consider the case of the [Truchet Tiles](http://en.wikipedia.org/wiki/Truchet_tiles) where a single design element can be presented in four different ways:
升目が偶数行と奇数行(または列)どちらに当たるかの判定方法を学んだ今、デザイン要素を場所に応じて再利用することができます。
同じデザイン要素が4種類の方法で使われる、[トルシェタイル](http://en.wikipedia.org/wiki/Truchet_tiles) を例として考えてみましょう。
![](truchet-00.png)
By changing the pattern across tiles, it's possible to contruct an infinite set of complex designs.
タイルごとのパターンを変えることによって、複雑なデザインを無限に組み立てることができます。
![](truchet-01.png)
Pay close attention to the function ```rotateTilePattern()```, which subdivides the space into four cells and assigns an angle of rotation to each one.
```rotateTilePattern()``` に注目してください。この関数は空間を4つの升目に分割しそれぞれに回転の角度を割り当てます。
<div class="codeAndCanvas" data="truchet.frag"></div>
* Comment, uncomment and duplicate lines 69 to 72 to compose new designs.
* 69行目から72行目までのコメントをつけたり外したり、行をコピーしたりして新しいデザインを作りましょう。
* Change the black and white triangle for another element like: half circles, rotated squares or lines.
* 黒と白の三角を他のデザイン要素、例えば半円や回転する正方形、線などに変えてみましょう。
* Code other patterns where the elements are rotated according to their position.
* 要素がその位置に応じて回転するパターンを作成してください。
* Make a pattern that changes other properties according to the position of the elements.
* 要素の場所によって他の属性(訳注:例えば色)を変化させるパターンを作ってください。
* Think of something else that is not necessarily a pattern where you can apply the principles from this section. (Ex: I Ching hexagrams)
* 必ずしも繰り返しのパターンではないもので、この項で学んだ原則を使える例を考えてください(例;八卦の組み合わせの一覧)。
<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>
## Making your own rules
##
Making procedural patterns is a mental exercise in finding minimal reusable elements. This practice is old; we as a species have been using grids and patterns to decorate textiles, floors and borders of objects for a long time: from meanders patterns in ancient Greece, to Chinese lattice design, the pleasure of repetition and variation catches our imagination. Take some time to look at [decorative](https://archive.org/stream/traditionalmetho00chririch#page/130/mode/2up) [patterns](https://www.pinterest.com/patriciogonzv/paterns/) and see how artists and designers have a long history of navigating the fine edge between the predictability of order and the surprise of variation and chaos. From Arabic geometrical patterns, to gorgeous African fabric designs, there is an entire universe of patterns to learn from.
規則によるパターン作りは、再利用可能な最小の要素を見つける頭の体操です。この行為自体は古くからあるもので、私たちの種はグリッドとパターンを織物や床をはじめ様々なものを装飾するために長い間利用してきました。曲がりくねった古代ギリシャの模様から中国の格子模様まで、繰り返しとその変奏をする楽しみはは私たちの想像力を捉えて来ました。ゆっくりと装飾的なパターン(例: [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)
With this chapter we end the section on Algorithmic Drawing. In the following chapters we will learn how to bring some entropy to our shaders and produce generative designs.
この章で「アルゴリズムで絵を描く」の説は終わりです。続く章ではある種の無秩序さをシェーダーに持ち込んでデザインを生成する方法について学びます。

View File

@ -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);
}

View File

@ -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);
}