Slide 1

Slide 1 text

Getting Started with ARKit Building augmented reality apps for iOS 11 Warren Moore @ NSMeetup 5 December 2017

Slide 2

Slide 2 text

A little about me • Worked on Camera & Photo apps at Apple (2014) • Wrote a book on Metal • Worked on Metal ecosystem at Apple (2016) • Now independent again 2

Slide 3

Slide 3 text

Agenda • What is AR[Kit]? • Building an ARKit app • Augmenting your face with iPhone X • Further considerations • Q&A 3

Slide 4

Slide 4 text

What is AR[Kit]?

Slide 5

Slide 5 text

What is AR? “[Taking] digital or computer-generated information, whether it be images, audio, video, and touch or haptic sensations and overlaying them [on] a real-time environment” Kipper, Greg; Rampolla, Joseph. Augmented Reality: An Emerging Technologies Guide to AR 5

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

A brief history 7

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

What is ARKit? • Tracking • Scene understanding • Rendering 9

Slide 10

Slide 10 text

Tracking • Six degree of freedom (6 DOF) world tracking • Visual inertial odometry • Markerless, bootstrapping 10

Slide 11

Slide 11 text

Scene Understanding • Feature detection • Horizontal planes • Facial poses and expressions (iPhone X) • Hit testing • Light estimation 11

Slide 12

Slide 12 text

Rendering • Deep integration with game frameworks • SpriteKit • SceneKit • Hooks and utilities for custom rendering (Metal, etc.) 12

Slide 13

Slide 13 text

13

Slide 14

Slide 14 text

14

Slide 15

Slide 15 text

Building an ARKit app

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

Step by step • Configuring and running a session • Receiving feature point updates • Adding geometry to visualize anchors • Interacting with the scene 17

Slide 18

Slide 18 text

But first! 18 NSCameraUsageDescription NSMicrophoneUsageDescription

Slide 19

Slide 19 text

Getting an ARSession 19 let session = ARSession() let session = arView.session

Slide 20

Slide 20 text

Creating a configuration 20 let config = ARWorldTrackingConfiguration() config.planeDetection = .horizontal

Slide 21

Slide 21 text

Running a configuration 21 session.run(configuration, options: .resetTracking)

Slide 22

Slide 22 text

ARSCNViewDelegate 22 arView.delegate = self

Slide 23

Slide 23 text

ARSCNViewDelegate 23 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { guard let planeAnchor = anchor as? ARPlaneAnchor else { return } addPlaneGeometry(for: planeAnchor, node) } func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { guard let planeAnchor = anchor as? ARPlaneAnchor else { return } guard let planeNode = node.childNodes.first else { return } updatePlaneGeometry(for: planeAnchor, planeNode) }

Slide 24

Slide 24 text

Adding geometry to an anchor 24 func addPlaneGeometry(for anchor: ARPlaneAnchor, _ node: SCNNode) { let planeGeometry = SCNPlane(width: 1, height: 1) let material = planeGeometry.firstMaterial! material.diffuse.contents = UIImage(named: "grid.png") material.diffuse.wrapS = .repeat material.diffuse.wrapT = .repeat let planeNode = SCNNode(geometry: planeGeometry) node.addChildNode(planeNode) }

Slide 25

Slide 25 text

Updating plane geometry 25 func updatePlaneGeometry(for anchor: ARPlaneAnchor, _ node: SCNNode) { node.position = SCNVector3(anchor.center.x, 0, anchor.center.z) node.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0) let planeGeometry = node.geometry as! SCNPlane planeGeometry.width = CGFloat(anchor.extent.x) planeGeometry.height = CGFloat(anchor.extent.z) let material = planeGeometry.firstMaterial! material.diffuse.contentsTransform = SCNMatrix4MakeScale(anchor.extent.x, anchor.extent.z, 1) }

Slide 26

Slide 26 text

Hit testing 26 override func touchesMoved(_ touches: Set, with event: UIEvent?) { super.touchesMoved(touches, with: event) if let firstTouch = touches.first { let point = firstTouch.location(in: arView) addInk(at: point) } }

Slide 27

Slide 27 text

Going splat 27 func addInk(at point: CGPoint) { let results = arView.hitTest(point, types: .existingPlaneUsingExtent) if let nearestResult = results.first { guard let anchor = nearestResult.anchor as? ARPlaneAnchor else { return } guard let planeNode = arView.node(for: anchor) else { return } let splatGeometry = SCNPlane(width: 0.25, height: 0.25) let material = splatGeometry.firstMaterial! material.diffuse.contents = UIImage(named: "splat-pink") let splatNode = SCNNode(geometry: splatGeometry) let planeOrienation = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0) splatNode.transform = SCNMatrix4Mult(planeOrienation, SCNMatrix4(nearestResult.localTransform)) planeNode.addChildNode(splatNode) } }

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

