To practice your SceneKit knowledge, create a new project and instead of choosing the Game template, pick the Single View Application template. Of course, you are free to explore the default project Xcode creates for you when you choose the Game template with SceneKit, but it's not terribly useful for the AR gallery.
After creating your project, open the main storyboard and look for a SceneKit view. Drag this view into the view controller. You should notice that the view you just added to the view controller has replaced the default view entirely. Because of this, the view property on ViewController will not be a regular UIView, it will be an instance of SCNView instead. This is the view that will be used to render the SceneKit scene in.
Add the following code to viewDidLoad() in ViewController.swift to cast the view property from a UIView to an SCNView:
guard let sceneView = self.view as? SCNView else { return }
Similar to how SpriteKit works, SceneKit uses a scene to render its nodes in. Create an instance of SCNScene right after guard in viewDidLoad(), as shown:
let scene = SCNScene() sceneView.scene = scene sceneView.allowsCameraControl = true sceneView.showsStatistics = true sceneView.backgroundColor = UIColor.black
The preceding code creates a simple scene that will be used render all elements in. In addition to creating the scene, several debugging features are enabled to monitor the performance of the scene. Also, note that the allowsCameraControl property on the scene view is set to true. This will allow users to move a virtual camera around so they can explore the scene by swiping around in it.
Every SceneKit scene is viewed as if you're looking at it through a camera. You will need to add this camera to the scene yourself, and you must set it up appropriately for your purpose. The fact that SceneKit uses a camera is very convenient because the camera that you are going to set up in a second is replaced by the actual camera of a device when the scene is run with ARKit.
Add the following lines of code to viewDidLoad() to create and configure the camera:
let cameraNode = SCNNode() cameraNode.camera = SCNCamera() cameraNode.position = SCNVector3(x: 0, y: 0, z: 15) scene.rootNode.addChildNode(cameraNode)
Setting up a basic camera isn't very complicated. All you need is an SCNNode to add the camera to and an SCNCamera that will be used to view your scene through. Note that the camera is positioned using an SCNVector3 object. All nodes in a SceneKit scene use this object to express their positions in 3D space.
In addition to using a simulated camera, SceneKit also simulates real lighting conditions. When you run your scene with ARKit, the lighting conditions will be automatically managed by ARKit, making your objects look as if they truly are part of the environment. When you create a plain scene, however, you will need to add the lights yourself. Add the following lines of code to implement some ambient lighting:
let ambientLightNode = SCNNode() ambientLightNode.light = SCNLight() ambientLightNode.light!.type = .ambient ambientLightNode.light!.color = UIColor.orange scene.rootNode.addChildNode(ambientLightNode)
You can add different types of lights to a SceneKit scene. You can use ambient light as this sample does, but you can also add directional lights that focus on a particular direction, spotlight, or light points that light in all directions.
Now that you have lighting and a camera in place, you can add an object to the scene. You can use several pre-made shapes, also known as geometries, in your scene. Alternatively, you could import an entire 3D model in your scene. If you take a look at the default SceneKit app that Xcode generates if you create a new project with the Game template, you can see that it imports a 3D model of an airplane.
In the AR gallery you will build later, the artwork is augmented with digital information signs that are attached to the piece of art they belong to. To practice building such a sign, you will add a rectangular shape, or plane, to your SceneKit scene and place some text on top of it.
Add the following code to create a simple white plane, a node that renders the plane, and add it to the scene:
let plane = SCNPlane(width: 15, height: 10) plane.firstMaterial?.diffuse.contents = UIColor.white plane.firstMaterial?.isDoubleSided = true plane.cornerRadius = 0.3 let planeNode = SCNNode(geometry: plane) planeNode.position = SCNVector3(x: 0, y: 0, z: -15) scene.rootNode.addChildNode(planeNode)
If you were to build and run your app now, you would see a white square that is positioned in front of the camera. By swiping on the scene, you can make the camera move around the plane to view it from all possible sides. Note that the plane appears to be quite large even though it was only set to be 15 wide and 10 height. You might have guessed that these numbers represent points on the screen, just like in other apps. In SceneKit, there is no concept of points. All values for size and distance must be specified in meters. This means that everything you do is done relative to other objects or their real-world sizes. Using real sizes is essential when you take your SceneKit knowledge to ARKit.
To add some text to the plane you just created, use the following code:
let text = SCNText(string: "Hello, world!", extrusionDepth: 0) text.font = UIFont.systemFont(ofSize: 2.3) text.isWrapped = true text.containerFrame = CGRect(x: -6.5, y: -4, width: 13, height: 8) text.firstMaterial?.diffuse.contents = UIColor.red let textNode = SCNNode(geometry: text) planeNode.addChildNode(textNode)
The preceding code creates a text geometry. Since all values in SceneKit are in meters, the text size will be a lot smaller than you would probably expect. To make sure the text is positioned properly in the plane, text wrapping is enabled, and a containerFrame is used to specify the bounds for the text. Since the origin for the text field will be in the center of the plane it is displayed on, the x and y positions are offset negatively from the center to make sure the text appears in the correct place. You can try to play with this frame to see what happens. After configuring the text, it is added to a node, and the node is added to the plane node.
If you run your app now, you can see the Hello, World! text rendered on the white plane you created before. This sample is an excellent taste of what you're going to create next. Let's dive straight into building your AR gallery!