AGAL入門的メモ第二弾です。
各レジスタには浮動少数値のx,y,z,wのプロパティがあり、コンポーネントと呼ばれます。つまり、レジスタ=4次ベクトル変数だと思えば良いです。こちらを演算時に指定した場合の挙動についてまとめます。(AGAL固有の話ではなさそう。)
コンポーネント指定なしでの演算
mul vt0, vt1, vt2
これは下記に等しいです。
mul vt0.xyzw, vt1.xyzw, vt2.xyzw
mul掛け算の命令で、わかりやすく書くと、vt0 = vt1 * vt2
と、なります。各要素ごとに演算をすることになります。
vt1 = {1,2,3,4}
、vt2 = {2,2,3,3}
の場合、 vt0 = {2,4,9,12}
の結果が入ります。
(vt1 = {1,2,3,4}
という書き方はvt1.x=1
、vt1.y=2
、vt1.z=3
、vt1.w=4
の状態をこの記事内のルールとして記してみたものです。)
コンポーネントを指定指定した演算
4つまで好きな組み合わせ+好きな順番+重複ありで記述できます。以下はすべて正しい記述です。ざっと200通り以上組み合わせはありそうです。
vt0.x
vt0.z
vt0.xy
vt0.yy
vt0.xzz
vt0.zwz
vt0.xxxx
vt0.xzzw
演算命令では各コンポーネント指定数を揃えるのが基本になります。コンポーネント指定なしは4つの指定だと思えば良いです。
add vt0.x, vt1.x, vt2.x
add vt0.xy, vt1.zw, vt2.yy
add vt0.xyz, vt1.yzw, vt2.zzz
add vt0, vt1.zyxw, vt2.yzwy
xyzwの順番が入れ替わっている場合も、頭から1つずつ個別の演算をされると思えば良いです。結果をおさめるレジスタにコンポーネント指定して結果をおさめる対象を狭める事を、マスクする、と言います。
add vt0, vt1.zyxw, vt2.yzwy
をかみ砕いて疑似コードで書くと
vt0.x = vt1.z + vt2.y;
vt0.y = vt1.y + vt2.z;
vt0.z = vt1.x + vt2.w;
vt0.w = vt1.w + vt2.y;
となります。単純な処理の演算子ではこのような計算になりますが、いわゆる行列演算をする場合はそれぞれで別のルールがあります。外積をベクトル演算するcrs
という命令では、
crs vt0.xyz, vt1.xyz, vt2.xyz
//は下記になる
vt0.x = vt1.y * vt2.z - vt1.z * vt2.y
vt0.y = vt1.z * vt2.x - vt1.x * vt2.z
vt0.z = vt1.x * vt2.y - vt1.y * vt2.x
という結果になります。
http://help.adobe.com/en_US/as3/dev/WSd6a006f2eb1dc31e-310b95831324724ec56-8000.html ここに各演算時の詳細が記されています。component-wise
と記載がある命令が最初の例のように要素ごとに演算をする命令となります。nrm
、crs
、m33
、m34
などは結果を収めるレジスタは3つ以下にマスクされていなくてはいけないと書いてあります。
m44
演算時などにコンポーネントの順序を入れ替えて指定するとどうなるかは、ちょっとわかりません。そのような需要があるのかどうか含めて、余裕があれば調べてみます。
コンポーネント指定数がずれた演算
結果がおさめられるレジスタに限っては、他の2つ(1つ)と指定コンポーネント数がずれても演算がなされる場合があります。
sub vt0.xyz, vt1.x, vt2.x
//↓
vt0.x = vt0.y = vt0.z = vt1.x - vt2.x;
と、なります。(なるはずです。)
おわりに
コンポーネント指定数がずれた演算
の項目のように微妙なコンポーネント数指定の演算になるとやってみてのテストが確認がしずらく、かつパターンがたくさんあるので、実際に手元でいろいろ実証できていない状況です。ここでまとめた内容とは違った結果になるかもしれませんが、なにかあれば記事に追加修正します。
そのように微妙なコンポーネント指定をした場合、mul
の乗算においてAGALのコンパイラ側にバグがあり正しい結果を得られなかった、との情報もあるので、ご注意ください。4年前の情報なのでさすがに修正されているかと思いますが。最新のAGALMiniAssembler.asはここにあります。AGAL3まで対応しています。
前回も紹介した、Introduction to AGAL: Part 2 こちらを元にこの記事をかきました。素晴らしい記事をありがとう。