Chapters

Hide chapters

Metal by Tutorials

Fifth Edition · macOS 26, iOS 26 · Swift 6, Metal 3 · Xcode 26

Section I: Beginning Metal

Section 1: 10 chapters
Show chapters Hide chapters

Section II: Intermediate Metal

Section 2: 8 chapters
Show chapters Hide chapters

Section III: Advanced Metal

Section 3: 8 chapters
Show chapters Hide chapters

9. Navigating a 3D Scene
Written by Marius Horga & Caroline Begbie

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

A scene can consist of one or more cameras, lights and models. Of course, you can add these objects in your renderer class, but what happens when you want to add some complicated game logic? Adding it to the renderer gets more impractical as you need additional interactions. Abstracting the scene setup and game logic from the rendering code is a better option.

Cameras go hand in hand with moving around a scene, so in addition to creating a scene to hold the models, you’ll add a camera structure. Ideally, you should be able to set up and update a scene in a new file without diving into the complex renderer.

You’ll also create an input controller to manage keyboard and mouse input so that you can wander around your scene. Game engines will include features such as input controllers, physics engines and sound.

While the game engine you’ll work toward in this chapter doesn’t have any high-end features, it’ll help you understand how to integrate other components and give you the foundation needed to add complexity later.

The Starter Project

Aside from some helpful comments in Renderer, the starter project for this chapter is the same as the challenge project for the previous chapter.

Scenes

A scene holds models, cameras and lighting. It’ll also contain the game logic and update itself every frame, taking into account user input.

Qcu ibikiik zliqu
Nki enizeuq jfuco

Cameras

Instead of creating view and projection matrices in the renderer, you can abstract the construction and calculation away from the rendering code to a Camera structure. Adding a camera to your scene lets you construct the view matrix in any way you choose.

Lju radeju qitujawc
Vho guhico sakuwohz

Lru wawatu koduhexs ebeacd ohl deqrog
Gfe yeweno devaguvm axuonz ikr titdeh

Input

There are various forms of input, such as game controllers, keyboards, mice and trackpads. On both macOS and iPadOS, you can use Apple’s GCController API for these types of inputs. This API helps you set your code up for:

Delta Time

First, you’ll set up the left and right arrows on the keyboard to control the camera’s rotation.

Camera Rotation

➤ Open GameScene.swift. In update(deltaTime:), replace:

Uhewy obhug vuqn tu jureja fma hogowi
Ojezb ewhag pelq gi bipiqe xno lawamo

Camera Movement

You can implement forward and backward movement the same way using standard WASD keys:

Supgeyq muyvedy
Wibcayc meznisf

Dogezd ajeulb dli ytelo upuyq dka wujtuult
Vocurf ukieqh nje gviba ojuwc jca debyealf

Mouse and Trackpad Input

Players on macOS games generally use mouse or trackpad movement to look around the scene rather than arrow keys. This gives all-around viewing, rather than the simple rotation on the y axis that you have currently.

Arcball Camera

In many apps, the camera rotates about a particular point. For example, in Blender, you can set a navigational preference to rotate around selected objects instead of around the origin.

Orbiting a Point

The camera needs a track to rotate about a point:

Edpevefh u jiosk
Abbasast u saihf

The lookAt Matrix

A lookAt matrix rotates the camera so it always points at a target. In MathLibrary.swift, you’ll find a float4x4 initialization init(eye:target:up:). You pass the camera’s current world position, the target and the camera’s up vector to the initializer. In this app, the camera’s up vector is always [0, 1, 0].

Ocgaji rvo kavj
Ornoge tmi gewv

Orthographic Projection

So far, you’ve created cameras with perspective so that objects further back in your 3D scene appear smaller than the ones closer to the camera. Orthographic projection flattens three dimensions to two dimensions without any perspective distortion.

Emxyazwupcaz xnovugpiid
Efwlocbuzvim zkisunxeow

Kmi ifdrebluvmoc wpobikqeem rresbey
Zlo atxwulwubfef zdiyaybouk gzuyxad

Utgvamvebfix diukacs qpuz qzu xjubd
Orrzonweszol coodewp fmuz wri gzoyw

Ihmmagnovpuh xaomick hmiz zku teb
Ajrbuchubteh veoxubf ggaw fzu gum

Challenge

For your challenge, combine FPCamera and ArcballCamera into one PlayerCamera. In addition to moving around the scene using the WASD keys, a player can also change direction and look around the scene with the mouse.

Noqefw ivuumt zre blaru
Ralijf oloezt hqe zgeri

Key Points

  • Scenes abstract game code and scene setup away from the rendering code.
  • Camera structures let you calculate the view and projection matrices separately from rendering the models.
  • On macOS and iPadOS, use Apple’s GCController API to process input from game controllers, keyboards and mice.
  • On iOS, GCVirtualController gives you onscreen D-pad controls.
  • For a first-person camera, calculate position and rotation from the player’s perspective.
  • An arcball camera orbits a target point.
  • An orthographic camera renders without perspective so that all vertices rendered to the 2D screen appear at the same distance from the camera.
Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now