Chapters

Hide chapters

Metal by Tutorials

Fourth Edition · macOS 14, iOS 17 · Swift 5.9 · Xcode 15

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

5. 3D Transformations
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

In the previous chapter, you translated vertices and moved objects around the screen by calculating the position data in the vertex function. But there’s a lot more you’ll want to do when working in 3D space, such as rotating and scaling your objects. You’ll also want to have an in-scene camera so that you can move around your scene.

To move, scale and rotate a triangle, you’ll use matrices — and once you’ve mastered one triangle, it’s a cinch to rotate a model with thousands of triangles at once!

For those of us who aren’t math geniuses, vectors and matrices can be a bit scary. Fortunately, you don’t always have to know what’s under the hood when using math. To help, this chapter focuses not on the math, but the matrices. As you work through this chapter, you’ll gradually extend your linear algebra knowledge as you learn what matrices can do for you and how to manipulate them.

Transformations

Look at the following picture.

Affine Transformations
Affine Transformations

Using the vector image editor, Affinity Designer, you can scale and rotate a cat through a series of affine transformations. Instead of individually calculating each position, Affinity Designer creates a transformation matrix that holds the combination of the transformations. It then applies the transformation to each element.

Note: Affine means that after you’ve done the transformation, all parallel lines remain parallel.

Of course, no one wants to translate, scale and rotate a cat since they’ll probably bite. So instead, you’ll translate, scale and rotate a triangle.

The Starter Project & Setup

➤ Open and run the starter project located in the starter folder for this chapter.

The starter project
Clo tbixdog dweguch

Translation

The starter project renders two triangles:

Displacement Vectors
Fabjjuwidiyq Dumnaqh

Vectors & Matrices

You can better describe position as a displacement vector of [0.3, -0.4, 0]. You move each vertex 0.3 units in the x-direction, and -0.4 in the y-direction from its starting position.

Vectors
Qowqucr

An identity matrix
En axijvasm rewduk

The Magic of Matrices

When you multiply matrices, you combine them into one matrix. You can then multiply a vector by this matrix to transform the vector. For example, you can set up a rotation matrix and a translation matrix. You can then calculate the transformed position with the following line of code:

translationMatrix * rotationMatrix * positionVector

Creating a Matrix

➤ Open Renderer.swift, and locate where you render the first gray triangle in draw(in:).

var position = simd_float3(0, 0, 0)
renderEncoder.setVertexBytes(
  &position,
  length: MemoryLayout<SIMD3<Float>>.stride,
  index: 11)
var translation = matrix_float4x4()
translation.columns.0 = [1, 0, 0, 0]
translation.columns.1 = [0, 1, 0, 0]
translation.columns.2 = [0, 0, 1, 0]
translation.columns.3 = [0, 0, 0, 1]
var matrix = translation
renderEncoder.setVertexBytes(
  &matrix,
  length: MemoryLayout<matrix_float4x4>.stride,
  index: 11)
position = simd_float3(0.3, -0.4, 0)
renderEncoder.setVertexBytes(
  &position,
  length: MemoryLayout<SIMD3<Float>>.stride,
  index: 11)
let position = simd_float3(0.3, -0.4, 0)
translation.columns.3.x = position.x
translation.columns.3.y = position.y
translation.columns.3.z = position.z
matrix = translation
renderEncoder.setVertexBytes(
  &matrix,
  length: MemoryLayout<matrix_float4x4>.stride,
  index: 11)
constant float3 &position [[buffer(11)]])
constant float4x4 &matrix [[buffer(11)]])
float3 translation = in.position.xyz + position;
float3 translation = in.position.xyz + matrix.columns[3].xyz;
Translation by adding a matrix column to the position
Rcetdxaweoq bq anwukq u bakcez cejakr fo vho yuweraox

float4 translation = matrix * in.position;
VertexOut out {
  .position = translation
};
return out;

Scaling

➤ Open Renderer.swift, and in draw(in:), locate where you set matrix in the second red triangle.

let scaleX: Float = 1.2
let scaleY: Float = 0.5
let scaleMatrix = float4x4(
  [scaleX, 0,   0,   0],
  [0, scaleY,   0,   0],
  [0,      0,   1,   0],
  [0,      0,   0,   1])
matrix = scaleMatrix
Scaling with a matrix
Qtamudm yumz i qornux

matrix = translation * scaleMatrix
A translated and scaled triangle
A vrefrdojex edd tminac bzuemssa

Rotation

You perform rotation in a similar way to scaling.

let angle = Float.pi / 2.0
let rotationMatrix = float4x4(
  [cos(angle), -sin(angle), 0,    0],
  [sin(angle),  cos(angle), 0,    0],
  [0,           0,          1,    0],
  [0,           0,          0,    1])

matrix = rotationMatrix
Rotating about the origin
Haraheft eqiit svo ibesis

matrix = translation * rotationMatrix * scaleMatrix
Scale, rotate and translate
Njefu, rudicu ijk vnolsfoya

translation.columns.3.x = triangle.vertices[2].x
translation.columns.3.y = triangle.vertices[2].y
translation.columns.3.z = triangle.vertices[2].z
matrix = translation.inverse
Rotate about a point (1)
Nicuvo oliiy a guojm (4)

matrix = rotationMatrix * translation.inverse
Rotate about a point (2)
Cofofu exoux a beotp (1)

matrix = translation * rotationMatrix * translation.inverse
Rotate about a point (3)
Mowode ofoeq u maekj (5)

Key Points

  • A vector is a matrix with only one row or column.
  • By combining three matrices for translation, rotation and scale, you can position a model anywhere in the scene.
  • In the resources folder for this chapter, references.markdown suggests further reading to help better understand transformations with linear algebra.
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.
© 2024 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