ARKitで動き出すポスターを作る
ポスターやカードをカメラで写すとARが浮かび上がってくるタイプのARが流行っています。手軽でできて分かりやすいARです。この機能をARKitで実装する方法を紹介していきます。
以下みたいなイメージ。
https://www.youtube.com/watch?v=mg-RDMab6VQ
[Swift/ARKit2] 動くポスターを1時間でつくろうという記事の実装部分の解説です。
ポスター画像と再生用の動画を用意する
画像マーカーとなるポスター画像ファイルと、マーカーを読み取った際に再生する動画ファイルを用意しましょう。それぞれjpgファイルとmp4ファイルだと間違いないと思います。また、2Dのポスターが突然動き出すように表現するためには、それぞれ縦横比を統一した方が良いでしょう。
ポスター画像をARImageResourceに登録する
ARKitで作るAR名刺と同じ容量で、ポスターが画像をARImageResourceに登録しましょう。
ポスター動画をプロジェクトに追加する
ポスター動画(例ではmovie.mp4というファイル)をXcodeのプロジェクトに対してドラッグアンドドロップします。
画像を読み取ったら反応するようにする
まずはsceneViewをARSCNViewDelegateに準拠させます。また、AR Resourcesの画像をtrackingImagesとしてARImageTrackingConfigurationにセットしときます。
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARImageTrackingConfiguration()
if let trackedImages = ARReferenceImage.referenceImages(inGroupNamed: "AR Resources", bundle: Bundle.main) {
configuration.trackingImages = trackedImages
}
sceneView.session.run(configuration)
}
以下のようにrenderer(didAdd node:)
のメソッドを書き、ARImageAnchorの発見を検知します。
extension ViewController: ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor else {
return
}
}
}
SKVideoNodeとSKSceneで動画のシーンを作成する
次にARKit(正確にはSceneKit)で動画を再生する方法を解説します。動画自体は2Dなので、今回SpriteKitを使って動画を再生します。SpriteKitで作られたSKSceneをSceneKitで再生していきます。
予め用意してXcodeにドラッグアンドドロップしていたmovie.mp4を呼び出して動画を再生します。
guard let imageAnchor = anchor as? ARImageAnchor else {
return
}
guard let fileUrlString = Bundle.main.path(forResource: "movie", ofType: "mp4") else {
return
}
let videoItem = AVPlayerItem(url: URL(fileURLWithPath: fileUrlString))
let player = AVPlayer(playerItem: videoItem)
player.play()
次に、SKSceneを作成し、その中にSKVideoNodeを追加します。
let size = CGSize(width: 480, height: 360)
let videoScene = SKScene(size: size)
let videoNode = SKVideoNode(avPlayer: player)
videoNode.position = CGPoint(x: size.width / 2, y: size.height / 2)
videoNode.yScale = -1.0
videoScene.addChild(videoNode)
SCNPlaneのマテリアルとして動画のシーンをセットする
最後にポスターと同じサイズの平面のジオメトリを持つSCNNodeを作成し、そのマテリアルとして、動画を再生するSKSceneを渡すことで、動画を再生する平面のノードを作ることができます。最後にその平面をImageAnchorの位置にあるnodeに追加して完成です。
let plane = SCNPlane(
width: imageAnchor.referenceImage.physicalSize.width,
height: imageAnchor.referenceImage.physicalSize.height
)
plane.firstMaterial?.diffuse.contents = videoScene
let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = -Float.pi / 2
node.addChildNode(planeNode)
画像検知後の一連のコードは以下です。
extension ViewController: ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor,
let fileUrlString = Bundle.main.path(forResource: "black", ofType: "mp4") else {
return
}
let videoItem = AVPlayerItem(url: URL(fileURLWithPath: fileUrlString))
let player = AVPlayer(playerItem: videoItem)
player.play()
let size = CGSize(width: 480, height: 360)
let videoScene = SKScene(size: size)
let videoNode = SKVideoNode(avPlayer: player)
videoNode.position = CGPoint(x: size.width / 2, y: size.height / 2)
videoNode.yScale = -1.0
videoScene.addChild(videoNode)
let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width,
height: imageAnchor.referenceImage.physicalSize.height)
plane.firstMaterial?.diffuse.contents = videoScene
let planeNode = SCNNode(geometry: plane)
planeNode.eulerAngles.x = -Float.pi / 2
node.addChildNode(planeNode)
}
}
以上です。特定のポスター画像を発見すると、その位置に動画を再生することができました。
(動画はイメージ Using ARKit To Display Video In Augmented Realityから引用)
関連記事
https://qiita.com/IZUMIRU/items/3c36f7730aff5e6305c5
https://medium.com/quick-code/using-arkit-to-display-video-in-augmented-reality-3a2e4c1418ad
Author And Source
この問題について(ARKitで動き出すポスターを作る), 我々は、より多くの情報をここで見つけました https://qiita.com/kboy/items/663a6119c8734fd1b06d著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .