目次
Session概要
RealityKitはAppleが拡張現実のためにゼロから作り上げたレンダリング、アニメーション、物理、音声エンジンです。これまでの3Dレンダラーを見直し、開発者が簡単にプロトタイプを作成し、高品質なAR体験を創り出すことができます。RealityKitの新たな改良点をアプリに効果的に実装すっる方法についてもお伝えします。ビデオテクスチャ、iPad ProのLiDARスキャナを使ったシーンの理解、ロケーションアンカー、フェイストラッキング、改良されたデバッグツールなどの機能を見ていきます。 https://developer.apple.com/videos/play/wwdc2020/10612/
動画マテリアル
- RealityKitのマテリアルとして動画が活用可能
- 動画の情報を取り入れ、変化するテクスチャを取得できる
- 例えば、グロー効果のシミュレートや動画講義など
- その他 音声の再生が可能で、空間オーディオの再生ができる
- 動画の空間オーディオソースとなる
- 空間オーディオは特定の場所から音が伝播するように動作する
- エンティティが音源となり臨場感を生み出す
- 動画の再生などはRealityKitの内部で行うため、同期やオーディオ再生などの追加作業は発生しない

使用方法
- 動画の読み込みを行い、エンティティのマテリアルに割り当てる(具体的には下記)
- RealityKitはAVFoundationのAVPlayerを動画マテリアルとして使用する
- AVFoundationで動画を読み込み、AVPlayerオブジェクトを作成する
- AVPlayerオブジェクトを使用して動画マテリアルが作成できる
- AVPlayerでは、メディア内で直接再生、一時停止、シークが可能であるがテクスチャごとに動画作成せずに動画アトラスを使用可能であるため動画マテリアルとして使用時も同様に可能
// 1. 動画の読み込みサンプル
// Use AVFoundation to load a video
let asset = AVURLAsset(url: Bundle.main.url(forResource: "glow", withExtension: "mp4")!)
let playerItem = AVPlayerItem(asset: asset)
// Create a Material and assign it to your model entity...
let player = AVPlayer()
bugEntity.materials = [VideoMaterial(player: player)]
// Tell the player to load and play
player.replaceCurrentItem(with: playerItem)
player.play()

LiDARセンサーを使用した Scene Understanding
- Scene Understandingとは
- バーチャルコンテンツを現実世界と相互作用させること
- 現実世界に関する設定のリストが環境構造体(Environment)の下にある
- EnvironmentはARViewが保持する
- Environmentでの構成
- 背景画像
- 環境ベースの光
- 空間オーディオオプション
- Scene Understandingオプション
- 現実世界と仮想空間の相互作用を構成する
- センサーからのデータをARKitが処理し、現実世界にバーチャルな世界を投影し、バーチャルコンテンツをインタラクティブに使用可能になった

Scene Understandingの構成
- オクルージョン
- 現実世界のオブジェクトがバーチャルオブジェクトを遮蔽すること
- Receives lighting(受光)
- バーチャルオブジェクトが現実世界で影を作る
- オクルージョンが自動的にオンになる
- Physics(物理)
- バーチャルオブジェクトが現実世界と物理的に相互作用できる
- Collisionが自動的にオンになる
- Collision(衝突)
- 衝突イベントの生成や現実世界にレイキャストする機能
- 衝突イベントの生成や現実世界にレイキャストする機能

オクルージョン
- バーチャルオブジェクトを遮蔽することでリアルさを増すことができる

木でバーチャルオブジェクトが隠れることがわかる
Receives lighting(受光)
- 左側はReceives lightingなしでバーチャルオブジェクトは影がなく浮いている用に見える
- 右側はReceives lightingありでバーチャルオブジェクトは影を作り設置しているように見える
- 影は水平に固定されたオブジェクトにできる影と似ている
- 現実世界のサーフェスを使用するので、オブジェクトを水平に固定する必要はない
- 仮想空間のエンティティすべてが現実世界に影を落とすことが可能
- ただし、影は上からの光によって作られる
- つまり、壁には影ができない
- この場合はエンティティを垂直方向に固定する必要がある

