【Godot】マスクの実装方法

この記事では Godot Engine でマスクを実装する方法について解説します。

マスクとは

マスクとは、画像の特定部分を切り抜いて描画する方法です。

この GIF動画では、円形で画像をくり抜いて、その部分だけを描画するようにしています。

画像の準備

マスク用の画像

マスク用に使う画像は、くり抜きたい部分を完全な白色 (R,G,B)=(255,255,255) にして、描画したくない部分は透過値を 0 に近づけます。

透過値のある画像を作るには、GIMPなどのグラフィックツールが必要です。

今回使用する素材一式を用意しました

素材の説明

mask.png: マスクする丸の画像

mask2.png: マスクする丸の画像(ふちがぼやけている)

bg.jpg: 背景用画像
ch.png: 前面に表示する画像

プロジェクト作成と背景・キャラの配置

2Dシーン (ノード名は “Main” ) を作成して、”bg.jpg” と “ch.png” を配置します。

キャラ画像が大きすぎた……ので、気になる場合は小さくしてもいいかもしれません。

Light2Dの配置

マスクをするために Light2D を作成します。

どこに追加しても良いですが、ひとまず ch ノードの下に追加しておきます。

“mask.png” をプロジェクトに追加して、Light2D のテクスチャに設定します。

さらに Light2D の Modeを 「Mix」にします

マスクされる側のマテリアルを設定する

chノード(Sprite)を選択して、インスペクタから CanvasItem > Material > Material > [空]をクリックして、「新規 CanvasItemMaterial」を選択します。

表示された CanvasItemMaterialをクリックして、LightMode > Light Onlyを選びます

するとこのようにマスクがかかります。

マスクをスクリプトで制御する

Main(2Dシーン)のスクリプトをアタッチして以下のように記述します。

extends Node2D

onready var light = $ch/Light2D

func _process(delta: float) -> void:
    # ライトの座標をマウスの座標に設定する
    light.position = get_viewport().get_mouse_position()

これで実行するとマウスの位置がくり抜かれる……はずなのですが、少しずれることがあります。”ch”ノードにぶら下げてしまったためで、”ch”ノードが原点に配置されていない場合はズレが発生します

なので、Light2D をMainノード直下に移動させます。

そしてスクリプトを修正します。

extends Node2D

onready var light = $Light2D # Mainノード直下に移動した

func _process(delta: float) -> void:
    # ライトの座標をマウスの座標に設定する
    light.position = get_viewport().get_mouse_position()

実行するとマウスの中心を基準にくり抜かれるようになりました。

フチをぼやけた画像に変えてみる

円のフチをぼやけた画像にすると、境界がぼやっとした感じになります。
“mask2.png” をプロジェクトに追加し、Light2D > Texture に割り当てます。

実行するとフチがぼやけた感じになりました!

補足

複数のマスクを同時に使いたい場合は、CanvasItem > Visibility > Light Mask の設定をマスクされる画像と Light2D で合わせると、特定の画像に特定のマスクを割り当てる……ということもできます。

※追記

Modeが Mix の場合は Light Mask の設定はうまく行かなさそうです。
複数のマスクを別々に適用したい場合には、以下の動画のように Light2Dの Mode を Mask に設定して、ViewportTexture経由でマスクする必要がありそうです(未検証)

参考