
Instant Mask は滑らかな階調のマスクです!
MeshRendererやSprite、UnityGUI、Particle等のイメージをマスク画像の形に切り取ったり、逆にその形に穴を空けたりします
アンチエイリアス、グラデーションなどの半透明を滑らかに表現します
アルファまたはグレイスケール画像によってマスクします
位置や回転、サイズ、マスク適用度などの各調整が可能です
3つまでのマスクを一つの画像に同時に適用できます
マスクされた画像を動的に生成、あるいは画像ファイルとして書き出すこともできます
余分な負荷を増やさず、BatchesとSetPass(DrawCalls)はオブジェクトごとに常に1です
用途に応じた3つのスクリプトをGameObjectにAddして使用します。
- InstantTextureMask
- InstantShaderMask
- InstantParticleMask
これらはアセットのScriptフォルダ内に入っています。
ここでは3つのスクリプトに共通した使い方の説明をしますので、各スクリプトの詳細な使い方はこのページ左部のメニューから各項目を選択してそちらを参照してください。
Inspectorウインドウでの各項目設定名はそのまま変数名になっています。
(大文字小文字はそのままで空白スペースを埋めた文字列)
例えばMaskの角度(MaskAngle)をスクリプトから変えたい場合
GetGomponent<InstantShaderMask>().MaskAngle += 2.0f;
とUpdate()内で変更させれば2度づつ回転します。
アセットのデモで使用しているIMaskDemoManager.csを参考にしてください。
あるいはAnimationウインドウのタイムラインで変化させてもかまいません。
WrapMode や SelectMaterial で使われているドロップダウンリストは内部的にはint型なので、スクリプトから変更する場合はリストの上から順に0からの整数を指定すれば変更できます
GetGomponent<InstantShaderMask>().BaseImageWrapMode = 1;
これでベースとなる画像のWrapModeはClampになります
ShaderおよびParticleを使用している際、描画のカリングを選択することができます。
裏面を描画したりSpriteのFlipを使用する場合はNoneにする必要があります。裏面を描画する必要がない場合はカリングをBackに設定しておくと無駄な処理をせずゲームの動作を軽くすることができます。
InstantMaskShaderのInspectorウインドウから設定できます。
ShaderおよびParticleを使用していて3DのGameObjectのテクスチャにマスクをかける際、マスクした穴からそのモデル自身の内面が見えるようにしたい場合のために2passShaderも含まれています。
これを使用するには、通常のInstantMaskShaderを2passShaderに差し替えるだけです。
設定値の変更をあまり頻繁に行わない一枚画像用途で使用します。
Unityの仕様として、画像は'Read/Write Enabled'をONにしないと処理に使用することができないので必ずONにしてください。
(画像を選択しInspectorウインドウで行う設定です。Advanced折りたたみメニューの中にあります。Unity5.5未満ではTexture TypeをAdvancedにする必要があります。)
InstantTextureMask のサイズや位置の変更はPixel単位、サイズや位置や回転のPivotはマスク画像の中心、マスク位置の座標原点(x:0,y:0)はベースの画像の左下です。
以下は設定の各項目について見ていきます。
マスクした画像を動的に作り、その結果画像はここに生成されます。
Texture2D MaskedTex = GetComponent<InstantTextureMask>().Result;
例えばこのようにしてマスクした画像を使用します。
Result画像の大きさを設定します。
マスクした結果の画像の不透明度を調節します。
Result画像のWrapModeを変更します。Unity2017以降ではU軸(横方向)とV軸(縦方向)をそれぞれ別に設定することができます。
マスクをする元の画像。
マスク処理に使用する画像。
この画像のアルファかグレイスケールを使って、BaseImageを切り取ったり穴を空けたりします。
マスク処理を行うかどうか。
これをOffにすれば瞬時にBaseImageの画像をそのまま表示する状態になります。
マスクの位置とサイズを変更します。 Pivotはマスク画像の中心、位置原点(x:0,y:0)はBaseImageの左下です。
マスクの適用度を調節します。
0でマスク処理をしていない場合と同じ表示になります。
マスクの回転を行うかどうかです。
重めの処理なので、回転する必要がない場合はこれをOffにしておくとよいでしょう。
マスクを回転させる角度です。
Pivotはマスク画像の中心です。
UnityGUIのImage, RawImageコンポーネントを使用して画像を表示する場合には、ここをチェックすることで自動で画像をImage, RawImageコンポーネントに適用することができます。
この場合、以下の2つの項目が追加されます。
これをOnにするとMaskImageに使用している画像をシーンにプレビューします。
上のMaskVisibilityがOnの時、シーンにプレビューされているMaskImageが見やすいように色を変えることができます。
これがWhite(255,255,255,255)だと元のMaskImageの画像の色となります。それとは反対にMaskImageに使用する画像をWhiteで描いておけば自由な色でシーン上に表示することができます。
マスクの形に切り抜くか、穴を空けるかを切り替えます。
これがOffの場合はMaskImageのアルファを利用してマスクします。
これがOnの場合はMaskImageの明度を利用してマスクします。
モザイクのような処理をします。
オマケのようなものなので精度はあまりよくありません。
ResultSizeをBaseImageの元画像のサイズと同値にします。
プログラム内でメソッドを実行することで同様の処理を行う事も出来ます。
GetComponent<InstantTextureMask>().BaseImageSetNatriveSize();
MaseRectのw,hをMaskImageの元画像のサイズと同値にします。
プログラム内でメソッドを実行することで同様の処理を行う事も出来ます。
GetComponent<InstantTextureMask>().MaskImageSetNatriveSize();
マスクした結果画像をファイルとして書き出します。
ProjectウインドウにおけるInstantMask/ExportImages内に、年月日時分秒+4桁のナンバーという数字ファイル名で生成されます。
シェーダーを使って各RendererやGUIのテクスチャをマスクします。
マスク部分を頻繁に移動や回転させるような場合に使用します。
InstantShaderMask のマスクサイズの変更はUnityのシェーダーの設定に準拠しており、Tilingで行います。TilingのPivotはデフォルトでは画像の左下です。
回転のPivotはマスク画像の中心です。
InstantShaderMaskを設置したGameObjectが持つRendererやUnityGUIのImage, RawImageコンポーネントに、InstantMaskShader.shaderを当てたマテリアルをアサインしてください。このマテリアルを通してマスクした結果の画像を描画します。
* Unityの仕様に伴う細かい注意点 *
InstantMaskShader.shaderはUnity準拠のUI用シェーダーにプロパティを付け加えたものです。 (UI-Default.shader)
あなたのお好みのシェーダーを使ってマスクしたい場合には、その別のシェーダースクリプトにInstantMaskのプロパティが適用できるようにあなた自身が書き加える必要があります。
プログラムからシェーダーを適切に書き変えるようなことはできないため、ユーザー側で手動で行ってもらうしかないためです。
そのようなシェーダーを作成した場合はそれを当てたマテリアルをRenderer等にアサインして下さい。
* Unityの仕様に伴う細かい注意点2 *
Unity自体の仕様におけるマテリアルの挙動の話ですが、ビルドしたゲームやEditorでのシーンPlay時には、Rendererで同一のマテリアルが共有されていても自動的にInstanceが作られ、各々のGameObjectで個別のレンダリングが行われます。
この場合はいいのですが、Edit時(シーンPlayしていない状態)にはInstanceが作られない仕様のため同じマテリアルを共有しているGameObjectには一斉にマテリアルへの変更が適用されてしまいます。
そのため同じマテリアルを共有する複数のGameObjectの個別のMask状態を見たい場合、シーンPlayして確認する必要があります。
また、UnityGUIのImaeg, RawImageコンポーネントにおいてはUnityはマテリアルのInstanceを作らないので、ビルドしたゲームやEditorでのシーンPlay時であっても、同じマテリアルは全て同一の描画結果になることに注意が必要です。
これらの挙動に対して、もしこのアセットがマテリアルを複製等して解決してしまうと他のアセットなどからマテリアルを参照している場合に挙動の食い違いによるエラー等が懸念されるため、Unity標準の挙動のままにしています。
各GameObjectに全て個別のマテリアルを使用している場合にはこの問題はありません。
以下は設定の各項目について見ていきます。
Renderer等に複数のマテリアルが設定できるときに、マスク操作をするマテリアルを選びます。
Renderer等にアサインされたマテリアルの一覧が出るので、InstantMaskShader.shaderを当てたマテリアルを指定して下さい。
マスクした結果の画像の不透明度を調節します。
マスクした結果の画像から、指定値の割合以下の不透明度の部分を非表示にします。
1で不透明な部分まで完全に非表示になります。
マスクをする元の画像。
SpriteRendererやUnityGUIのImageコンポーネントのようなSpriteしか扱えない表示先の場合はBaseSpriteという項目名になり、Sprite画像しかアタッチできなくなります。
BaseImage/BaseSpriteのサイズ(繰り返し数)を変更します。
Unityのシェーダーの設定におけるTilingと同じです。
BaseImage/BaseSpriteの位置を変更します。
Unityのシェーダーの設定におけるOffsetと同じです。
BaseImageのWrapModeを変更します。
* Unityの仕様に伴う細かい注意点 *
WrapModeは元となる画像の設定として行うもののため、Edit時(シーンPlayしていない状態)ではこのアセットからは変更できないようになっています。
Edit時は元の画像の設定から通常の方法でWrapModeの変更を行って下さい。
ビルドしたゲーム内やシーンPlay中にはこのアセットからWrapModeを変更する事ができます。
ただし、先述の通りWrapModeは元の画像の設定なので、同じ画像を使用しているGameObject全てが一斉にWrapModeの変更を受けることに注意して下さい。
Unity2017以降ではU軸(横方向)とV軸(縦方向)をそれぞれ別に設定することができます。
これをOnにするとMaskImageに使用している画像をシーンにプレビューします。 ただしシェーダーを通しての表示のため、InstantTextureMaskと違って描画範囲内にない部分は表示されません。
上のMaskVisibilityがOnの時、どのマスク画像をシーンにプレビューするか選択します。
上のMaskVisibilityがOnの時、シーンにプレビューされているMaskImageが見やすいように色を変えることができます。
これがWhite(255,255,255,255)だと元のMaskImageの画像の色となります。それとは反対にMaskImageに使用する画像をWhiteで描いておけば自由な色でシーン上に表示することができます。
* InstantMaskShaderにおいてはマスクを3つまで適用することができます。
以下は便宜上Mask1の場合の項目名(変数名)で説明しています。
マスク処理に使用する画像。
この画像のアルファかグレイスケールを使って、BaseImageを切り取ったり穴を空けたりします。
マスク処理を行うかどうか。
これをOffにすれば瞬時にマスクを適用していない状態になります。
MaskImageのサイズ(繰り返し数)を変更します。
Unityのシェーダーの設定におけるTilingと同じです。
スプライトアニメーションをマスクする場合は、スプライトを整頓されたグリッド状にスライスし、マスク画像のWrapModeをRepeatにしてこの数値をスプライトのグリッドと同じ分割になるように設定することで、アニメーションを通して同じ形でマスクすることができます。
Tilingは通常は画像の左下が起点になっていますが、これを画像の中央を起点にTilingするようにします。マスク位置を動かさずサイズを変更をしたい場合などに便利です。
MaskImageの位置を変更します。
Unityのシェーダーの設定におけるOffsetと同じです。
マスクの適用度を調節します。
0でマスク処理をしていない場合と同じ表示になります。
MaskImageの位置をTilingやAngleにおけるPivotごと変更します。Offsetとの違いがやや分かりづらいですが、例えばマスクが回転しながら移動するような挙動を作るとOffsetでの動きは惑星の公転のような挙動になるのに対しこちらは自転のような動きを楽に作ることができます。
マスクを回転させる角度です。
デフォルトのPivotはマスク画像の中心です。
マスクの処理の仕方を変えることができます。マスクはMask1から順に適用されます。そのため、Mask1においてはマスク部分を隠す挙動(Hide)以外のモードが必要となることはないため、Mask1にはMask1Prescribeというこの項目(および変数)自体がありません。また、Masek2,Mask3もそれ以前のマスクがなければこの項目を使うことはできません。他のマスクによってすでに隠された部分がなければ、隠す挙動(Hide)以外のモードが必要となることはないためです。
- Hide
マスク範囲を隠して見えなくする一般的なマスクの挙動です。
- Add Visible Part
このマスクだけをベース画像に適用した画像を作り、その表示部分をここまでの結果に重ねるような挙動です。例えば、デモのシーンにおけるShaderの例では大きな星形の穴を作り、その中に小さな星型の切り抜きを作って別々の動きをさせていますが、これは本来ならば一枚の画像へのマスクでは不可能です。大きな星のマスク部分によって小さな星は隠され、小さな星のマスク部分によって大きな星の枠は隠されるからです(デモのこの項目のモードをHideにしてみれば判るでしょう)。デモではMask2をAddVisiblePartにすることで大きな星形の穴を空けたあとに小さな星型の切り抜きの表示部分を重ねるような挙動になっているため、この表示が可能になっています。
- Invert
マスク部分のアルファ値を反転させます。
ここまでの画像での表示部分は隠され、他のマスクで隠されていた部分は表示されます。
マスクの形に切り抜くか、穴を空けるかを切り替えます。
これがOffの場合はMaskImageのアルファを利用してマスクします。
これがOnの場合はMaskImageの明度を利用してマスクします。
基本的な構造は前の項のInstantShaderMaskと同じですが、パーティクルでのテクスチャおよびテクスチャシートアニメーションをマスクします。
InstantParticleMask のマスクサイズの変更はUnityのシェーダーの設定に準拠しており、Tilingで行います。TilingのPivotはデフォルトでは画像の左下です。
回転のPivotはマスク画像の中心です。
InstantParticleMaskを設置したGameObjectが持つParticle(Syuriken)のRendererに、InstantMaskShader.shaderを当てたマテリアルをアサインしてください。このマテリアルを通してマスクした結果の画像を描画します。
* Unityの仕様に伴う細かい注意点 *
InstantMaskShader.shaderはUnity準拠のUI用シェーダーにプロパティを付け加えたものです。 (UI-Default.shader)
あなたのお好みのシェーダーを使ってマスクしたい場合には、その別のシェーダースクリプトにInstantMaskのプロパティが適用できるようにあなた自身が書き加える必要があります。
プログラムからシェーダーを適切に書き変えるようなことはできないため、ユーザー側で手動で行ってもらうしかないためです。
そのようなシェーダーを作成した場合はそれを当てたマテリアルをRendererにアサインして下さい。
* Unityの仕様に伴う細かい注意点2 *
Unity自体の仕様におけるマテリアルの挙動の話ですが、ビルドしたゲームやEditorでのシーンPlay時には、Rendererで同一のマテリアルが共有されていても自動的にInstanceが作られ、各々のGameObjectで個別のレンダリングが行われます。
この場合はいいのですが、Edit時(シーンPlayしていない状態)にはInstanceが作られない仕様のため同じマテリアルを共有しているGameObjectには一斉にマテリアルへの変更が適用されてしまいます。
そのため同じマテリアルを共有する複数のGameObjectの個別のMask状態を見たい場合、シーンPlayして確認する必要があります。
この挙動に対して、もしこのアセットがマテリアルを複製等して解決してしまうと他のアセットなどからマテリアルを参照している場合に挙動の食い違いによるエラー等が懸念されるため、Unity標準の挙動のままにしています。
各GameObjectに全て個別のマテリアルを使用している場合にはこの問題ありません。
以下は設定の各項目について見ていきます。
InstantParticleMask上部にはParticleのRendererにアサインされているマテリアル名が表示されます。これは先述の通りInstantMaskShader.shaderを当てたマテリアルである必要があります。
マスクした結果の画像の不透明度を調節します。
指定値の割合以下の不透明度の部分を非表示にします。
1で不透明な部分まで完全に非表示になります。
マスクをする元の画像。
BaseImageのサイズ(繰り返し数)を変更します。
Unityのシェーダーの設定におけるTilingと同じです。
BaseImageの位置を変更します。
Unityのシェーダーの設定におけるOffsetと同じです。
BaseImageのWrapModeを変更します。
* Unityの仕様に伴う細かい注意点 *
WrapModeは元となる画像の設定として行うもののため、Edit時(シーンPlayしていない状態)ではこのアセットからは変更できないようになっています。
Edit時は元の画像の設定から通常の方法でWrapModeの変更を行って下さい。
ビルドしたゲーム内やシーンPlay中にはこのアセットからWrapModeを変更する事ができます。
ただし、先述の通りWrapModeは元の画像の設定なので、同じ画像を使用しているGameObject全てが一斉にWrapModeの変更を受けることに注意して下さい。
Unity2017以降ではU軸(横方向)とV軸(縦方向)をそれぞれ別に設定することができます。
これをOnにするとMaskImageに使用している画像をシーンにプレビューします。 ただしシェーダーを通しての表示のため、InstantTextureMaskと違って描画範囲内にない部分は表示されません。
上のMaskVisibilityがOnの時、どのマスク画像をシーンにプレビューするか選択します。
上のMaskVisibilityがOnの時、シーンにプレビューされているMaskImageが見やすいように色を変えることができます。
これがWhite(255,255,255,255)だと元のMaskImageの画像の色となります。それとは反対にMaskImageに使用する画像をWhiteで描いておけば自由な色でシーン上に表示することができます。
* InstantMaskShaderにおいてはマスクを3つまで適用することができます。
以下は便宜上Mask1の場合の項目名(変数名)で説明しています。
マスク処理に使用する画像。
この画像のアルファかグレイスケールを使って、BaseImageを切り取ったり穴を空けたりします。
マスク処理を行うかどうか。
これをOffにすれば瞬時にBaseImageの画像をそのまま表示する状態になります。
MaskImageのサイズ(繰り返し数)を変更します。
Unityのシェーダーの設定におけるTilingと同じです。
パーティクルのテクスチャシートアニメーションを行う場合は、マスク画像のWrapModeをRepeatにしてこの数値を同じ区切りになるように設定することで、アニメーションを通して同じ形でマスクすることができます。
Tilingは通常は画像の左下が起点になっていますが、これを画像の中央を起点にTilingするようにします。マスク位置を動かさずサイズを変更をしたい場合などに便利です。
MaskImageの位置を変更します。
Unityのシェーダーの設定におけるOffsetと同じです。
マスクの適用度を調節します。
0でマスク処理をしていない場合と同じ表示になります。
MaskImageの位置をTilingやAngleにおけるPivotごと変更します。Offsetとの違いがやや分かりづらいですが、例えばマスクが回転しながら移動するような挙動を作るとOffsetでの動きは惑星の公転のような挙動になるのに対しこちらは自転のような動きを楽に作ることができます。
マスクを回転させる角度です。
デフォルトのPivotはマスク画像の中心です。
マスクの処理の仕方を変えることができます。マスクはMask1から順に適用されます。そのため、Mask1においてはマスク部分を隠す挙動(Hide)以外のモードが必要となることはないため、Mask1にはMask1Prescribeというこの項目(および変数)自体がありません。また、Masek2,Mask3もそれ以前のマスクがなければこの項目を使うことはできません。他のマスクによってすでに隠された部分がなければ、隠す挙動(Hide)以外のモードが必要となることはないためです。
- Hide
マスク範囲を隠して見えなくする一般的なマスクの挙動です。
- Add Visible Part
このマスクだけをベース画像に適用した画像を作り、その表示部分をここまでの結果に重ねるような挙動です。例えば、デモのシーンにおけるShaderの例では大きな星形の穴を作り、その中に小さな星型の切り抜きを作って別々の動きをさせていますが、これは本来ならば一枚の画像へのマスクでは不可能です。大きな星のマスク部分によって小さな星は隠され、小さな星のマスク部分によって大きな星の枠は隠されるからです(デモのこの項目のモードをHideにしてみれば判るでしょう)。デモではMask2をAddVisiblePartにすることで大きな星形の穴を空けたあとに小さな星型の切り抜きの表示部分を重ねるような挙動になっているため、この表示が可能になっています。
- Invert
マスク部分のアルファ値を反転させます。
ここまでの画像での表示部分は隠され、他のマスクで隠されていた部分は表示されます。
マスクの形に切り抜くか、穴を空けるかを切り替えます。
これがOffの場合はMaskImageのアルファを利用してマスクします。
これがOnの場合はMaskImageの明度を利用してマスクします。