概要
この記事では Godot Engine でマスクを実装する方法について解説します。
マスクとは
マスクとは、画像の特定部分を切り抜いて描画する方法です。
この GIF動画では、円形で画像をくり抜いて、その部分だけを描画するようにしています。
画像の準備
マスク用の画像
マスク用に使う画像は、くり抜きたい部分を完全な白色 (R,G,B)=(255,255,255)
にして、描画したくない部分は透過値を 0 に近づけます。
透過値のある画像を作るには、GIMPなどのグラフィックツールが必要です。
ひとまず素材として以下の画像を用意しました。
↑真っ白でわかりにくいですが、これを "mask.png" として保存します。
背景用の画像
背景には以下の画像を使用します。ファイル名は "bg.jpg" として保存します。
くり抜く対象の画像
くり抜く対象の画像は以下のものを使用します。 "ch.png" として保存します。
プロジェクト作成と背景・キャラの配置
2Dシーン (ノード名は "Main" ) を作成して、"bg.jpg" と "ch.png" を配置します。
キャラ画像が大きすぎた……ので、気になる場合は小さくしてもいいかもしれません。
Light2Dの配置
マスクをするために Light2D
を作成します。
どこに追加しても良いですが、ひとまず ch ノードの下に追加しておきます。
"mask.png" をプロジェクトに追加して、Light2D
のテクスチャに設定します。
マスクされる側のマテリアルを設定する
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
経由でマスクする必要がありそうです(未検証)