Flashで使えるシェーダ言語を作ってみた

いい加減AGALでシェーダを書くのが辛くなってきたので、
FlashのStage3Dで使えるシェーダ言語を作りました。

ついでにレイトレしてみました。
>> Open ray tracing demo (Required Flash Player 16 or later)
>> View source code

 

何ができるの?

OGSL – Oimo Graphics Shading Language を使うと
Stage3DのシェーダプログラムがGLSLっぽく書けます。
アセンブリと格闘する日々とお別れできます。

早速試してみる

ここからソースコードをダウンロードしてソースフォルダに配置する。

Stage3Dが使えるように設定後Sample.asを起動する。

ぐるぐるが表示されればOK。下のほうにあるOGSL_SOURCEをいじってみましょう。

設定とかいいから…

今すぐ試したい方はこちらのオンラインエディタをどうぞ。
フラグメントシェーダを適当に編集してコンパイルボタンを押しましょう。
uniform変数をいじるとエラーになるので注意。

言語概要

ActionScript3.0に似てます。

基本的なところをコメント付きで載せてみました。
丁度AS3とGLSLの中間的な文法なのが分かるかと思います。
次から細かい部分を見ていきます。

型について

float, vec2, vec3, vec4, mat3x4, mat4x4, texture 型があります。
texture型はフラグメントシェーダの外部定数としてのみ使えます。使い方は後述。

型の扱いの雰囲気が掴めたでしょうか。
続いては行列です。

mat3x3はこの辺の事情によりありません。mat3x4を使ってください。

関数について

main関数のほかにも関数を定義して呼び出せます。ただし再帰的な呼び出しはできません。
また、return文を書く場合は必ず関数の最後にする必要があります。

AS3的にはやや破格の文法ですが参照渡しもできます。通常は全て値渡しです。

条件分岐

AS3と同じように使えます。
条件に使える演算子は >, >=, <, <=, ==, !=, ||, && のみ。優先順位もAS3と同じです。 否定(!)は使えないので注意。 また、条件文にfloat型を指定することができ、その場合は != 0 の判定がなされます。

ループ

実はAGALにはループ命令がありません。
そのためOGSLでのループは静的ループのみで、全て強制的に展開されます。
ループを多用すると命令数の上限にわりとすぐ引っかかりますのでご注意を。

continue, break文はありません。頑張りましたが階層をぶち壊す系の命令は
どうしても技術的に無理でした…。AGALにジャンプ命令が欲しい。

テクスチャを利用する

tex2DまたはtexCube関数を使うとテクスチャをサンプリングできます。
AGALの制約上、uniformで宣言したテクスチャは全てサンプリングしなくてはならず、また、
条件分岐の内部でのサンプリングはできなくなっています。

フラグメントシェーダの強制終了

discard文を使うと色を出力せずにフラグメントシェーダを
途中で終了させることができます。

ビルトイン関数一覧

引数の型は指定がない場合は任意ですが、異なる型を渡すと怒られることあります。
(例えばmin関数の第1引数にvec2型を、第2引数にvec3型を渡すとエラーになるが、
第1引数にfloat型を、第2引数にvec3型を渡した場合は、floatがvec3に自動変換されるため
エラーは生じない)

最適化について

AGALで書き出すときに自動で最適化してくれますが、過度な期待は禁物です。
最適化内容は、コピー伝播、不要命令削除、命令並列化、一時レジスタ数削減、
定数畳み込みなど。あまり賢くないので共通式削除とかはやってくれません。

よくありそうな質問

Q. 他のライブラリへの依存は?
 A. AGALを吐き出すだけなら依存なし。
   AGALのアセンブルにはAGALMiniAssembler等が必要。
Q. GLSL2AGAL使ったら?
 A. よくバグるしAGAL2非対応なのでお勧めしません。
Q. int型はないの?
 A. ないです。float型を使ってください。
Q. boolean型はないの?
 A. 実はfloat型がboolean型の代わりになったりします。お試しあれ。
Q. MRTとか偏微分命令は使えないの?
 A. 使えません。どうしても使いたい場合は出力されたAGALをいじってください。
Q. AGAL2でしか出力できないの?
 A. 条件分岐(if文)を使わなければAGAL1でも動きます。
Q. 他のライブラリとあわせて使いたい!
 A. AGALが使えるライブラリなら一緒に使えます。
   各種レジスタのindexはOGSLクラスから取得可能。
Q. バグを発見したけどどうすれば?
 A. コメント欄に書くかTwitterでreplyを送ると直すかもしれません。
Q. Stage3Dってどう設定するの?
 A. ここでは触れないので各自で調べてください。
Q. 改造していい?
 A. MITライセンスなのでご自由にどうぞ。
Q. 他にどうしても分からないことが…
 A. コメント欄に書くかTwitterでreplyを送ると答えるかもしれません。
Q. ソース汚い
 A. ごめんね

おわりに

最初は自分用に作ってましたが、
どうせならということでまとめてライブラリ形式にしてみました。
何かの役に立てば嬉しいです。

そろそろゲーム作りたい。

2 Responses to “Flashで使えるシェーダ言語を作ってみた”

  1. genesis01 より:

    元気ですかッ!!

Leave a Reply