Physics(物理)
- 以前のAR体験では現実世界を平面とプリミティブで表現していたが、非現実な表現となってしまう
- 注意点
- 現実世界のオブジェクトは無限の質量を持つ静的オブジェクトとし、移動しない前提
- メッシュは常に更新され、特に平面以外のサーフェスにオブジェクトが静止することはない
- 再構築されたメッシュはスキャンされた領域に限定される
- 例えば、床をスキャナしなければシーンにも存在しないためオブジェクトは落下する
- メッシュは現実世界の近似
- Physicsのメッシュはオクルージョンマスクほど正確ではないため、下記の画像のようにくっきりしたエッジは期待できない
- Physicsは共同セッションには対応しない
- 共同セッションを機能させるにはScene Understandingオプションが必要
- 共同セッションを機能させるにはScene Understandingオプションが必要


Collision(衝突)
- ユースケース
- レイキャスティング
- パス検索や初期オブジェクトの配置、視覚テストやメッシュ状の物の維持などで活用できる
- Collisionイベント
- 現実世界のオブジェクトと仮想オブジェクトが衝突した際に反応させる
- レイキャスティング
- レイキャスティングはエンティティのリストを返し、Collisionイベントは2つのエンティティ間で発生する
- すなわち、現実世界のオブジェクトに対応するエンティティが必要となる
- そのため、Scene Understandingエンティティを使用する
- Scene Understandingエンティティは様々なコンポーネントから成るエンティティで下記のコンポーネントを持つ
- Transform(変形)
- Collision(衝突)
- Physics(物理)
- Scene Understanding
- HasSceneUnderstandingトレイトを持ち
- レイキャスティングやCollisionイベントの結果から現実世界のオブジェクトを見つけるにはScene Understandingエンティティを探せば良い
- これらのエンティティはRealityKitによって作成され管理されている
- 現実世界のオブジェクトと衝突させるのを回避するには、Collision filtersを使用する
// オブジェクト回避の実装サンプル(レイキャスティングの使用)
// Get the position and forward direction of the bug in world space
let bugOrigin = bug.position(relativeTo: nil)
let bugForward = bug.convert(direction: [0, 0, 1], relativeTo: nil)
// Perform a raycast
let collisionResults = arView.scene.raycast(origin: bugOrigin, direction: bugForward)
// Get all hits against a Scene Understanding Entity
let filteredResults = collisionResults.filter { $0.entity as? HasSceneUnderstanding }
// Pick the closest one and get the collision point
guard let closestCollisionPoint = filteredResults.first?.position else {
return
}
if length(bugOrigin - closestCollisionPoint) < safeDistance {
// Avoid obstacle too close to object’s forward
}
// Collisionイベント
// Subscribe to all collision events
arView.scene.subscribe(to: CollisionEvents.Began.self) { event in
// Get any entity if it conforms to HasSceneUnderstanding
guard let sceneUnderstandingEntity = (event.entityA as? HasSceneUnderstanding)
?? (event.entityB as? HasSceneUnderstanding)
else {
// Did not collide with real world
return
}
// The bug entity is the one that is not the scene understanding entity
let bugEntity = (sceneUnderstandingEntity == event.entityA)
? event.entityB : event.entityA
// Disintegrate the bug entity
…
}
// Collisionフィルターによる現実世界のオブジェクトの衝突を回避
// Only collide with real world
entity.collision?.filter.mask = [.sceneUnderstanding]
// Never collide with real world
entity.collision?.filter.mask = CollisionGroup.all.subtracting(.sceneUnderstanding)
デバッグの視覚化
- ARViewのデバッグオプションにshowSceneUnderstandingを追加することで現実世界のオブジェクトにメッシュを表示することが可能


色の距離はデバイスのカメラからの距離を表す
デバッグレンダリングの改善について
- エンティティのレンダリングに関連する様々なプロパティの検視機能が追加
- デバッグレンダリング関連の問題を軽減するために追加したのがエンティティのレンダリングに関連する様々なプロパティを検査する機能
- モデルが正しくロードされたか、モデルに問題がないかを確認するために使用する
- 入射した拡散光や鏡面光などのPBR関連の出力を使用してマテリアルパラメータの調整量を知ることができる
- これらのパラメータを視覚化するには、DebugModelComponentを使用する
- ただし、視覚化は対象エンティティのみ適応され子には継承されないので注意

ARKit 4の統合に関する更新について
- 顔追跡機能
- ARKitは顔追跡機能のサポートをより多くのデバイスに拡張した
- A12プロセッサまたはそれ以上のデバイス
- ロケーションアンカー
- RealityKitを使用してARコンテンツを現実世界に投影する
- ARコンテンツを現実世界の特定の場所に配置可能
- これらの詳細についてはこちらを参照