おもちゃラボ

Unityで遊びを作ってます

【Unityシェーダ】テクスチャを円形にトランジションさせる

uGUIのImageを使うと、画像のトランジションを簡単に実現することができます。この記事では円形のトランジションを通常のテクスチャやスプライトでも行えるようなシェーダを作ります。

円に沿って表示する方法

テクスチャの一部を表示するにはdissolveシェーダでやったのと同じ方法を使います。

nn-hokuson.hatenablog.com

dissolveシェーダではグレースケールのノイズ画像を用意し、しきい値を超えているところは描画、しきい値以下の部分はdiscardします。そのしきい値を変えることで徐々に消えていく動きを実現しました。

f:id:nn_hokuson:20190702184349j:plain:w400

今回はノイズ画像ではなく、次のようなグレースケールの画像を用意します。この画像は0度のところが黒色で時計回りに明るくなり、360度のところで白色になります。
f:id:nn_hokuson:20190702184430p:plain:w300
この画像をしきい値で二値化します。例えば、明度が0.1未満の部分は白、明度が0.1以上の部分は黒色とすると次のような画像になります。
f:id:nn_hokuson:20190702184438p:plain:w350
このしきい値を徐々に変化させて行くことで、扇状に白色の部分が増えていきます。
f:id:nn_hokuson:20190702184820p:plain:w550
作成した画像をマスクとして使います。マスクの白色部分はテクスチャを表示し、黒色部分のピクセルは破棄することでuGUIのように環状にテクスチャを表示できるようになります。
f:id:nn_hokuson:20190702185555p:plain:w550

円形切り取りシェーダ

それでは円形トランジションシェーダを作っていきましょう。プロジェクトウィンドウで右クリックして「Create」→「Shader」→「Unlit Shader」を選択し、ファイル名を「RadialFIll」にします。

また、作成したシェーダを右クリックして「Create」→「Material」を選択し、シェーダをアタッチしたマテリアルを作成します。
f:id:nn_hokuson:20190702184640p:plain:w200
ファイルが作成できたら、次のプログラムを入力してください。

Shader "Unlit/RadialFIll"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Threshold ("Threshold", Range(0,1)) = 0
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float _Threshold;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {                
                fixed4 col = tex2D(_MainTex, i.uv);

                // 平面上の角度を求める
                fixed2 uv = 0.5 - i.uv;
                float rad = atan2(uv.y, uv.x);                
                
                // -π〜πを0〜1の値に変換する
                float value = (rad + 3.14)/(2 * 3.14);

                // しきい値以下なら表示しない
                if ( value < _Threshold ) discard;

                return value;
            }
            ENDCG
        }
    }
}

主にフラグメントシェーダのプログラムを修正しています。まずはテクスチャの中心を原点にするためにuv座標を0.5引いています。これによりuv座標は-0.5から0.5の値で変化します。

f:id:nn_hokuson:20190702184711p:plain:w400

次に平面上の座標から角度を求め、その角度にしたがって明度を0〜1に設定します。平面上の角度はatan2関数によって求められます。atan2は-π〜πの範囲の値を返すため、これを明度になおすため、0〜1にスケールします

次にスケールした値がしきい値よりも大きい場合には描画、小さい場合にはdiscardしています。しきい値はインスペクタから入力できるようにPropertiesブロックの中で_Threshold変数を記述しています。またvertexシェーダの上でも宣言するのを忘れないようにしてください。

スタート位置や回転方向を変える

uGUIのFillを使えば、どこから表示をスタートするのか(Top, Bottom, Left, Right)を選択することができます。これを実現するにはatan2に指定するuv座標を次のように設定します。

スタートの角度 指定方法
0度(右) atan2(uv.y, uv.x)
90度(上) atan2(-uv.x, uv.y)
180度(左) atan2(-uv.y, -uv.x)
270度(下) atan2(uv.x, -uv.y)

f:id:nn_hokuson:20190702184735g:plain

また、時計周りで表示させたい場合はatan2の第一引数の正負をひっくり返すだけです。具体的には次のように指定してください。

0度(右) atan2(-uv.y, uv.x)
90度(上) atan2(uv.x, uv.y)
180度(左) atan2(uv.y, -uv.x)
270度(下) atan2(-uv.x, -uv.y)

実行結果

シェーダプログラムができたら保存して、マテリアルを平面オブジェクトにアタッチしてください。インスペクタからThresholdのスライダを動かすと、それに合わせてテクスチャが円形にトランジションします。
f:id:nn_hokuson:20190702185903j:plain:w500

