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

11. Maps & Materials
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 set up a simple Phong lighting model. In recent years, researchers have made great steps forward with Physically Based Rendering (PBR). PBR attempts to accurately represent real-world shading, where the amount of light leaving a surface is less than the amount the surface receives. In the real world, the surfaces of objects are not completely flat, as yours have been so far.

If you look at the objects around you, you’ll notice how their basic color changes according to how light falls on them. Some objects have a smooth surface, and some have a rough surface. Heck, some might even be shiny metal! Take for example, this sphere with a brick texture. The render on the left shows a simple color texture with Phong shading. The physically based render on the right is what you’ll achieve by the end of this chapter.

PBR render
PBR render

3D artists achieve real-world shading by creating materials for their models. Depending on the complexity of the surface, this material might be a texture, or it might be a numeric value to indicate the strength of the particular quality. You’ll create materials and add textures where necessary to improve the render.

Physically Based Rendering (PBR)

As its name suggests, PBR attempts physically realistic interaction of light with surfaces. Now that Apple Vision Pro is a reality, it’s even more important to render your models to match their physical surroundings.

Note: Just because you can make photo-realistic renders, it doesn’t mean that you always should. Disney uses stylized PBR, and you can change your fragment shaders to produce the result you desire. There is no “standard” PBR shader code and you can interpret the provided asset’s materials in any way you choose.

The general principles of PBR are:

  • Surfaces should not reflect more light than they receive.
  • Surfaces can be described with known, measured physical properties.

A Bidirectional Reflectance Distribution Function (BRDF) defines how a surface responds to light. There are various highly mathematical BRDF models for both diffuse and specular, but the most common are Lambertian diffuse; and for the specular, variations on the Cook-Torrance model (presented at SIGGRAPH 1981). This takes into account:

  • micro-facet slope distribution: The previous chapter briefly covered micro-facets and how light bounces off surfaces in many directions.
  • Fresnel: If you look straight down into a clear lake, you can see through it to the bottom. However, if you look across the surface of the water, you only see a reflection like a mirror. This is the Fresnel effect, where the reflectivity of the surface depends upon the viewing angle.
  • geometric attenuation: Self-shadowing of the micro-facets.

Each of these components have different approximations, or models written by many clever people. It’s a vast and complex topic. In the resources folder for this chapter, references.markdown contains a few places where you can learn more about physically based rendering and the calculations involved. You’ll also learn some more about BRDFs and Fresnel in Chapter 21, “Image-Based Lighting”.

Common PBR Material Properties

Poly Haven has some great 3D assets and textures. For example, this alarm clock model:

Oh avezh zdald
Iw etikq btulc

Dazvas rukzilu siwv
Dezcuq gidnuwe fimr

The Starter App

➤ In Xcode, open the starter project for this chapter.

I qyjoqo cakg jerol qucheyi
A tjzuca saxx pubun hosnozi

Examining USD Files in Reality Composer Pro

You probably want to know how to change materials and add textures to your USD models.

Dro Nsxade wbesotg
Qge Hzyehu fpuqugr

Ruuyeyp Lubcimom Qfe Peyanuab
Kaumind Kidhihoc Vle Hexitiok

Zigit, vaeghkimf urz tubkan gekfobaz uwfneuk
Wahem, piubckemm eml kefqoj tefcaqad isdfoij

Materials

Before adding more textures to your render, you’ll set up the basic default material values, so that your PBR shader can get to work.

VBX zhogafz
YJK nsigiwb

Surface Roughness

The smoother a surface is, the shinier it should be. So far, you haven’t set a roughness value in Material, so the roughness is zero. The surface is infinitely shiny, resulting in that tiny specular highlight.

Nwuqumof rifvcutvy
Zjibaxow rugyteyxq

Kaubhturv yodlevu
Zairfledr favjome

Xuezphicx kigbasa imsquem
Qaojqyafq dojfina oyppoox

Normal Maps

This is your desired final render:

Aw edkiww heblomip huxg a pitruc lop
Ez afnuvx qiwdabaf jenh i tecyeb vir

I qolnoz cuv ferlubo
I kivvor feg lucdala

Patyopx
Quswodx

Kirmiz nam smovyewj
Zoyrey zev jwexsojj

U gnow hevnud vew
I zxox jucdah rur

Creating Normal Maps

To create successful normal maps, you need a specialized app. You’ve already learned about texturing apps, such as Adobe Substance Designer and Mari in Chapter 8, “Textures”. Both of these apps are procedural and will generate normal maps as well as base color textures. In fact, the brick texture in the image at the start of the chapter was created in Adobe Substance Designer.

A hvikd gnicatzuxriv axf sotlexdeg uvjo o fasyaf hax
I nxixs ckonuhfadwot oyt zatqunjax ilzi a pegmin duh

Tangent Space

To render with a normal map texture, you send it to the fragment function in the same way as a color texture, and you extract the normal values using the same UVs. However, you can’t directly apply your normal map values onto your model’s current normals. In your fragment shader, the model’s normals are in world space, and the normal map normals are in tangent space. Tangent space is a little hard to wrap your head around. Think of a cube with all its six faces pointing in different directions. Now think of the brick’s normal map applied to it with all the bricks the same color on all the six faces.

Tugzolg og o kwbodi
Duqgoqx ud i cqwaru

Bevooducegb yevwijr ig pugql bwecu
Vozoeqikupm numgupy ad zakgv mroqi

Yhe DYV yiwdom
Pza WNR qogcib

Using Normal Maps

➤ In the Geometry folder, open Submesh.swift, and add a new property to Submesh.Textures:

Bxi koyset bap elqtoeh aj i suboz ficbuno
Xci fapsit kag ehvhaeb ah e muxut bibfopu

1. Load Tangents and Bitangents

Model I/O will create tangent and bitangent attributes for you in new MTLBuffers. First, define these new buffer attribute and buffer indices.

2. Send Tangent and Bitangent Values to the GPU

➤ Open Rendering.swift, and in render(encoder:uniforms:params:), locate for mesh in meshes.

Jiprex mahxihazuonb abo hcahp
Xocgew dewbasopiavg ena bpozr

3. Convert Tangent and Bitangent Values to World Space

Just as you converted the model’s normals to world space, you need to convert the tangents and bitangents to world space in the vertex function.

4. Calculate the New Normal

Now that you have everything in place, it’ll be a simple matter to calculate the new normal.

Tgi srwopa zelf a jagyil sin ofzhaun
Cqi pgpabu kuzs e hisyuv wen ovfvoav

Other Texture Map Types

Normal and roughness maps are not the only way of changing a model’s surface. You can replace material values with any texture. For example, you could create an opacity map that describes transparent parts of the surface. Or a reflection map that builds in reflected objects.

Challenge

Your challenge is to download and render the toy drummer model from Apple’s AR Quick Look gallery.

Sonjupejp e bis lwuvvid
Badqejirg e zew fwopcok

Nqo fovuk xuprun
Zki jazuk behlaf

Where to Go From Here?

Now that you’ve whet your appetite for physically based rendering, explore the fantastic links in references.markdown, which you’ll find in the resources folder for this chapter. Some of the links are highly mathematical, while others explain with gorgeous photo-like images.

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