<!--
{
  "availability" : [
    "iOS: 15.0.0 -",
    "iPadOS: 15.0.0 -",
    "macCatalyst: 15.0.0 -",
    "macOS: 12.0.0 -",
    "tvOS: 26.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "RealityKit",
  "identifier" : "/documentation/RealityKit/CustomMaterial/normal-swift.property",
  "metadataVersion" : "0.1.0",
  "role" : "Instance Property",
  "symbol" : {
    "kind" : "Instance Property",
    "modules" : [
      "RealityKit"
    ],
    "preciseIdentifier" : "s:17RealityFoundation14CustomMaterialV6normalAC6NormalVvp"
  },
  "title" : "normal"
}
-->

# normal

A texture map that stores fine surface details for the entity.

```
var normal: CustomMaterial.Normal { get set }
```

## Discussion

*Normal mapping* is a real-time rendering technique that captures fine
surface details for a model by using a texture instead of increasing the
number of polygons in the model. It works by storing *surface normals*,
which are vectors perpendicular to the surface of the model, from a much
higher-resolution version of the same 3D object. A normal map stores
each vector in the image by storing the vectors’ `X`, `Y`, and `Z`
values as the `R`, `G`, and `B` components of the corresponding pixel in
the UV-mapped image.

For custom materials, [`normal`](/documentation/RealityKit/CustomMaterial/normal-swift.property) is only
used when [`lightingModel`](/documentation/RealityKit/CustomMaterial/lightingModel-swift.property) is
[`CustomMaterial.LightingModel.lit`](/documentation/RealityKit/CustomMaterial/LightingModel-swift.enum/lit) or
[`CustomMaterial.LightingModel.clearcoat`](/documentation/RealityKit/CustomMaterial/LightingModel-swift.enum/clearcoat) and its surface
shader calls `params.surface().set_normal(). T`he normal map texture is
still available to your surface shader function when using
[`CustomMaterial.LightingModel.unlit`](/documentation/RealityKit/CustomMaterial/LightingModel-swift.enum/unlit).

The following code loads a normal map texture and uses it to set this
property:

```swift
if let normalResource = try? TextureResource.load(named:"entity_normals") {
    let normalMap = MaterialParameters.Texture(normalResource)
    material.normal = .init(texture:normalMap)
}
```

The following Metal code shows how to sample the normal map texture in a
surface shader and use it to set the fragment’s surface normal:

```cpp
// Retrieve the entity's texture coordinates.
float2 uv = params.geometry().uv0();

// Entities loaded from USDZ or .reality files have texture coordinates
// with a flipped y-axis. This adjusts for that.
uv.y = 1.0 - uv.y;

// Sample the normal map to get the surface normal for this fragment.
auto tex = params.textures();
float3 color = (float3)tex.normal().sample(textureSampler, uv).rgb;

// Set the fragment's surface normal using the sampled value.
params.surface().set_normal(color);
```

For more information on creating custom materials and writing shader
functions, see
[Modifying RealityKit rendering using custom materials](/documentation/RealityKit/modifying-realitykit-rendering-using-custom-materials).

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)