Flash3D/AGALでシェーダー
AGALでシェーダー
プログラマブルシェーダーの項でAGALMiniAssemblerというクラスを使ってシェーダーを作成する短いコードのサンプルを載せましたが、あの頃はまだAGALMiniAssemblerがSDKに標準で含まれているものと思ってました。あれはcom.adobe.utilsパッケージで配布されている便利クラスだったのですね。assembleメソッドに渡す文字列がAGALと呼ばれる言語で、それをバイトコードに翻訳してくれるのがAGALMiniAssemblerクラスの目的のようです。なので、このクラスを使わずにバイトコードに予め翻訳したものをProgram3D.uploadメソッドに渡すこともできるようです。バイトコードに翻訳する処理が繰り返し行われるような実装にすることはそんなにないと思うので、実行時に翻訳してもさして問題にならないと思います。何よりAGALをActionScriptの中で編集できるのは保守作業を少し楽にしてくれそうです。逆にPixelBender3Dでシェーダープログラムを書くと、何をするにも一段階作業が増えそうです。AGALの仕様を読んだ感じではシンプルな内容だったので、AGALでシェーダーを書くのでもよさそうに思いました。
なんか、AGALって言葉を適当に使って語弊が生じるような気がしてきたので、補足を入れるとソースに書くテキストの状態もAGALだし、バイトコードに変換された状態もAGALであると理解しています。両者を峻別する単語ってあるんでしょうかね。
AGALは現在シェーダーを想定した仕様にとどまっていますが、もうちょっと汎用的な用途に使えるようになったらいいんじゃないかなと夢をみています。将来的に物理演算部分もAGALで書けるようになるかもしれないし、AGALのことをもうちょっと詳しく調べてみようと思います。
OpCode
AGALではGPUを操作するためにOpCodeという命令が定義されています。命令のあとには出力を一つ、入力を一つか二つ持っています。この命令を組み合わせて必要な数値(座標位置とか表示色)を計算させるのですが、入力が二つまでに限定されているため、例えば、1+2+4を計算する場合は、1+2=3と3+4=7という二つの足し算の命令に分けてあげる必要があります。計算の順序を考えて、パズルのようにOpCodeを組み合わせれば複雑な計算も可能になります。
- mov
- 入力1を出力1にコピー
- add
- 入力1と入力2の和を出力1に設定
- sub
- 入力1と入力2の差を出力1に設定
- mul
- 入力1と入力2の積を出力1に設定
- div
- 入力1と入力2の商を出力1に設定
- rcp
- 入力1の逆数を出力1に設定
- min
- 入力1と出力1の小さい方を出力1に設定
- max
- 入力1と出力1の大きい方を出力1に設定
- frc
- 入力1の小数点以下の数値を出力1に設定
- sqt
- 入力1の平方根を出力1に設定
- rsq
- 入力1の平方根の逆数を出力1に設定
- pow
- 入力1の累乗(入力1を[入力2]個分乗算)を出力1に設定
- log
- 2を底とする入力1の対数を出力1に設定
- exp
- 2の累乗(2を[入力1]個分乗算)を出力1に設定
- nrm
- 入力1を正規化して出力1に設定
- sin
- 入力1の正弦を出力1に設定
- cos
- 入力1の余弦を出力1に設定
- crs
- 入力1と入力2の外積を出力1に設定
- dp3
- 入力1と入力2の内積(3x3)を出力1に設定
- dp4
- 入力1と入力2の内積(4x4)を出力1に設定
- abs
- 入力1の絶対値を出力1に設定
- neg
- 入力1の反数を出力1に設定
- sat
- 入力1を0-1の範囲に収めて出力1に設定
- m33
- 入力1と入力2の3x3の行列の積を出力1に設定
- m44
- 入力1と入力2の4x4の行列の積を出力1に設定
- m34
- 入力1と入力2の3x4の行列の積を出力1に設定
- kil
- 入力に0より小さい数値が含まれていたら描画をしない(フラグメントシェーダーのみ)
- tex
- 入力2のテクスチャ中の、入力1の座標位置からカラーサンプルをとって出力1に設定(フラグメントシェーダーのみ)
- sge
- 入力1が入力2以上であれば出力1に1を設定、そうでなければ0を設定
- slt
- 入力1が入力2より小さければ出力1に1を設定、そうでなければ0を設定
- seq
- 入力1と入力2が等しければ出力1に1を設定、そうでなければ0を設定
- sne
- 入力1と入力2が等しくなければ出力1に1を設定、そうでなければ0を設定
AGALMiniAssemblerの中身をみるとその他に"ifz", "inz", "ife", "ine", "ifg", "ifl", "ieg", "iel", "els", "eif", "rep", "erp", "brk", "sgn"といったOpCodeが予約されているようですが、まだ実用化されていないようです。なんとなく条件分岐に使うものが多そうですが、古いGPUで使えないとかそんな事情でもあるんでしょうか。
レジスター
OpCodeの入出力値に指定するのはレジスターと呼ばれる文字です。
- va0-va7
- Context3D.setVertexBufferAtで設定された入力値(座標、色、UV座標など)
- vc0-vc127
- Context3D.setProgramConstantsで設定された入力値(シェーダーで共通で利用する値など)
- fc0-fc27
- Context3D.setProgramConstantsで設定された入力値(シェーダーで共通で利用する値など)
- vt0-vt7
- 一時的な変数
- ft0-ft7
- 一時的な変数
- op
- バーテックスシェーダーの出力値(頂点の座標)
- oc
- フラグメントシェーダーの出力値(ピクセルの色)
- v0-v7
- バーテックスシェーダーからフラグメントシェーダーに渡される数値
- fs0-fs7
- テクスチャデータのサンプラー(サンプラーの動作を指定できる<(2d, 3d, cube)|(nomip, mipnone, mipnearest)|(nearest, linear)|(repeat, wrap, clamp)>)
Date: 2011/11/21
- Androidアプリ/日記5Activityの設計もできたので、実際にActivityの詳細を実装していきます。まずはInputWeightアクティビティから始めてみることにします。これはâ¦
- PuzzleNoteアプリ名 PuzzleNote 公開場所 Google Play 詳細はこちら 作曲する必要があったので、自分風のエディタを考えてみました。 PuzzleNotâ¦
- 開発日記/2013年の日記Adobe AIRのアプリを開発中に詰まったメモ。AIRでは簡易データベースとしてSQLiteが組み込まれているのでアプリの履歴に関するデータをSQLiteのテâ¦
- Androidアプリ/日記8SoftbankキャリアのHTC Desireも2010年10月8日にAndroid OS 2.2へのアップデートを果たしました。噂の通り、動作が全般的に機敏にâ¦
WPF/日記4昨日、うまくいかなかった部分について検討を加えて直してみました。画像を貼り付けたポリゴンがうまく表示されなかった原因は、貼り付けた画像のサイズが極端に大きかったâ¦- Androidアプリ/日記2Androidアプリを作成する前に、しばらく既存のアプリで遊んでみてどんなことができるのか、どんなUI設計が望ましいのか観察していました。やはり携帯電話のアプリâ¦
- 開発日記/2026年の日記日本語URLのお話です。このサイトもそうなのですが、Wikiっぽい仕組みを使ってよくサイトを作ります。それでドメイン名にWikiName(記事名)をくっつけたらâ¦
- Androidアプリ/日記10Android端末の普及とともに、本屋さんの棚のiPhone開発関連書籍の隅のAndroid開発関連書籍が増えてきたような気がします。パラパラとめくってみても、â¦
- MinimalSoojiアプリ名 MinimalSooji 公開場所 Google Play 詳細はこちら 日本には大掃除という文化があります。年越し前に家を清め、元旦を美しく迎えようâ¦
- Flash3D/プログラマブルシェーダー実際にプログラマブルシェーダーを実装する場合、以下のような感じになるらしいそうです。 var vertexShaderAssembler:AGALMiniAssâ¦