MFGとは
MFGはModern Filter language for GPUからつけた名前で、画像処理アプリに組み込む、2次元の画像に対してのフィルタを記述するための言語です。 大きな特徴としてiPadでもPCと同じフィルタが動きます。
言語はフィルタ用に独自に作ったモダンなスクリプト言語で、最初からGPUで動くことを前提にシェーダーの実行モデルに合わせた仕様となっています。
シンタックスはSwiftやJavaScriptに似ていますが、関数などは各種シェーダーや、Halide、PyTorchやRなどの機械学習系のものと揃えています。
例:ネガポジ反転
一番簡単なネガポジ反転フィルタは以下のようになります。
@title "ネガポジ反転"
def result_u8 |x, y|{
let [b, g, r, a] = input_u8(x, y)
u8[255-b, 255-g, 255-r, a]
}
言語の詳細やもっと複雑な例については、以下を参照ください。
iPadでスクリプトで書いたフィルタを動かすために必要な事
iPadでスクリプトで書いたフィルタを動かすと言うのはいくつかのチャレンジがあります。MFGというものが必要になったのも、これらの理由からです。
フィルタは極めて大きいコンピューティングパワーを要求する
ブラシのスクリプトなどは比較的良く見られる一方で、フィルタのスクリプトがあまり普及していない理由の一つに、フィルタと言うのは極めて大きなコンピューティングリソースを必要とする、と言うのが挙げられます。
フィルタは多くの場合に全ピクセルに対して計算をする必要があり、その計算量はピクセル数に依存します。そしてiPadは、画面の解像度が極めて高いデバイスです。写真などの外から入ってくるデータのピクセル数も膨大なため、通常のスクリプトでは全く遅くて使い物にならないほどの計算リソースが必要となってしまいます。
実際、グラフィックスにまつわるものは通常のCPUではなくGPUという専用のハードウェアが使われています。これはまさにグラフィックスの計算リソースが膨大になってきている為、CPUでは処理が間に合わないからでもあります。
iPad(厳密にはApple Store)ではJITが使えない
割と有名な事ですが、実行属性をつけたメモリを作るようなフラグを立てるとApple Storeの審査でrejectされます。その為、よくPCなどで使われているパフォーマンスが十分なスクリプト言語をそのパフォーマンスを生かしたまま使うことは出来ません。
ただでさえCPUでは厳しいフィルタにおいて、JITが使えないと言うのは、事実上通常のスクリプト言語では不可能という事を意味します。
iPadで外部で書かれたスクリプトでフィルタを実現する場合、実質的には以下の二つの選択肢しかありません。
- JavaScriptで実装してWebCoreを使ってJITする
- Metal(シェーダー)のコンパイルを使う
MFGは後者の手段を取っています(前者は少し複雑なフィルタになるとパフォーマンス的に厳しい)
なぜただシェーダーを使うだけではダメなのか?
最終的にシェーダーとしてコンパイルするなら、最初からシェーダーを書けばいいじゃないか、と思うかもしれないけれど、これにはホスト側のコードを書く方法が無い、という問題がある。
シェーダーを外部から実行する仕組みの場合、通常は何らかの方法でホスト側のコードをホスト側の言語で拡張する仕組みがついているものだが、iOSの場合はWebGLやUnityのような手頃な何かがない。(むしろそうしたプラグイン的な事が出来ないようにAppleは頑張っている)
一方、MFGはスクリプトを解析してスクリプトに合わせたホスト側のコードも自動で作られる。特に複数カーネルをスクリプトだけで作れる、というのがMFGの大きな特徴となっている。
大雑把に言えば、
MFG = シェーダー + ホスト側コード
と言える。
この辺のより詳しい話は以下のページも参照のこと。