Oculus Rift Advent Calendar 2017の1日目の記事です!
ARKitでiPhoneXのFace Trackingを利用することができます。
Face Tracking with ARKit
Live2D Euclidと組み合わせると、こんなことが可能になります。
iPhoneX使ってLive2Dを動かしてみた。これ楽しすぎ! pic.twitter.com/RzWLiUKtQl
— のしぷ (@noshipu) 2017年11月9日
また、UnityのARKit Pluginから呼び出せるようになっていたので簡易的な解説をします。
実行環境
Unity 2017.1.2p1
Unity ARKit Plugin v1.0.12
https://assetstore.unity.com/packages/essentials/tutorial-projects/unity-arkit-plugin-92515
設定
- iOSにプラットフォーム切り替え
- Unity ARKit Pluginをインポート
- 設定ファイルを下記に変更
Assets/UnityARKitPlugin/Resources/UnityARKitPlugin/ARKitSettings.asset
シーンのセットアップ
Camera
ClearFlagをDepthOnlyに設定
UnityARVideo
YUV形式のカメラのテクスチャを取得、描画
ClearMaterialにYUVMaterialを設定する
UnityARCameraNearFar
Unityで設定しているClipping PlanesのNear/FarをNative側に伝える役割
ARCameraTracker
TrackedCameraにトラッキングさせたいカメラを指定
UnityARFaceMeshManager
MeshFilterに顔のMeshを反映させたいMeshを指定
また、このゲームオブジェクト自体が顔の位置をトラッキングする
これで下記のようなマスクマン的なことはできるようになります。
Unity ARKit Pluginを試してる。泥パックだ… pic.twitter.com/9wwCiVqoOF
— のしぷ (@noshipu) 2017年11月6日
その他のクラスについて
UnityARFaceAnchorManager
任意のオブジェクトをトラッキングさせる。顔の位置、回転がわかればいいならこちらでOK
BlendshapePrinter
Blendshape(表情のパラメータ)の値をOnGUIで出力するデバッグ用スクリプト
これを使用するとフレームレートが落ちるので注意
UnityARKitLightManager
Meshにリアル空間の環境光を反映できるスクリプト
サンプルシーンのFaceDirectionalLightEstimateで確認可能
顔検出のScriptを簡易解説
顔を検出する
1. usingする
using UnityEngine.XR.iOS;
2. FaceTracking開始、検出イベント登録
configの設定を行い、サポートしていればSessionを開始
その後、顔の検出時のイベントを登録
・顔の検出をされるとFaceAddedが呼ばれる
・検出した顔の情報が更新されるとFaceUpdatedが呼ばれる
・顔の検出がはずれるとFaceRemovedが呼ばれる
void Start() { UnityARSessionNativeInterface session = UnityARSessionNativeInterface.GetARSessionNativeInterface(); Application.targetFrameRate = 60; ARKitFaceTrackingConfiguration config = new ARKitFaceTrackingConfiguration(); config.alignment = UnityARAlignment.UnityARAlignmentGravity; config.enableLightEstimation = true; if (!config.IsSupported) { // 利用できない場合の処理はここで行う return; } session.RunWithConfig(config); // 顔の検出イベント登録 UnityARSessionNativeInterface.ARFaceAnchorAddedEvent += FaceAdded; UnityARSessionNativeInterface.ARFaceAnchorUpdatedEvent += FaceUpdated; UnityARSessionNativeInterface.ARFaceAnchorRemovedEvent += FaceRemoved; }
※ ちなみに検出可能な顔は1つで、体感ですが手前にある顔が優先されている感じです。
3. コールバック側で処理する
void FaceAdded (ARFaceAnchor anchorData) { // 検出された時の処理 } void FaceUpdated (ARFaceAnchor anchorData) { // 検出中の処理 } void FaceRemoved (ARFaceAnchor anchorData) { // 検出から外れた時の処理 }
基本的には、ARFaceAnchorで渡ってくるパラメータを使って、FaceMeshを作成したり、顔の位置やBlendshapeの値を取得することが可能です。
ARFaceAnchorを使ったサンプルコード
顔の位置、回転を取得する
void FaceUpdated (ARFaceAnchor anchorData)
{
gameObject.transform.localPosition = UnityARMatrixOps.GetPosition (anchorData.transform);
gameObject.transform.localRotation = UnityARMatrixOps.GetRotation (anchorData.transform);
}
顔のMeshを作成、更新する
void FaceAdded (ARFaceAnchor anchorData) { faceMesh = new Mesh (); faceMesh.vertices = anchorData.faceGeometry.vertices; faceMesh.uv = anchorData.faceGeometry.textureCoordinates; faceMesh.triangles = anchorData.faceGeometry.triangleIndices; faceMesh.RecalculateBounds(); faceMesh.RecalculateNormals(); meshFilter.mesh = faceMesh; } void FaceUpdated (ARFaceAnchor anchorData) { faceMesh.vertices = anchorData.faceGeometry.vertices; faceMesh.uv = anchorData.faceGeometry.textureCoordinates; faceMesh.triangles = anchorData.faceGeometry.triangleIndices; faceMesh.RecalculateBounds(); faceMesh.RecalculateNormals(); }
Blendshapeを取得する
取得可能な値の一覧は下記から画像付きで解説してくれています。
ARFaceAnchor.BlendShapeLocation - ARFaceAnchor | Apple Developer Documentation
ARBlendShapeLocationにパラメータKeyが格納されています。
パラメータを取得してモデルに反映させるコードはこんな感じになります。
void FaceUpdated (ARFaceAnchor anchorData) { blendShapes = anchorData.blendShapes; // 口の開閉値を取得 jawOpen = blendShapes[ARBlendShapeLocation.JawOpen]; // 左目の開閉値を取得 eyeBlink_L = blendShapes[ARBlendShapeLocation.EyeBlinkLeft]; // Blendshapeの値をモデルに反映するなど m_MeshRenderer.SetBlendShapeWeight(0, jawOpen * 100f); }
iPhoneX限定という制約はありますが、かなりコードがシンプルなので、お手軽にフェイシャルモーションを作ることができるのではないでしょうか。
明日の記事はnryotaさんになります!
qiita.com