You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
thebookofshaders/08/README-jp.md

103 lines
7.0 KiB
Markdown

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