Augmenting your face

Slide 30

Slide 30 text

ARFaceTrackingConfiguration • Uses TrueDepth camera exclusive to iPhone X • Higher-fidelity light estimation 30

Slide 31

Slide 31 text

ARFaceAnchor • 6 DOF facial pose • Fine-grained facial expression via blend shapes • Face mesh - ARFaceGeometry, ARSCNFaceGeometry 31

Slide 32

Slide 32 text

Visualizing blend shapes

Slide 33

Slide 33 text

Blend shape locations 33 browDownLeft browDownRight browInnerUp browOuterUpLeft browOuterUpRight cheekPuff cheekSquintLeft cheekSquintRight eyeBlinkLeft eyeBlinkRight eyeLookDownLeft eyeLookDownRight eyeLookInLeft eyeLookInRight eyeLookOutLeft eyeLookOutRight eyeLookUpLeft eyeLookUpRight eyeSquintLeft eyeSquintRight eyeWideLeft eyeWideRight jawForward jawLeft jawOpen jawRight mouthClose mouthDimpleLeft mouthDimpleRight mouthFrownLeft mouthFrownRight mouthFunnel mouthLeft mouthLowerDownLeft mouthLowerDownRight mouthPressLeft mouthPressRight mouthPucker mouthRight mouthRollLower mouthRollUpper mouthShrugLower mouthShrugUpper mouthSmileLeft mouthSmileRight mouthStretchLeft mouthStretchRight mouthUpperUpLeft mouthUpperUpRight noseSneerLeft noseSneerRight

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

Step by step • Configuring and running a face-tracking session • Receiving face anchor updates • Adding/updating geometry according to blend shapes 35

Slide 36

Slide 36 text

Face Tracking Configuration 36 let config = ARFaceTrackingConfiguration() config.isLightEstimationEnabled = true

Slide 37

Slide 37 text

Loading the Model 37 // Load model file from bundle let nutcrackerNode = SCNReferenceNode(url: url)! nutcrackerNode.load() // Store nodes we will be animating mouthNode = nutcrackerNode.childNode(withName: "mouth", recursively: true) eyebrowLeftNode = nutcrackerNode.childNode(withName: "left_eyebrow", recursively: true) eyebrowRightNode = nutcrackerNode.childNode(withName: "right_eyebrow", recursively: true) // Store initial positions of animated nodes so we can offset them mouthPosition = mouthNode.position eyebrowLeftPosition = eyebrowLeftNode.position eyebrowRightPosition = eyebrowRightNode.position

Slide 38

Slide 38 text

Animating by blend shapes 38 func updateModel(_ faceAnchor: ARFaceAnchor) { let blendShapes = faceAnchor.blendShapes guard let browUp = blendShapes[.browInnerUp] as? Float else { return } guard let jawOpen = blendShapes[.jawOpen] as? Float else { return } eyebrowLeftNode.position.y = eyebrowLeftPosition.y + (browUp * browRaiseHeight) eyebrowRightNode.position.y = eyebrowRightPosition.y + (browUp * browRaiseHeight) mouthNode.position.y = mouthPosition.y - (jawOpen * jawHeight) }

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

Further considerations

Slide 41

Slide 41 text

• Finding AR content • AR “aesthetic” • Accessibility 41 Topics

Slide 42

Slide 42 text

Where to find AR content • Not an artist? Not a problem! • Multiple high-quality content markets - Sketchfab - Google Poly - CGTrader, Turbosquid, etc. • Easily convert to OBJ/DAE/SCN 42

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

A E S T H E T I C

Slide 46

Slide 46 text

Accessibility • As with all custom drawing (Core Graphics, Metal, etc.), it’s not automatic • Consider adopting the UIAccessibilityContainer protocol • See Sommer Panage’s talk at Realm https://academy.realm.io/posts/sommer-panage-accessibility-implementation-ios/ • Matt Gemmell has some timeless words on this too https://mattgemmell.com/accessibility-for-iphone-and-ipad-apps/ 46

Slide 47

Slide 47 text

Accessibility redux • By definition, you’re already augmenting the world • Look for opportunities to aid users with visual, motor, or cognitive challenges • Machine learning can help everyone see better - Object identification, navigation, situational awareness 47

Slide 48

Slide 48 text

Resources / Q&A • WWDC 2017 and Fall 2017 Videos https://developer.apple.com/arkit/ • Mohammad Azam’s book and course on Udemy https://gumroad.com/l/QOIq https://www.udemy.com/mastering-arkit-for-ios-using-swift • Upload ARKit weekend course (Dec. 8-10) https://upload.io/courses/ux-of-ar-design-arkit/ 48

Slide 49

Slide 49 text

Thank you!