【ARKit】3Dオブジェクトをマーカーにする

ARKit2.0からは2次元の画像マーカーだけでなく、3次元の物体(例えばぬいぐるみだったり、玩具だったり)をマーカーにすることが出来るようになりました。ただ、現状ではオブジェクトトラッキングはできないため、3Dマーカーは動かないことが前提の使い方になります。

f:id:nn_hokuson:20190625191641j:plain

物体をマーカーにする流れ

  1. マーカーにしたい物体を360度撮影して、物体のもつ特徴点データを検出します。
  2. 作成した特徴点データをUnityにインポートし、ARReferenceObjectに登録します。
  3. 作成したAssetを、ARReferenceObjectsSetAssetに登録します。
  4. 作成したSetAssetをAR Config Optionsに登録します。

f:id:nn_hokuson:20190616223701j:plain:w500

このように書くと、ものすごく複雑そうに見えますが、やっていることは2次元マーカーを登録したときと同じことをしています。

nn-hokuson.hatenablog.com

一点違うのが❶の特徴点データを検出する部分です。ここはプログラマが手作業でやる必要があります。まずはその方法から見ていきましょう。

特徴点データを取り出す

3Dの特徴点データを取り出すには専用のアプリが用意されています。といっても、自分でビルドする必要があります(笑)

まずは次のサイトからARKit Scannerのプロジェクトをダウンロードしてください。

developer.apple.com

ダウンロードできたらビルドして、アプリを起動します。起動したらまずはマーカーにしたい物体を囲むように黄色い枠を広げます。枠のサイズはドラッグやピンチで変更できます。

f:id:nn_hokuson:20190616222022j:plain:w250

次に物体を360度(といっても底面はありませんが)から撮影します。うまく撮影できると、画面上のScanのパーセンテージが上昇し、ボックスの表面が黄色く変化します。

f:id:nn_hokuson:20190616222122j:plain:w250 f:id:nn_hokuson:20190616222416j:plain:w250

すべての面が撮影できたら「Share」ボタンを押して、特徴点データをPCに転送します(転送にはAirDropが便利!)。ファイル名は「Scan-xxxx.arobject」みたいになっていると思います。

f:id:nn_hokuson:20190616222529j:plain:w250

ここでは名前をyadon.arobjectに変更しておきました。

Unityに特徴点データをインポート

Unityのプロジェクトを作成し、ARKit Pluginをインポートしたら、Unity ARKit Sceneを開いてください。詳しい方法は次の記事で紹介しています。

nn-hokuson.hatenablog.com

先程転送した、特徴点データをプロジェクトウィンドウにドラッグ&ドロップして追加しておきます。

f:id:nn_hokuson:20190621222854j:plain

ARReferenceObjectAssetを作成する

追加できたらプロジェクトウインドウで右クリックして、「Create」→「UnityARKitPlugin」→「ARReferenceObjectAsset」 を選択します。

f:id:nn_hokuson:20190621222949p:plain:w400

作成したARReferenceObjectAssetのファイル名は「yadonObject」にしました。

f:id:nn_hokuson:20190621223045p:plain:w300

続いて今作成したyadonObjectに3Dモデルの特徴点情報を登録します。インスペクタのReference Object欄に特徴点データ「yadon.arobject」をドラッグ&ドロップします。また、Object Nameはyadonにしておきます。

f:id:nn_hokuson:20190621223304j:plain:w600

ARReferenceObjectsSetAssetに追加する

作成したARReferenceObjectAssetをARReferenceObjectsSetAssetに登録します。名前が似ていてややこしいですね。。ARReferenceObjectAssetは本、ARReferenceObjectsSetAssetはARReferenceObjectAssetを収める本棚とイメージすると理解しやすいかもしれません。

ARReferenceObjectAsset
ARReferenceObjectsSetAsset 本棚

プロジェクトウインドウで右クリックして、「Create」→「UnityARKitPlugin」→「ARReferenceObjectsSetAsset」 を選択してください。

f:id:nn_hokuson:20190621223420p:plain:w400

作成したARReferenceObjectsSetAssetのファイル名はObjectsSetにしました。

f:id:nn_hokuson:20190621223456p:plain:w300

いま作成したObjectsSetのインスペクタに上で作成したyadonObjectを登録します。Resource Group Nameはtest、Reference Object AssetsのSizeを「1」にして、Element 0の欄にyadonObjectをドラッグ&ドロップします。

f:id:nn_hokuson:20190621223707j:plain

