フィルタをかけると画面全体が拡大されてしまう

概要

以下のようなpixi.jsのオーバーレイフィルタをピクチャにかけると画面全体(マップ全体)が拡大されてしまう現象があるそうで、その解析をしていました。

1
$gameScreen.picture(1)._blendMode = PIXI.BLEND_MODES.OVERLAY;

フィルタかける前

フィルタかけた後

ただ発生するのはスペックの低めのPCだけであり、通常は発生しないようです。
手持ちのPCで発生するのが一台あり、簡単なスペックは以下です。

1
Windows 7 Home Premium 32-bit 
2
Core(TM) i5 CPU M 520
3
Intel(R) HD Graphics

オーバーレイについて

pixi.jsはデフォルトでは以下にコメントされているようにオーバーレイは利用できず、pixi-picture.jsを読み込むことによって利用できます。
ファイルはツクールMVのlibフォルダに存在していて自動的に読み込まれています。

1
IMPORTANT - The WebGL renderer only supports the NORMAL, ADD, MULTIPLY and SCREEN blend modes.
2
Anything else will silently act like NORMAL.

フィルタをかけると

ピクチャのblendModeをOVERLAYに変えると最終的に以下の箇所の処理が大きく変わります。
細かいことはおいといて、最終的にstageにvoidFilterが適用されるようになります。
ここでいうstageはScene_Mapです。
このvoidFilterは何もしないフィルターのはずですが、なぜかこれが適用されると拡大されます。
Scene_Mapに適用されるので画面全体が拡大されてしまいます。

1
Sprite.prototype._speedUpCustomBlendModes = function(renderer) {
2
    var picture = renderer.plugins.picture;
3
    var blend = this.blendMode;
4
    if (renderer.renderingToScreen && renderer._activeRenderTarget.root) {
5
        if (picture.drawModes[blend]) {
6
            var stage = renderer._lastObjectRendered;
7
            var f = stage._filters;
8
            if (!f || !f[0]) {
9
                setTimeout(function () {
10
                    var f = stage._filters;
11
                    if (!f || !f[0]) {
12
                        stage.filters = [Sprite.voidFilter];
13
                        stage.filterArea = new PIXI.Rectangle(0, 0, Graphics.width, Graphics.height);
14
                    }
15
                }, 0);
16
            }
17
        }
18
    }
19
};

ためしに、コンソールからSceneManager._scene.filters = [Sprite.voidFilter]と実行すると拡大されるのでOVERLAYフィルタの問題ではなく、このvoidFilterの影響だと考えられます。

voidFilterのpadding?

pixi.jsのfilterにはpaddingというメンバがあります。これはデフォルトで4に設定されていて、このpaddingを0に変えると拡大がなぜか直ります・・・。

pixi.jsのバージョンについて

この現象ですが最新のchromeでゲームをブラウザで起動しても発生します。
また、pixi.jsの4.7.1以降だと発生せず、4.7.0だと発生します(MVは4.5.4)。

解決策

paddingを0にするプラグインを作成しました。私のPCではこれで解決します。
また、これを適用してリリースして頂いたプロダクトは特に問題の報告もないようです。

VoidFilterPadding.js