Phaser3 カメラエフェクト

phaser

Phaser3 カメラエフェクト

前回の記事
https://mijinc0.github.io/blog/post/20200821_phaser3_tilemap/

カメラエフェクトをかける方法

Phaser3ではカメラ用の標準的なエフェクトがいくつか用意されている。

逆に言うと、これら以外は基本的にない(はず)。

例えば、画面全体をグレースケールにするだとか、色味の調整だとか、そういったものが無い。また、雨の演出を入れたいだとか、海中で画面が揺らぐ演出を入れたいだとか、色々とこだわりを出していくと足りないものが増えてくる。

Phaser3でカメラにエフェクトをかけたいとき、主に2つの方法が考えられる

  1. カメラの描写範囲に追随するオブジェクトをシーンに追加する
  2. シェーダ―を使う

1. カメラの描写範囲に追随するオブジェクトをシーンに追加する

カメラの描写範囲に追随するオブジェクトをシーンに追加すれば、ゲームをプレイしている人にとっては画面全体にエフェクトがかかっているように見える。

オブジェクトをカメラに追随させるには、setScrollFactorを使えば良い。

// this === Scene
const camera = this.cameras.main;

const worldView = camera.worldView;

const color = 0x110833;
const alpha = 0.5;

const rectangle = scene.add.rectangle(
  worldView.x,
  worldView.y,
  worldView.width,
  worldView.height,
  color,
  alpha,
);

rectangle.setOrigin(0);
rectangle.setScrollFactor(1);

上記の例だと、半透明のフィルターがカメラにかかっている状態になる。

注意: worldViewについて

camera.worldViewはその時カメラが描写している範囲を取得することが出来る便利なプロパティ。色々とお世話になることがあると思う。

しかし、このworldViewはシーンがupdateされる度に更新され、初期値は{x: 0, y: 0, widht: 0, height: 0}になっている。これがどういうことかというと、シーンのcreate関数内でworldViewを取得すると、常に初期値が返ってきてしまうため、期待した動きをしないことがある。これを避けるには、create内ではその処理を行わないか、自分で描写されるであろう範囲を判断して値を扱わなくてはいけない。

2. シェーダ―を使う

シェーダー、特にフラグメントシェーダ―を使ってカメラにエフェクトをかける方法。これはレンダラーにWebGLを使っていときのみ有効な手段で、canvas2Dを使っているときには出来ない。

シェーダーの説明自体は他の記事で書いているのでそちらを参照してください。

https://mijinc0.github.io/blog/post/20200811_about_shader/

以下のようにして使う。

const fragShader = `
  GLSLシェーダーのコード
`;

// this === Scene
var config = {
    game: this.game,
    renderer: this.game.renderer,
    fragShader: fragShader
};

var pipelineInstance = new Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline(config);

// エフェクトの登録
scene.game.renderer.addPipeline('pipelineName', pipelineInstance);

// エフェクトをカメラにセット
const camera = this.cameras.main;

// どちらかの方法で良い
camera.setRenderToTexture(pipelineInstance); // インスタンスを直接渡す
camera.setRenderToTexture('pipelineName'); // 登録時のキーで指定

上記の他に、TextureTintPipelineを継承したカスタムパイプラインクラスを用意して、そのインスタンスを使う方法もある。カスタムパイプラインクラスは、その中に、GLGL内のuniform変数をセットする関数などを用意することで、普通のオブジェクトの操作をしているような感覚でシェーダーの変数を操作できるようになるなどの利点がある。

参考

GLSLの勉強など
https://wgld.org/d/webgl/
https://qiita.com/doxas/items/b8221e92a2bfdc6fc211
https://qiita.com/doxas/items/5a7b6dedff4bc2ce1586
https://thebookofshaders.com/