The Book of Shaders by Patricio Gonzalez Vivo & Jen Lowe

Bahasa Indonesia - Tiếng Việt - 日本語 - 中文版 - 한국어 - Español - Portugues - Français - Italiano - Deutsch - Русский - Polski - English


二次元行列

平行移動

前の章では図形を描く方法を学びました。この章では描いた図形を動かしてみましょう。秘訣は座標系自体を動かしてしまうことです。これはそれぞれのフラグメント(ピクセル)の位置を格納する変数 st にベクトルを加えれば簡単に実現することができます。

説明するよりも実際に見た方が簡単です。自分自身で試してみましょう。

下記の課題に挑戦してみましょう。

回転

物体を回転させるにはやはり空間全体を動かす必要があります。そのためには行列(matrix)を使います。行列とは行(横方向)と列(縦方向)に並べられた数字の集まりです。決められたルールに従ってベクトルに行列を掛け合わせることで、ベクトルの値をある法則に沿って変化させることができます。

行列 - Wikipedia

GLSLはネイティブで二次元、三次元、四次元の行列をサポートしています。mat2(2×2)、mat3 (3×3)、mat4 (4×4)がそれぞれ対応します。GLSLはまた行列の掛け算(*) や行列に特化した関数(matrixCompMult())もサポートします.

行列の性質をうまく使うと、特定の作用を生み出すことができます。例えば行列を使ってベクトルを平行移動させることができます。

さらに興味深いことに、行列は座標系を回転させるためにも使うことができます。

二次元の回転行列を作り出す下記のコードを見てみましょう。この関数は二次元ベクトルについての上記の公式に従って vec2(0.0) を中心に座標を回転させます。

mat2 rotate2d(float _angle){
    return mat2(cos(_angle),-sin(_angle),
                sin(_angle),cos(_angle));
}

これまでに学んだ描画方法を思い出してみると、この関数は本当に欲しいものとはちょっと違います。私たちの十字は描画領域の中心に相当する( vec2(0.5) )に描かれています。そのため、空間を回転させる前に図形を中心から vec2(0.0) まで移動させてやる必要があります。移動させたらその場で空間を回転させ、またもとの場所に戻してやります。

コードで示すと下記のようになります。

下記の課題に挑戦してみましょう。

拡大・縮小

ここまでは行列を使って物体を空間の中で平行移動させたり回転させたりする様子(より正確には、座標系全体を変形させることで物体を動かしたり回転させる様子)を見てきました。3DモデリングのソフトウェアやProcessingのpushやpopなどの行列関数を使ったことがあれば、行列を使って物体の大きさを拡大・縮小できることもご存知でしょう。

上記の公式に従えば、二次元の拡大・縮小を行う行列を作ることができます。

mat2 scale(vec2 _scale){
    return mat2(_scale.x,0.0,
                0.0,_scale.y);
}

下記の課題に挑戦して理解を深めましょう。

その他の行列の用途: YUVカラー

YUVは人間の知覚できる範囲を考慮して色成分の帯域を減らすことのできる、写真やビデオのアナログエンコーディングで用いられる色空間です。

下記のコードは色を1つのモードから別のモードに変換する、GLSLでの行列演算の面白い使い道の例です。

見てのとおり色をベクトルとして扱い行列を掛け合わせています。このようにして色の値を「動かす」ことができるのです。

この章では行列を使ってベクトルを移動、回転、拡大・縮小する方法を学びました。これらの変形は、前章で学んだ図形を組み合わせてより複雑な図を作成するのに欠かせない技術です。次の章ではこれまで学んだことを全て活かして、規則に基づいた美しいパターンを作成します。コードによる反復と変化の楽しさを発見しましょう。