Phaser3: Lightを使う 

今回はLightを使ってみようと思います。

スプライトでノーマルマッピング

Phaser3のスプライトはノーマルマッピングをサポートしており、lightを当てたときにスプライトの凹凸を表現できます。

GIMPでノーマルマップを作成する

まずはスプライト用のノーマルマップを作成します。

SpriteIlluminator - Normalmap Editor for 2d Dynamic Lightingが高機能で使いやすそうなのですが、フリー版ではノーマルマップの出力ができないのでGIMPのノーマルマッププラグインを使います。
こちらの画像をもとに、 f:id:Phaser_3:20190117134945p:plain こちらのノーマルマップを作成しました。 f:id:Phaser_3:20190117135011p:plain

Phaser3に取り込む

ノーマルマップ付きのスプライトを作成する

まずはノーマルマップ付きのスプライトを作成します。
[スプライト、ノーマルマップ]の形でload.imageを実行するとノーマルマップ付きのテクスチャデータが作成されます。

//ノーマルマップ
this.load.image("rect", ["assets/images/rect3.png", "assets/images/rect2_normal.png"]);


createでスプライトを作成し、setPipelineでlight2Dを指定します。
light2Dはphaserに組み込まれているシェーダのようです。

create() {

    let rect = this.add.sprite(this.sys.canvas.width / 2, this.sys.canvas.height / 2,  "rect");

    //light2dのパイプライン
    rect.setPipeline("Light2D")

}

次にlightを追加し、マウスに追従させるようにします。

        create() {

            let rect = this.add.sprite(this.sys.canvas.width / 2, this.sys.canvas.height / 2,  "rect");

            //light2dのパイプライン
            rect.setPipeline("Light2D")

            //ライトを追加
            let light = this.lights.addLight(0, 0, 200);

            this.lights.enable().setAmbientColor(0x555555);

            this.input.on('pointermove', function (pointer) {
                light.x = pointer.x;
                light.y = pointer.y;
            });
        }

実行結果がこちらです。 f:id:Phaser_3:20190117135733g:plain すこしわかりにくいので、灰色のスプライトにライティングを行ってみました。 f:id:Phaser_3:20190117140015p:plain f:id:Phaser_3:20190117140031g:plain

テキストの部分が浮かび上がっている様子がはっきりわかります。


今回のソースはこちらです。

/// <reference path="../app.ts" />

namespace MyGame {


    export class MyScene1 extends Phaser.Scene {

        constructor() {
            super({ key: 'MyScene1', active: false });
        }

        preload() {
            //ノーマルマップ
            this.load.image("rect", ["assets/images/rect3.png", "assets/images/rect2_normal.png"]);
        }

        create() {

            let rect = this.add.sprite(this.sys.canvas.width / 2, this.sys.canvas.height / 2,  "rect");

            //light2dのパイプライン
            rect.setPipeline("Light2D")

            //ライトを追加
            let light = this.lights.addLight(0, 0, 200);

            this.lights.enable().setAmbientColor(0x555555);

            this.input.on('pointermove', function (pointer) {
                light.x = pointer.x;
                light.y = pointer.y;
            });
        }
        update() {
        }
    }
}