このReference Object Assetsに登録したObjectAssetが立体マーカーとして検出される対象になります。

ARReferenceObjectsSetAssetを登録する

上のステップで作成したARReferenceObjectsSetAssetをシステムに登録します。ヒエラルキーウインドウでARCameraManagerを選択します。インスペクタのUnityARCameraManagerのObject Trackingの項目を見てください。Detection Objectの欄に先程のObjectsSetをドラッグ&ドロップします。

f:id:nn_hokuson:20190621223945j:plain

これでオブジェクトトラッキングが行われるようになります。ただ、このままではARマーカーを見つけても何も起こりません。マーカーを見つけたときには3Dモデルを表示するようにしましょう。

画像と表示するモデルを関連づける

ARマーカーを映したときに、マーカー上に表示する3Dモデルを決めます。今回は「やぁん」の3Dモデルをを使用しています(以降のスクショと少し齟齬があります・・・)

f:id:nn_hokuson:20190625190902j:plain:w500

ヒエラルキーウインドウで「Create」→「Create Empty」で空のゲームオブジェクトを作ります。次に作成したオブジェクトを選択した状態で「Add Component」→「Generate Object Anchor」スクリプトをアタッチします。

スクリプトのReferenceObjectに「yadonObject」、Prefab To Generateに生成したいPrefabをそれぞれドラッグ&ドロップしてください。

f:id:nn_hokuson:20190621224225j:plain

ターゲットの画像マーカーが見つかった場合は、Generate Object Anchorスクリプトの中のAddObjectAnchorが呼び出されます。また、画像マーカーの位置が更新された場合にはUpdateObjectAnchorが呼び出されます。

RemoveObjectAnchorもありますが、これは画像マーカーが画面外に出たときに呼び出されるわけではありません。明示的に次のスクリプトでAnchorを破棄したときにのみ呼び出されます。

UnityARSessionNativeInterface.GetARSessionNativeInterface().RemoveUserAnchor( arImageAnchor.identifire );

オブジェクトトラッキングの確認

これでUnityとARKitを使って画像トラッキングを行う準備は完了です。実際にビルドして正しく動くか確認してみてください。

正しく設定できていれば、ARマーカーを映すと指定した3Dモデルが表示されます。

【Blender】金平糖を作る

Blenderで金平糖みたいなツノツノのモデルを簡単に作る方法を紹介します。ここではBlender2.80を使って作っていきますが、Blender2.7xでもほとんど同じ操作で可能です。

f:id:nn_hokuson:20190621203515j:plain:w650

金平糖の素を作る

まずは金平糖のもとになる球を作成します。Alt-Aで表示される追加オプションから「メッシュ>ICO球」を選択します。
f:id:nn_hokuson:20190621202238j:plain:w400

ICO球のメッシュをもう少し細かく設定します。左下のメニューから細分化を「4」に設定してください。
f:id:nn_hokuson:20190621202431j:plain:w600

金平糖の角を作る

次に金平糖の角を作っていきます。ICO球上にある頂点をランダムに選択してください。選択する頂点数は下図を参考にしてみてください。
f:id:nn_hokuson:20190621202630j:plain:w600

次にプロポーショナル編集を「有効」にして、減衰タイプを「スムーズ」にします。プロポーショナル編集を有効にることで、選択した頂点だけでなく、その周囲の頂点も連動して動くようになります。
f:id:nn_hokuson:20190621202955j:plain:w600

それでは頂点を押し出しましょう。まずは「Eキー」を押して押し出しモードにします。次に「Alt+S」をクリックして押し出し方向を法線方向にして、マウスを移動させると次のように角を押し出すことができます。押し出している最中にマウスホイールを回すことでプロポーショナル編集の影響範囲を調整できます。
f:id:nn_hokuson:20190621203207g:plain

金平糖を滑らかにする

最後に金平糖モデルの上で右クリックして「スムース面」を選択することで、スムースシェーディングが適用され、滑らかな見た目に変更できます。
f:id:nn_hokuson:20190621203407j:plain:w600

好きな色をつければ、金平糖が完成!
f:id:nn_hokuson:20190621203515j:plain:w600

金平糖をお買い求めの方はこちら

あ、Blenderともモデリングとも関係ありませんが、
京都に来られた際はぜひ「緑寿庵清水」で金平糖を買ってみてください(笑)
日本で唯一の金平糖専門店です。
出町柳をちょっと下がった所にあります。
www.konpeito.co.jp
macaro-ni.jp