エンジンと高速化

このプラグインには複数の実行エンジンがあります。標準は同梱の LuaJIT ネイティブレーンで、 決まった形の重いピクセル処理はさらに CPU カーネルへ変換されます。Lua 5.2 互換の MoonSharp は フォールバック用の従来エンジンです。指定子を書かなくても、内容に応じて自動で最適なレーンが選ばれます。

エンジンの種類

エンジン指定子特徴
ネイティブ(LuaJIT)--!native(既定)別プロセスの LuaJIT で実行。ピクセル処理が大幅に高速
MoonSharp--!moonsharpLua 5.2 互換。フォールバック用の従来エンジン
CPU カーネル--!cpu決まった形のピクセルループを並列実行へ変換。SIMD を実測で使い分け、MoonSharp と一致する結果
GPU カーネル--!gpuピクセルループを GPU シェーダーに変換。最速だが float32 精度(明示指定のみ)
スライダー obj.slider0obj.slider3 と文字列パラメータ obj.text / obj.font / obj.dir / obj.file_* は、 MoonSharp とネイティブのどちらのエンジンでも同じ名前で参照できます。 CPU カーネルと GPU カーネルは数値計算に特化するため、文字列を扱いません。

指定子の書き方

エンジンの指定子は --! で始まる 1 行です。トークンの前後の空白以外に文字があってはいけません。 スクリプトのどの行に書いても構いません。

--!native
for y = 0, obj.h - 1 do
    for x = 0, obj.w - 1 do
        local r, g, b, a = obj.getpixel(x, y)
        obj.setpixel(x, y, 255 - r, 255 - g, 255 - b, a)
    end
end

自動振り分け

指定子が無いときは、スクリプトの内容から自動でエンジンが選ばれます。

明示した指定子は自動振り分けより優先されます。GPU カーネルは浮動小数点の 32 ビットで計算するため、 自動で選ぶときは初回の検証に通ったプログラムだけを対象とし、CPU カーネルと食い違うことはありません。 --!gpu を明示したときは検証に通れば GPU、通らなければ CPU カーネルで実行します。

カーネルに変換できる形

CPU / GPU カーネルは、次の決まった形のスクリプトだけを変換します。条件に合わないスクリプトは カーネルにならず、自動でほかのエンジンへフォールバックします(結果は変わりません)。

obj.getpixeldata() で得たハンドルの get / setlocal i = (y * data.width + x) * 4 の基底インデックスで使う形も同様にカーネル化されます。 ループの後の obj.putpixeldata(data) は置いても置かなくてもかまいません。 if 文の中で obj.setpixelset を呼ぶ形はカーネル化されません。

カーネル内で使える要素は限られます。

分類使えるもの
演算子+ - * / % ^、単項マイナス、条件式 cond and a or b
math 関数abs, floor, ceil, sqrt, sin, cos, tan, asin, acos, atan, atan2, exp, log, pow, fmod, min, max
math 定数math.pi, math.huge
条件比較(< > <= >= == ~=)、and / or / notobj.check0obj.check3
参照できる値座標 x / yobj の各フィールド、scene.width/height/cx/cytime, frame, totalframe, framerate, timelineframe, timelinetime, layer, color
CPU カーネルは、4 画素をまとめて計算する SIMD 経路を持ちます。SIMD が有利かどうかは カーネルの内容と実行環境で変わるため、最初の数フレームでスカラ経路と SIMD 経路の両方を 実行して時間を計り、速かった経路をそのプログラムで使い続けます。どちらの経路でも出力は 同一です。

カーネルになるグレースケールの例

for y = 0, obj.h - 1 do
    for x = 0, obj.w - 1 do
        local r, g, b, a = obj.getpixel(x, y)
        local gray = r * 0.299 + g * 0.587 + b * 0.114
        obj.setpixel(x, y, gray, gray, gray, a)
    end
end

フォールバックの動き

GPU カーネルは float32 精度で計算するため、MoonSharp / CPU カーネルとわずかに結果が異なることがあります。 厳密に一致させたい場合は CPU カーネルかネイティブを使ってください。
← ピクセル操作 パラメータ指定子 →