おもちゃラボ

Unityで遊びを作っていきます

Unityで始めるARKit入門 影の表示編

ARKitを使って影を表示する場合、足元に丸影を置くのが一番簡単です。ただ、見栄え的にはやはりちゃんとした影があったほうがリアルですね。そこで、ARで影を付ける方法を紹介します。

f:id:nn_hokuson:20181011215215j:plain

ARで影を表示する手順

ARKitを使って綺麗な影を付ける方法は、ほとんど丸影をつける方法と同じ手順で出来ます。

  1. 影を表示するための平面を作成
  2. モデルの子要素にする
  3. MobileARShadowシェーダを使用する

3つ目の手順だけが丸影とは異なります。丸影の場合はココに影のテクスチャをセットしますが、今回はリアルな影を表示したいので、UnityのARKit Pluginに用意されているMobileARShadowシェーダを使います。
 

影を表示する平面を作成

ヒエラルキーウインドウから「Create」→「3D Object」→ 「Plane」を選択して、適当な大きさに変形して、足元に配置します。

f:id:nn_hokuson:20181011215412j:plain:w500

影の平面を子要素にする

配置できたら影用の平面をモデルの子要素にします。ヒエラルキーウインドウで平面をモデルにドラッグ&ドロップしてください。

f:id:nn_hokuson:20181011215425p:plain:w270

MobileARShadowシェーダを使用する

配置した平面にMobileARShadowシェーダを適用します。「UnityARKitPlugin/Example/Common/Materials」の中の「ShadowPlane」マテリアルを、平面オブジェクトにドラッグ&ドロップしてください。

f:id:nn_hokuson:20181011215604j:plain:w500

エディタ上でも影だけが表示されているのがわかると思います。後はこのPrefabをARで表示すれば、自動的にモデルの形の影が表示されるようになります。

f:id:nn_hokuson:20181011215215j:plain:w500

ARでタップしたところにモデルを表示する方法は次の記事を参考にして下さい。

nn-hokuson.hatenablog.com

影だけを表示するシェーダの中身を見る

折角なので影を表示するシェーダの中身を見ておきましょう。シェーダは「UnityARKitPlugin/Example/Common/Shaders」の「MobileARShadow.shader」にあります。

Shader "Custom/MobileARShadow"
{
    SubShader {
        Pass {
            Tags { "LightMode" = "ForwardBase" "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True"  }
	    LOD 150
	    Blend Zero SrcColor
	    ZWrite On
        
            CGPROGRAM
 
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc" 
            #pragma multi_compile_fwdbase
            #include "AutoLight.cginc"
  
            struct v2f
            {
                float4 pos : SV_POSITION;
                LIGHTING_COORDS(0,1)
            };
  
            v2f vert(appdata_base v) {
                v2f o;
                o.pos = UnityObjectToClipPos (v.vertex);
                TRANSFER_VERTEX_TO_FRAGMENT(o);                 
                return o;
            }
 
            fixed4 frag(v2f i) : COLOR {
                float attenuation = LIGHT_ATTENUATION(i);
                return fixed4(1.0,1.0,1.0,1.0) * attenuation;
            }
 
            ENDCG
        }
    }
    Fallback "VertexLit"

}

このシェーダの中ではv2f構造体の中でLIGHTING_COORDSを使ってライトマップとシャドウマップ用のTEXCOORDを生成しています。フラグメントシェーダではLIGHT_ATTENUATIONを使って、先程適宜したライトマップとシャドウマップから光の減衰具合を調べています。これにより影のある場所だけが不透明になり、その他の部分は透明な画像になります。

Unityのシェーダに関しては次の記事も合わせてご覧ください。

nn-hokuson.hatenablog.com

SwiftでARKitを学習したい

SwiftでARKitを試したい場合は、ぜひ拙書の「ARKit超入門」を見ていただければと思います。
ただ、SceneKitでリアルな影を表示するのはUnityほど簡単じゃないかもです・・・(笑)
booth.pm