One Logo Pool Ball
RealityFoundation · IOS API REFERENCE

CustomMaterial

struct · iOS 15.0+ · SDK 27.1

struct CustomMaterial

A material that works with custom Metal shader functions. Custom, or programmable, materials allow you to leverage RealityKit’s existing shader pipeline to render physically based or unlit materials that support custom Metal shader functions. These functions modify how RealityKit renders an entity. Custom materials support two different types of custom Metal shader functions: geometry modifiers and surface shaders. Use a _surface shader _to calculate or specify all the material attributes that RealityKit uses to render your entity, such as ``CustomMaterial/baseColor-swift.property``, ``CustomMaterial/normal-swift.property``, and ``CustomMaterial/roughness-swift.property``. A _geometry modifier_ can offset the position of an entity’s vertices to change the size and shape of an entity. It can also change other per-vertex data, such as vertex color and UV texture coordinates, which define how RealityKit maps textures on to the model. - Important: For the Metal API documentation for custom material shader functions, see [the Metal RealityKit APIs PDF](https://developer.apple.com/metal/Metal-RealityKit-APIs.pdf). For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

Members (47)

get · iOS 18.0+

readsDepth

TypeScript
get readsDepth(): boolean
Swift declaration
var readsDepth: Bool { get set }

A boolean value that determines whether this material performs the depth test by reading RealityKit's depth buffer. If true, meshes with this material will depth test each of their fragments when being rendered. If an object that writes depth is in front of this material, this material will be hidden. If false, meshes with this material will ignore the depth test, and always render all of their fragments during their draw call, regardless of the positioning of other objects in the scene. Note that other objects may still render on top of this material, depending on draw order. The default value is true.

set · iOS 18.0+

readsDepth

TypeScript
set readsDepth(value: boolean)
Swift declaration
var readsDepth: Bool { get set }

A boolean value that determines whether this material performs the depth test by reading RealityKit's depth buffer. If true, meshes with this material will depth test each of their fragments when being rendered. If an object that writes depth is in front of this material, this material will be hidden. If false, meshes with this material will ignore the depth test, and always render all of their fragments during their draw call, regardless of the positioning of other objects in the scene. Note that other objects may still render on top of this material, depending on draw order. The default value is true.

get · iOS 15.0+

faceCulling

TypeScript
get faceCulling(): MaterialParameterTypes_FaceCulling
Swift declaration
var faceCulling: CustomMaterial.FaceCulling { get set }

A process in which the system specifies polygons to remove before rendering a mesh using this material. To improve performance, RealityKit culls polygons, or _faces_, that it determines won’t be visible. Discarding faces that aren’t part of the final render eliminates the need to do any calculations for those faces. RealityKit recognizes when a face aims toward the camera (a _front face_) or away from the camera (a _back face_). This value controls the type of faces RealityKit culls. The default for this value is ``MaterialParameterTypes/FaceCulling/back``, which means RealityKit removes faces that point away from the camera. Because back faces point away from the camera and are usually obscured by front-facing polygons, the user typically won’t see them. As a result, in most cases, the default setting is desirable because it culls polygons that don’t contribute to the rendered scene. You can change the culling behavior to cull front faces instead or to turn off face culling altogether, but be aware that turning off face culling results in less efficient rendering and may negatively impact your app’s frame rate.

set · iOS 15.0+

faceCulling

TypeScript
set faceCulling(value: MaterialParameterTypes_FaceCulling)
Swift declaration
var faceCulling: CustomMaterial.FaceCulling { get set }

A process in which the system specifies polygons to remove before rendering a mesh using this material. To improve performance, RealityKit culls polygons, or _faces_, that it determines won’t be visible. Discarding faces that aren’t part of the final render eliminates the need to do any calculations for those faces. RealityKit recognizes when a face aims toward the camera (a _front face_) or away from the camera (a _back face_). This value controls the type of faces RealityKit culls. The default for this value is ``MaterialParameterTypes/FaceCulling/back``, which means RealityKit removes faces that point away from the camera. Because back faces point away from the camera and are usually obscured by front-facing polygons, the user typically won’t see them. As a result, in most cases, the default setting is desirable because it culls polygons that don’t contribute to the rendered scene. You can change the culling behavior to cull front faces instead or to turn off face culling altogether, but be aware that turning off face culling results in less efficient rendering and may negatively impact your app’s frame rate.

get · iOS 18.0+

writesDepth

TypeScript
get writesDepth(): boolean
Swift declaration
var writesDepth: Bool { get set }

A boolean value that determines whether this material writes its depth into RealityKit's depth buffer. If true, meshes with this material will occlude objects behind them by writing their depth into RealityKit's depth buffer. If false, meshes with this material will not write their depth into RealityKit's depth buffer, and may be overwritten by objects drawn behind them, depending on draw order. The default value is true.

set · iOS 18.0+

writesDepth

TypeScript
set writesDepth(value: boolean)
Swift declaration
var writesDepth: Bool { get set }

A boolean value that determines whether this material writes its depth into RealityKit's depth buffer. If true, meshes with this material will occlude objects behind them by writing their depth into RealityKit's depth buffer. If false, meshes with this material will not write their depth into RealityKit's depth buffer, and may be overwritten by objects drawn behind them, depending on draw order. The default value is true.

get · iOS 15.0+

emissiveColor

TypeScript
get emissiveColor(): CustomMaterial_EmissiveColor
Swift declaration
var emissiveColor: CustomMaterial.EmissiveColor { get set }

The color of light this material emits. With physically based rendering (PBR), you can give entities in RealityKit the appearance of emitting light. Use this property to simulate real-world objects that glow, such as objects with LEDs or computer screens. To enable light emission from a material, set ``PhysicallyBasedMaterial/emissiveIntensity`` to a value greater than zero, then specify a color (other than black) using this property. You can specify a single emissive color for the entire material, or use a UV-mapped image texture to use different colors for different parts of the entity. With custom materials, RealityKit doesn’t use ``CustomMaterial/emissiveColor-swift.property`` automatically to render your entity. Call `params.surface().set_emissive_color()` from your surface shader, otherwise RealityKit renders no light emission. The following example assigns a tint color to the ``PhysicallyBasedMaterial/emissiveColor-swift.property`` property, without a texture: ```swift self.emissiveColor = PhysicallyBasedMaterial.EmissiveColor(color: .red) ``` This next example uses a texture to specify the ``PhysicallyBasedMaterial/emissiveColor-swift.property`` property: ```swift if let emissiveResource = try? TextureResource.load(named: "entity_emissive") { let emissiveMap = MaterialParameters.Texture(emissiveResource) material.emissiveColor = .init(texture: emissiveMap) } ``` This Metal code shows how to access the emissive color tint in your shader functions: ```cpp half3 emissiveTint = (half3)params.material_constants().emissive_color(); ``` The following Metal code demonstrates how to sample the emissive color texture for the current fragment: ```cpp // Get the entity's primary texture coordinates. float2 uv = params.geometry().uv0(); // Flip the y-axis. You only need to do this for entities you load from // USDZ or .reality files. uv.y = 1.0 - uv.y; // Sample the emissive color texture to get the value for this fragment. auto tex = params.textures(); half3 emissiveColor = (half3)tex.emissive_color() .sample(textureSampler, uv).rgb; ```

set · iOS 15.0+

emissiveColor

TypeScript
set emissiveColor(value: CustomMaterial_EmissiveColor)
Swift declaration
var emissiveColor: CustomMaterial.EmissiveColor { get set }

The color of light this material emits. With physically based rendering (PBR), you can give entities in RealityKit the appearance of emitting light. Use this property to simulate real-world objects that glow, such as objects with LEDs or computer screens. To enable light emission from a material, set ``PhysicallyBasedMaterial/emissiveIntensity`` to a value greater than zero, then specify a color (other than black) using this property. You can specify a single emissive color for the entire material, or use a UV-mapped image texture to use different colors for different parts of the entity. With custom materials, RealityKit doesn’t use ``CustomMaterial/emissiveColor-swift.property`` automatically to render your entity. Call `params.surface().set_emissive_color()` from your surface shader, otherwise RealityKit renders no light emission. The following example assigns a tint color to the ``PhysicallyBasedMaterial/emissiveColor-swift.property`` property, without a texture: ```swift self.emissiveColor = PhysicallyBasedMaterial.EmissiveColor(color: .red) ``` This next example uses a texture to specify the ``PhysicallyBasedMaterial/emissiveColor-swift.property`` property: ```swift if let emissiveResource = try? TextureResource.load(named: "entity_emissive") { let emissiveMap = MaterialParameters.Texture(emissiveResource) material.emissiveColor = .init(texture: emissiveMap) } ``` This Metal code shows how to access the emissive color tint in your shader functions: ```cpp half3 emissiveTint = (half3)params.material_constants().emissive_color(); ``` The following Metal code demonstrates how to sample the emissive color texture for the current fragment: ```cpp // Get the entity's primary texture coordinates. float2 uv = params.geometry().uv0(); // Flip the y-axis. You only need to do this for entities you load from // USDZ or .reality files. uv.y = 1.0 - uv.y; // Sample the emissive color texture to get the value for this fragment. auto tex = params.textures(); half3 emissiveColor = (half3)tex.emissive_color() .sample(textureSampler, uv).rgb; ```

get · iOS 15.0+

lightingModel

TypeScript
get lightingModel(): CustomMaterial_LightingModel
Swift declaration
var lightingModel: CustomMaterial.LightingModel { get }

The lighting model that the material uses. A custom material’s lighting model determines exactly how RealityKit uses the values set in your surface shader’s to render the entity. Custom materials supports the following lighting models: | Lighting Model | Description | Supported Shader Outputs | |-------------- | ----------- | ------------------------ | | `.lit` | Uses physically based rendering techniques, but excludes clearcoat. | All except `set_clearcoat()` and `set_clearcoat_roughness()` | | `.clearcoat` | Uses physically based rendering techniques, including clearcoat. | All | | `.unlit` | Renders without any shading or lighting calculations. The result is similar to using an ``UnlitMaterial``. | Uses `set_emissive_color()` only |

init · iOS 15.0+

init

TypeScript
static initSurfaceShaderGeometryModifierLightingModel(surfaceShader: CustomMaterial_SurfaceShader, geometryModifier: (CustomMaterial_GeometryModifier) | null, lightingModel: CustomMaterial_LightingModel): CustomMaterial
Swift declaration
init(surfaceShader: CustomMaterial.SurfaceShader, geometryModifier: CustomMaterial.GeometryModifier? = nil, lightingModel: CustomMaterial.LightingModel) throws

Creates a custom material from a lighting model, surface shader, and geometry modifier. This initializer creates a custom material using a lighting model you specify, which determines how RealityKit renders the output of your shader functions. The ``CustomMaterial/LightingModel-swift.enum/lit`` and ``CustomMaterial/LightingModel-swift.enum/clearcoat`` use RealityKit’s physically-based shaders to render the entity based on the output of your shader functions. When using these lighting models, RealityKit uses all provided material attributes like ``CustomMaterial/baseColor-swift.property``, ``CustomMaterial/metallic-swift.property`` and ``CustomMaterial/normal-swift.property``. The ``CustomMaterial/LightingModel-swift.enum/unlit`` lighting model renders the entity with no shadows or surface effects. This lighting model only supports ``CustomMaterial/baseColor-swift.property`` and ``CustomMaterial/blending-swift.property``. - Parameters: - surfaceShader: The surface shader function. - geometryModifier: The geometry modifier shader function. - lightingModel: The lighting model.

get · iOS 18.0+

clearcoatNormal

TypeScript
get clearcoatNormal(): CustomMaterial_ClearcoatNormal
Swift declaration
var clearcoatNormal: CustomMaterial.ClearcoatNormal { get set }

Waviness and imperfections for the top clearcoat. An entity in RealityKit can display a clearcoat, which is a separate layer of transparent specular highlights used to simulate a clear coating, like on a car or the surface of lacquered objects. This property allows you to specify a clearcoat normal and add waviness and imperfections to the top clearcoat. This example shows how to set the `clearcoatNormal` using a UV-mapped image: ```swift if let clearcoatNormalTextureResource = try? TextureResource.load(named: "entity_cc_normalMap") { let ccNormalMap = CustomMaterial.Texture(clearcoatNormalTextureResource) material.clearcoatNormal = .init(texture: ccNormalMap) } ``` With custom materials, RealityKit only renders a clearcoat if ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and the material’s surface shader function calls `params.surface().set_clearcoat()`. To specify ``CustomMaterial/clearcoatNormal-swift.property``, your surface shader function also needs to call `params.surface().set_clearcoat_normal()`. The following Metal code demonstrates using ``CustomMaterial/clearcoat-swift.property`` and ``CustomMaterial/clearcoatNormal-swift.property`` in a surface shader, replicating the behavior of the ``PhysicallyBasedMaterial`` shader: ```cpp // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Entities loaded from a USDZ or .reality file use texture coordinates with // a flipped y-axis. This compensates for that. uv.y = 1.0 - uv.y; // Sample a value from the clearcoat normal texture. auto tex = params.textures(); half3 clearcoatNormal = realitykit::unpack_normal(tex.clearcoat_normal().sample(textureSampler, uv).rgb); // assign the result. params.surface().set_clearcoat_normal(clearcoatNormal); params.surface().set_clearcoat(1.0); ```

set · iOS 18.0+

clearcoatNormal

TypeScript
set clearcoatNormal(value: CustomMaterial_ClearcoatNormal)
Swift declaration
var clearcoatNormal: CustomMaterial.ClearcoatNormal { get set }

Waviness and imperfections for the top clearcoat. An entity in RealityKit can display a clearcoat, which is a separate layer of transparent specular highlights used to simulate a clear coating, like on a car or the surface of lacquered objects. This property allows you to specify a clearcoat normal and add waviness and imperfections to the top clearcoat. This example shows how to set the `clearcoatNormal` using a UV-mapped image: ```swift if let clearcoatNormalTextureResource = try? TextureResource.load(named: "entity_cc_normalMap") { let ccNormalMap = CustomMaterial.Texture(clearcoatNormalTextureResource) material.clearcoatNormal = .init(texture: ccNormalMap) } ``` With custom materials, RealityKit only renders a clearcoat if ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and the material’s surface shader function calls `params.surface().set_clearcoat()`. To specify ``CustomMaterial/clearcoatNormal-swift.property``, your surface shader function also needs to call `params.surface().set_clearcoat_normal()`. The following Metal code demonstrates using ``CustomMaterial/clearcoat-swift.property`` and ``CustomMaterial/clearcoatNormal-swift.property`` in a surface shader, replicating the behavior of the ``PhysicallyBasedMaterial`` shader: ```cpp // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Entities loaded from a USDZ or .reality file use texture coordinates with // a flipped y-axis. This compensates for that. uv.y = 1.0 - uv.y; // Sample a value from the clearcoat normal texture. auto tex = params.textures(); half3 clearcoatNormal = realitykit::unpack_normal(tex.clearcoat_normal().sample(textureSampler, uv).rgb); // assign the result. params.surface().set_clearcoat_normal(clearcoatNormal); params.surface().set_clearcoat(1.0); ```

get · iOS 15.0+

ambientOcclusion

TypeScript
get ambientOcclusion(): CustomMaterial_AmbientOcclusion
Swift declaration
var ambientOcclusion: CustomMaterial.AmbientOcclusion { get set }

The ambient light exposure for a material. Ambient occlusion (AO) represents the entity’s exposure to ambient light. Specify ambient occlusion using a UV-mapped image called an _ambient occlusion map_. In an AO map, black pixels represent parts of the model that receive no ambient light because of a crevice, dent, or recessed area, or another part of the entity blocking ambient light from reaching it. White pixels represent flat portions of the model that receive full ambient light. You generate ambient occlusion maps using a 3D software package. The following code loads an ambient occlusion map and adds it to the custom material: ```swift if let aoResource = try? TextureResource.load(named:"entity_ao") { let aoMap = MaterialParameters.Texture(aoResource) material.emissiveColor = .init(texture: aoMap) } ``` In a custom material, RealityKit doesn’t automatically use the value you set on this property to render your entity. The ambient occlusion texture is available in the material’s shader functions, but RealityKit only renders ambient occlusion if the material’s ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/lit`` or ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and its surface shader calls `params.surface().set_ambient_occlusion()`. The following Metal code shows how to sample the ambient occlusion texture to set the AO value in a surface shader function: ```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 ambient occlusion texture and use it to set the // ambient occlusion value to use during rendering. auto tex = params.textures(); half metallic = tex.ambient_occlusion().sample(textureSampler, uv).r; params.surface().set_ambient_occlusion(metallic); ```

set · iOS 15.0+

ambientOcclusion

TypeScript
set ambientOcclusion(value: CustomMaterial_AmbientOcclusion)
Swift declaration
var ambientOcclusion: CustomMaterial.AmbientOcclusion { get set }

The ambient light exposure for a material. Ambient occlusion (AO) represents the entity’s exposure to ambient light. Specify ambient occlusion using a UV-mapped image called an _ambient occlusion map_. In an AO map, black pixels represent parts of the model that receive no ambient light because of a crevice, dent, or recessed area, or another part of the entity blocking ambient light from reaching it. White pixels represent flat portions of the model that receive full ambient light. You generate ambient occlusion maps using a 3D software package. The following code loads an ambient occlusion map and adds it to the custom material: ```swift if let aoResource = try? TextureResource.load(named:"entity_ao") { let aoMap = MaterialParameters.Texture(aoResource) material.emissiveColor = .init(texture: aoMap) } ``` In a custom material, RealityKit doesn’t automatically use the value you set on this property to render your entity. The ambient occlusion texture is available in the material’s shader functions, but RealityKit only renders ambient occlusion if the material’s ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/lit`` or ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and its surface shader calls `params.surface().set_ambient_occlusion()`. The following Metal code shows how to sample the ambient occlusion texture to set the AO value in a surface shader function: ```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 ambient occlusion texture and use it to set the // ambient occlusion value to use during rendering. auto tex = params.textures(); half metallic = tex.ambient_occlusion().sample(textureSampler, uv).r; params.surface().set_ambient_occlusion(metallic); ```

get · iOS 15.0+

opacityThreshold

TypeScript
get opacityThreshold(): (number) | null
Swift declaration
var opacityThreshold: Float? { get set }

The minimum opacity value to treat as fully opaque. In a custom material, `opacityThreshold` helps define how RealityKit renders transparency when using a texture (known as an _alpha map_) to control opacity. This property is available as an input to the material’s surface shader, but RealityKit doesn’t automatically use this value to render your entity. To render an entity transparent, call `params.surface().set_opacity()` from the surface shader. When `opacityThreshold` is set, ``PhysicallyBasedMaterial`` uses the opacity texture as a mask. RealityKit discards pixels with opacity values less than the `opacityThreshold`, and renders opacity values greater than or equal to `opacityThreshold` fully opaque. The following Metal code replicates the behavior of the ``PhysicallyBasedMaterial`` shaders: ```cpp // Retrieve the threshold from the CustomMaterial. float opacityThreshold = params.material_constants().opacity_threshold(); // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Entities loaded from USDZ or .reality files use texture coordinates with // a flipped y-axis. This adjusts for that. uv.y = 1.0 - uv.y; // Retrieve the opacity texture from the material. auto tex = params.textures(); // Sample the value from the opacity texture. half opacity = tex.opacity().sample(textureSampler, uv).r; // When the opacity threshold is used, set the opacity to either // 1.0 or 0.0 depending on the value of the opacity threshold for // the masking behavior. opacity = (opacity <= opacityThreshold) ? 0.0 : 1.0; // Use the calculated value to set the opacity for rendering. params.surface().set_opacity(opacity); ```

set · iOS 15.0+

opacityThreshold

TypeScript
set opacityThreshold(value: (number) | null)
Swift declaration
var opacityThreshold: Float? { get set }

The minimum opacity value to treat as fully opaque. In a custom material, `opacityThreshold` helps define how RealityKit renders transparency when using a texture (known as an _alpha map_) to control opacity. This property is available as an input to the material’s surface shader, but RealityKit doesn’t automatically use this value to render your entity. To render an entity transparent, call `params.surface().set_opacity()` from the surface shader. When `opacityThreshold` is set, ``PhysicallyBasedMaterial`` uses the opacity texture as a mask. RealityKit discards pixels with opacity values less than the `opacityThreshold`, and renders opacity values greater than or equal to `opacityThreshold` fully opaque. The following Metal code replicates the behavior of the ``PhysicallyBasedMaterial`` shaders: ```cpp // Retrieve the threshold from the CustomMaterial. float opacityThreshold = params.material_constants().opacity_threshold(); // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Entities loaded from USDZ or .reality files use texture coordinates with // a flipped y-axis. This adjusts for that. uv.y = 1.0 - uv.y; // Retrieve the opacity texture from the material. auto tex = params.textures(); // Sample the value from the opacity texture. half opacity = tex.opacity().sample(textureSampler, uv).r; // When the opacity threshold is used, set the opacity to either // 1.0 or 0.0 depending on the value of the opacity threshold for // the masking behavior. opacity = (opacity <= opacityThreshold) ? 0.0 : 1.0; // Use the calculated value to set the opacity for rendering. params.surface().set_opacity(opacity); ```

get · iOS 18.0+

triangleFillMode

TypeScript
get triangleFillMode(): MaterialParameterTypes_TriangleFillMode
Swift declaration
var triangleFillMode: CustomMaterial.TriangleFillMode { get set }

The object that controls how RealityKit draws triangles. A value of ``MaterialParameterTypes/TriangleFillMode/fill`` causes RealityKit to draw triangles normally, while a value of ``MaterialParameterTypes/TriangleFillMode/lines`` turns on wireframe rendering.

set · iOS 18.0+

triangleFillMode

TypeScript
set triangleFillMode(value: MaterialParameterTypes_TriangleFillMode)
Swift declaration
var triangleFillMode: CustomMaterial.TriangleFillMode { get set }

The object that controls how RealityKit draws triangles. A value of ``MaterialParameterTypes/TriangleFillMode/fill`` causes RealityKit to draw triangles normally, while a value of ``MaterialParameterTypes/TriangleFillMode/lines`` turns on wireframe rendering.

get · iOS 15.0+

clearcoatRoughness

TypeScript
get clearcoatRoughness(): CustomMaterial_ClearcoatRoughness
Swift declaration
var clearcoatRoughness: CustomMaterial.ClearcoatRoughness { get set }

The degree to which an entity’s clear, shiny coating scatters light to create soft highlights. An entity in RealityKit can display a clearcoat, which is a separate layer of transparent specular highlights used to simulate a clear coating, like on a car or the surface of lacquered objects. This property allows you to specify a clearcoat roughness value to indicate how much the clearcoat scatters light that bounces off of it, which softens and disperses the highlights. You can specify a single value that applies to the entire material, or you can supply a UV-mapped image texture containing different roughness values for different parts of the entity. This value is available in your surface shader. RealityKit won’t render a clearcoat with roughness unless your surface shader calls both `params.surface().set_clearcoat_roughness()` and `params.surface().set_clearcoat()` with a value greater than `0.0`. The following Swift code demonstrates setting the `clearcoatRoughness` using a single value: ```swift material.clearcoatRoughness = .init(floatLiteral: 0.5) ``` This example shows how to set the `clearcoatRoughness` using a UV-mapped image: ```swift if let clearcoatRoughnessResource = try? TextureResource.load(named: "entity_cc_roughness") { let ccRoughnessMap = MaterialParameters.Texture(clearcoatRoughnessResource) material.clearcoat = .init(texture: ccRoughnessMap) } ``` With custom materials, RealityKit only renders a clearcoat if ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and the material’s surface shader function calls `params.surface().set_clearcoat()`. To specify ``CustomMaterial/clearcoatRoughness-swift.property``, your surface shader function needs to also call `params.surface().set_clearcoat_roughness()`. The following Metal code demonstrates using ``CustomMaterial/clearcoat-swift.property`` and ``CustomMaterial/clearcoatRoughness-swift.property`` in a surface shader, replicating the behavior of the ``PhysicallyBasedMaterial`` shader: ```cpp // Retrieve the clearcoat scale and roughness from the CustomMaterial. float clearcoatScale = params.material_constants().clearcoat_scale(); float clearcoatRoughnessScale = params.material_constants().clearcoat_roughness_scale(); // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Entities loaded from a USDZ or .reality file use texture coordinates with // a flipped y-axis. This compensates for that. uv.y = 1.0 - uv.y; // Sample a value from the clearcoat and clearcoat roughness textures. auto tex = params.textures(); half clearcoat = tex.clearcoat().sample(textureSampler, uv).r; half clearcoatRoughness = tex.clearcoat_roughness().sample(textureSampler, uv).r; // Multiply the scale and sampled texture value from the clearcoat and // assign the result. clearcoat *= clearcoatScale; params.surface().set_clearcoat(clearcoat); // Multiply the scale and sampled texture value from the clearcoat roughness // and assign the result. clearcoatRoughness *= clearcoatRoughnessScale; params.surface().set_clearcoat_roughness(clearcoatRoughness); ```

set · iOS 15.0+

clearcoatRoughness

TypeScript
set clearcoatRoughness(value: CustomMaterial_ClearcoatRoughness)
Swift declaration
var clearcoatRoughness: CustomMaterial.ClearcoatRoughness { get set }

The degree to which an entity’s clear, shiny coating scatters light to create soft highlights. An entity in RealityKit can display a clearcoat, which is a separate layer of transparent specular highlights used to simulate a clear coating, like on a car or the surface of lacquered objects. This property allows you to specify a clearcoat roughness value to indicate how much the clearcoat scatters light that bounces off of it, which softens and disperses the highlights. You can specify a single value that applies to the entire material, or you can supply a UV-mapped image texture containing different roughness values for different parts of the entity. This value is available in your surface shader. RealityKit won’t render a clearcoat with roughness unless your surface shader calls both `params.surface().set_clearcoat_roughness()` and `params.surface().set_clearcoat()` with a value greater than `0.0`. The following Swift code demonstrates setting the `clearcoatRoughness` using a single value: ```swift material.clearcoatRoughness = .init(floatLiteral: 0.5) ``` This example shows how to set the `clearcoatRoughness` using a UV-mapped image: ```swift if let clearcoatRoughnessResource = try? TextureResource.load(named: "entity_cc_roughness") { let ccRoughnessMap = MaterialParameters.Texture(clearcoatRoughnessResource) material.clearcoat = .init(texture: ccRoughnessMap) } ``` With custom materials, RealityKit only renders a clearcoat if ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and the material’s surface shader function calls `params.surface().set_clearcoat()`. To specify ``CustomMaterial/clearcoatRoughness-swift.property``, your surface shader function needs to also call `params.surface().set_clearcoat_roughness()`. The following Metal code demonstrates using ``CustomMaterial/clearcoat-swift.property`` and ``CustomMaterial/clearcoatRoughness-swift.property`` in a surface shader, replicating the behavior of the ``PhysicallyBasedMaterial`` shader: ```cpp // Retrieve the clearcoat scale and roughness from the CustomMaterial. float clearcoatScale = params.material_constants().clearcoat_scale(); float clearcoatRoughnessScale = params.material_constants().clearcoat_roughness_scale(); // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Entities loaded from a USDZ or .reality file use texture coordinates with // a flipped y-axis. This compensates for that. uv.y = 1.0 - uv.y; // Sample a value from the clearcoat and clearcoat roughness textures. auto tex = params.textures(); half clearcoat = tex.clearcoat().sample(textureSampler, uv).r; half clearcoatRoughness = tex.clearcoat_roughness().sample(textureSampler, uv).r; // Multiply the scale and sampled texture value from the clearcoat and // assign the result. clearcoat *= clearcoatScale; params.surface().set_clearcoat(clearcoat); // Multiply the scale and sampled texture value from the clearcoat roughness // and assign the result. clearcoatRoughness *= clearcoatRoughnessScale; params.surface().set_clearcoat_roughness(clearcoatRoughness); ```

get · iOS 15.0+

textureCoordinateTransform

TypeScript
get textureCoordinateTransform(): MaterialParameterTypes_TextureCoordinateTransform
Swift declaration
var textureCoordinateTransform: CustomMaterial.TextureCoordinateTransform { get set }

A two-dimensional transformation RealityKit applies to the entity’s primary texture coordinates. An entity’s UV texture coordinates control how RealityKit materials map image textures onto an entity. Use this property to transform the texture coordinates and change the way this material maps its textures. For example, you might change the scale of the UV coordinates to apply a tiled, repeating pattern to the surface of your entity, or continuously rotate or translate the texture coordinates to animate materials and create special effects, such as fire or flowing liquids. The following example shows how to set a material’s UV transformation: ```swift let rotationRadians = Float(45.0) * .pi / 180 // 45 degrees converted to radians. material.textureCoordinateTransform = .init( offset: [0.5, 0.5], scale: [0.5, 0.5], rotation: rotationRadians ) ``` The material’s shader function doesn’t have to do anything to apply the transformation. When the shader calls `params.geometry().uv1()`, RealityKit already transforms the returned coordinates.

set · iOS 15.0+

textureCoordinateTransform

TypeScript
set textureCoordinateTransform(value: MaterialParameterTypes_TextureCoordinateTransform)
Swift declaration
var textureCoordinateTransform: CustomMaterial.TextureCoordinateTransform { get set }

A two-dimensional transformation RealityKit applies to the entity’s primary texture coordinates. An entity’s UV texture coordinates control how RealityKit materials map image textures onto an entity. Use this property to transform the texture coordinates and change the way this material maps its textures. For example, you might change the scale of the UV coordinates to apply a tiled, repeating pattern to the surface of your entity, or continuously rotate or translate the texture coordinates to animate materials and create special effects, such as fire or flowing liquids. The following example shows how to set a material’s UV transformation: ```swift let rotationRadians = Float(45.0) * .pi / 180 // 45 degrees converted to radians. material.textureCoordinateTransform = .init( offset: [0.5, 0.5], scale: [0.5, 0.5], rotation: rotationRadians ) ``` The material’s shader function doesn’t have to do anything to apply the transformation. When the shader calls `params.geometry().uv1()`, RealityKit already transforms the returned coordinates.

get · iOS 26.0+

supportsMutableUniformsResources

TypeScript
static get supportsMutableUniformsResources(): boolean
Swift declaration
static var supportsMutableUniformsResources: Bool

Whether the current device supports resource storage within the WithMutableUniforms API. Ensure this is true before setting resources such as textures and buffers on `CustomMaterial.ResourceStorage`

set · iOS 26.0+

supportsMutableUniformsResources

TypeScript
static set supportsMutableUniformsResources(value: boolean)
Swift declaration
static var supportsMutableUniformsResources: Bool

Whether the current device supports resource storage within the WithMutableUniforms API. Ensure this is true before setting resources such as textures and buffers on `CustomMaterial.ResourceStorage`

get · iOS 15.0+

secondaryTextureCoordinateTransform

TypeScript
get secondaryTextureCoordinateTransform(): MaterialParameterTypes_TextureCoordinateTransform
Swift declaration
var secondaryTextureCoordinateTransform: CustomMaterial.TextureCoordinateTransform { get set }

A two-dimensional transformation RealityKit applies to the entity’s secondary texture coordinates. An entity’s UV texture coordinates define how RealityKit maps image textures onto an entity. Use this property to transform the secondary texture coordinates and change the way this material maps textures onto an entity. If an entity has multiple materials assigned to it, the transformation doesn’t affect how the other materials map their textures. For example, you might change the scale of the UV coordinates to apply a tiled, repeating pattern to the surface of your entity, or continuously rotate or translate the texture coordinates to animate materials and create special effects, such as fire or flowing liquids. The following example demonstrates how to set a material’s UV transformation: ```swift let rotationRadians = Float(45.0) * .pi / 180 // 45 degrees converted to radians. secondaryTextureCoordinateTransform = .init( offset: [0.5, 0.5], scale: [0.5, 0.5], rotation: rotationRadians ) ``` The material’s shader function doesn’t have to do anything to apply the transformation. When the shader calls `params.geometry().uv1()`, RealityKit already transforms the returned coordinates.

set · iOS 15.0+

secondaryTextureCoordinateTransform

TypeScript
set secondaryTextureCoordinateTransform(value: MaterialParameterTypes_TextureCoordinateTransform)
Swift declaration
var secondaryTextureCoordinateTransform: CustomMaterial.TextureCoordinateTransform { get set }

A two-dimensional transformation RealityKit applies to the entity’s secondary texture coordinates. An entity’s UV texture coordinates define how RealityKit maps image textures onto an entity. Use this property to transform the secondary texture coordinates and change the way this material maps textures onto an entity. If an entity has multiple materials assigned to it, the transformation doesn’t affect how the other materials map their textures. For example, you might change the scale of the UV coordinates to apply a tiled, repeating pattern to the surface of your entity, or continuously rotate or translate the texture coordinates to animate materials and create special effects, such as fire or flowing liquids. The following example demonstrates how to set a material’s UV transformation: ```swift let rotationRadians = Float(45.0) * .pi / 180 // 45 degrees converted to radians. secondaryTextureCoordinateTransform = .init( offset: [0.5, 0.5], scale: [0.5, 0.5], rotation: rotationRadians ) ``` The material’s shader function doesn’t have to do anything to apply the transformation. When the shader calls `params.geometry().uv1()`, RealityKit already transforms the returned coordinates.

init · iOS 15.0+

init

TypeScript
static initFromSurfaceShaderGeometryModifier(material: SDKHandle, surfaceShader: CustomMaterial_SurfaceShader, geometryModifier?: (CustomMaterial_GeometryModifier) | null): CustomMaterial
Swift declaration
init(from material: any Material, surfaceShader: CustomMaterial.SurfaceShader, geometryModifier: CustomMaterial.GeometryModifier? = nil) throws

Creates a custom material from an existing material, surface shader, and geometry modifier. Use this initializer to create a custom material with the same properties as another existing material, but with a geometry modifier and surface shader. - Parameters: - material: The material from which to copy properties. - surfaceShader: The surface shader function. - geometryModifier: The geometry modifier shader function.

init · iOS 15.0+

init

TypeScript
static initFromGeometryModifier(material: SDKHandle, geometryModifier: CustomMaterial_GeometryModifier): CustomMaterial
Swift declaration
init(from material: any Material, geometryModifier: CustomMaterial.GeometryModifier) throws

Creates a custom material from an existing material and a geometry modifier. Use this initializer to create a custom material with the same properties as another existing material, but with a geometry modifier. - Parameters: - material: The material on which to base the custom material. - geometryModifier: The geometry modifier shader function.

get · iOS 15.0+

custom

TypeScript
get custom(): CustomMaterial_Custom
Swift declaration
var custom: CustomMaterial.Custom { get set }

User-defined properties for the material’s shader functions. Use a ``CustomMaterial/Custom-swift.struct`` object to send custom data to your shader functions. A custom object can hold a texture or a vector value, or both. Both the texture and vector value are available in your shader functions. - Note: Unlike other ``CustomMaterial`` properties, you don’t need to create a ``CustomMaterial/Custom-swift.struct`` object for your material. All ``CustomMaterial`` objects have one by default; you just need to set the ``CustomMaterial/Custom-swift.struct/value`` property, ``CustomMaterial/Custom-swift.struct/texture`` property, or both. The following code demonstrates how to use the custom property to pass a vector to your shader functions: ```swift // Specify a custom vector to pass to the shader functions. customMaterial.custom.value = [0.25, 0.25, 0.25, 1.0] ``` You can also use it to pass up to four scalar values instead of a vector: ```swift let customValue1: Float = 0.25 let customValue2: Float = 0.75 customMaterial.custom.value[0] = customValue1 customMaterial.custom.value[1] = customValue2 ``` The custom property can also include a texture. The following code demonstrates how to add a texture to the custom property: ```swift if let theResource = try? TextureResource.load(named: "MyCustomTexture") { let myTexture = CustomMaterial.Texture(theResource) customMaterial.custom.texture = .init(myTexture) } ``` The following Metal code shows how to retrieve the custom vector in a shader function: ```cpp float4 myCustomVector = params.uniforms().custom_parameter(); ``` The following Metal code shows how to retrieve individual values from the custom vector in your shader functions: ```cpp float firstCustomValue = params.uniforms().custom_parameter()[0]; float secondCustomValue = params.uniforms().custom_parameter()[1]; ``` Here’s how to retrieve the custom texture in your shader functions: ```cpp float voronoiColor = params.textures() .custom().sample(textureSampler, UV).r; ```

set · iOS 15.0+

custom

TypeScript
set custom(value: CustomMaterial_Custom)
Swift declaration
var custom: CustomMaterial.Custom { get set }

User-defined properties for the material’s shader functions. Use a ``CustomMaterial/Custom-swift.struct`` object to send custom data to your shader functions. A custom object can hold a texture or a vector value, or both. Both the texture and vector value are available in your shader functions. - Note: Unlike other ``CustomMaterial`` properties, you don’t need to create a ``CustomMaterial/Custom-swift.struct`` object for your material. All ``CustomMaterial`` objects have one by default; you just need to set the ``CustomMaterial/Custom-swift.struct/value`` property, ``CustomMaterial/Custom-swift.struct/texture`` property, or both. The following code demonstrates how to use the custom property to pass a vector to your shader functions: ```swift // Specify a custom vector to pass to the shader functions. customMaterial.custom.value = [0.25, 0.25, 0.25, 1.0] ``` You can also use it to pass up to four scalar values instead of a vector: ```swift let customValue1: Float = 0.25 let customValue2: Float = 0.75 customMaterial.custom.value[0] = customValue1 customMaterial.custom.value[1] = customValue2 ``` The custom property can also include a texture. The following code demonstrates how to add a texture to the custom property: ```swift if let theResource = try? TextureResource.load(named: "MyCustomTexture") { let myTexture = CustomMaterial.Texture(theResource) customMaterial.custom.texture = .init(myTexture) } ``` The following Metal code shows how to retrieve the custom vector in a shader function: ```cpp float4 myCustomVector = params.uniforms().custom_parameter(); ``` The following Metal code shows how to retrieve individual values from the custom vector in your shader functions: ```cpp float firstCustomValue = params.uniforms().custom_parameter()[0]; float secondCustomValue = params.uniforms().custom_parameter()[1]; ``` Here’s how to retrieve the custom texture in your shader functions: ```cpp float voronoiColor = params.textures() .custom().sample(textureSampler, UV).r; ```

get · iOS 15.0+

normal

TypeScript
get normal(): CustomMaterial_Normal
Swift declaration
var normal: CustomMaterial.Normal { get set }

A texture map that stores fine surface details for the entity. _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, ``CustomMaterial/normal-swift.property`` is only used when ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/lit`` or ``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-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 <doc:modifying-realitykit-rendering-using-custom-materials>.

set · iOS 15.0+

normal

TypeScript
set normal(value: CustomMaterial_Normal)
Swift declaration
var normal: CustomMaterial.Normal { get set }

A texture map that stores fine surface details for the entity. _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, ``CustomMaterial/normal-swift.property`` is only used when ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/lit`` or ``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-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 <doc:modifying-realitykit-rendering-using-custom-materials>.

init · iOS 18.0+

init

TypeScript
static initProgram(program: CustomMaterial_Program): CustomMaterial
Swift declaration
init(program: CustomMaterial.Program)
get · iOS 18.0+

program

TypeScript
get program(): CustomMaterial_Program
Swift declaration
var program: CustomMaterial.Program { get set }
set · iOS 18.0+

program

TypeScript
set program(value: CustomMaterial_Program)
Swift declaration
var program: CustomMaterial.Program { get set }
get · iOS 15.0+

blending

TypeScript
get blending(): CustomMaterial_Blending
Swift declaration
var blending: CustomMaterial.Blending { get set }

The transparency of an entity.

set · iOS 15.0+

blending

TypeScript
set blending(value: CustomMaterial_Blending)
Swift declaration
var blending: CustomMaterial.Blending { get set }

The transparency of an entity.

get · iOS 15.0+

metallic

TypeScript
get metallic(): CustomMaterial_Metallic
Swift declaration
var metallic: CustomMaterial.Metallic { get set }

The reflectiveness of an entity. In physically based rendering, the `metallic` property represents the reflectiveness of an entity. Use this property to specify whether the entity displays metallic qualities and reflects the surrounding environment, or displays dielectric qualities and doesn’t reflect the environment. With custom materials, RealityKit doesn’t automatically use the values set on this property. To render a custom material using the metallic property, set ``CustomMaterial/lightingModel-swift.property`` to ``CustomMaterial/LightingModel-swift.enum/lit`` or ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and call `params.surface().set_roughness()` from its surface shader. ![An illustration showing two spheres rendered in RealityKit. The sphere on the left is shiny but dielecric so doesn’t reflect the surrounding environment other than specular highlights from the visible light. The sphere on the right is metallic and reflects all of the surrounding environment like a mirror ball.](CustomMaterial-metallic-swift-property-1) The following Swift code shows how to use an image and a scale to specify roughness: ```swift if let metallicResource = try? TextureResource.load(named:"entity_metallic") { let metallic = MaterialParameters.Texture(metallicResource) material.metallic = PhysicallyBasedMaterial.Metallic(scale: 1.0, texture:metallic) } ``` The following surface shader takes the scale and texture values from the ``CustomMaterial/metallic-swift.property`` property, multiplies them together, and uses the result to specify the metallic value for rendering, which emulates the behavior of ``PhysicallyBasedMaterial``. ```cpp #include <metal_stdlib> #include <RealityKit/RealityKit.h> using namespace metal; // Use samplers to retrieve a color value from a texture based on // the entity's UV coordinates. Samplers can be reused with different textures. // Surface shader functions should define no more than eight samplers. constexpr sampler textureSampler(address::clamp_to_edge, filter::bicubic); [[visible]] void mySurfaceShader(realitykit::surface_parameters params) { // Retrieve the metallic scale from the CustomMaterial. float metallicScale = params.material_constants().metallic_scale(); // 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 metallic texture based on the UV coordinates. auto tex = params.textures(); half metallic = tex.metallic().sample(textureSampler, uv).r; // Multiply the tint and the sampled value from the texture, // and assign the result to the shader's metallic property. metallic *= metallicScale; params.surface().set_metallic(metallic); } ``` For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

set · iOS 15.0+

metallic

TypeScript
set metallic(value: CustomMaterial_Metallic)
Swift declaration
var metallic: CustomMaterial.Metallic { get set }

The reflectiveness of an entity. In physically based rendering, the `metallic` property represents the reflectiveness of an entity. Use this property to specify whether the entity displays metallic qualities and reflects the surrounding environment, or displays dielectric qualities and doesn’t reflect the environment. With custom materials, RealityKit doesn’t automatically use the values set on this property. To render a custom material using the metallic property, set ``CustomMaterial/lightingModel-swift.property`` to ``CustomMaterial/LightingModel-swift.enum/lit`` or ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and call `params.surface().set_roughness()` from its surface shader. ![An illustration showing two spheres rendered in RealityKit. The sphere on the left is shiny but dielecric so doesn’t reflect the surrounding environment other than specular highlights from the visible light. The sphere on the right is metallic and reflects all of the surrounding environment like a mirror ball.](CustomMaterial-metallic-swift-property-1) The following Swift code shows how to use an image and a scale to specify roughness: ```swift if let metallicResource = try? TextureResource.load(named:"entity_metallic") { let metallic = MaterialParameters.Texture(metallicResource) material.metallic = PhysicallyBasedMaterial.Metallic(scale: 1.0, texture:metallic) } ``` The following surface shader takes the scale and texture values from the ``CustomMaterial/metallic-swift.property`` property, multiplies them together, and uses the result to specify the metallic value for rendering, which emulates the behavior of ``PhysicallyBasedMaterial``. ```cpp #include <metal_stdlib> #include <RealityKit/RealityKit.h> using namespace metal; // Use samplers to retrieve a color value from a texture based on // the entity's UV coordinates. Samplers can be reused with different textures. // Surface shader functions should define no more than eight samplers. constexpr sampler textureSampler(address::clamp_to_edge, filter::bicubic); [[visible]] void mySurfaceShader(realitykit::surface_parameters params) { // Retrieve the metallic scale from the CustomMaterial. float metallicScale = params.material_constants().metallic_scale(); // 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 metallic texture based on the UV coordinates. auto tex = params.textures(); half metallic = tex.metallic().sample(textureSampler, uv).r; // Multiply the tint and the sampled value from the texture, // and assign the result to the shader's metallic property. metallic *= metallicScale; params.surface().set_metallic(metallic); } ``` For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

get · iOS 15.0+

specular

TypeScript
get specular(): CustomMaterial_Specular
Swift declaration
var specular: CustomMaterial.Specular { get set }

The bright highlights to apply to the entity. In physically based rendering (PBR), specular highlights primarily come from the object’s ``PhysicallyBasedMaterial/roughness-swift.property`` value. RealityKit renders materials that have a low roughness value with specular highlights based on the environment, lighting, and shape of the entity. As a result, for most materials, you don’t need to specify a `specular` value. For some types of dielectric (nonmetallic) materials, like facet-cut glass or gems, PBR algorithms don’t create bright enough specular highlights using just roughness. To accurately simulate those types of materials, the ``PhysicallyBasedMaterial/specular-swift.property`` property allows you to specify additional specularity for the entity. The following example demonstrates how to add specularity using a single value for the entire material: ```swift material.specular = .init(floatLiteral: 0.8) ``` The following code shows how to add specularity using a UV-mapped image texture: ```swift if let specularResource = try? TextureResource.load(named: "entity_specular") { let specularMap = MaterialParameters.Texture(specularResource) material.specular = .init(texture: specularMap) } ``` With custom materials, the specular ``CustomMaterial/Specular-swift.struct/scale`` and ``CustomMaterial/Specular-swift.struct/texture`` are available to the material’s shader functions, but RealityKit doesn’t automatically use the values you set. To render a custom material with additional specular highlights, set ``CustomMaterial/lightingModel-swift.property`` to ``CustomMaterial/LightingModel-swift.enum/lit`` or ``CustomMaterial/LightingModel-swift.enum/clearcoat``, and call `params().surface().set_specular()` from its surface shader. The following Metal code demonstrates using the specular scale and texture values, simulating the behavior of the shaders that render a ``PhysicallyBasedMaterial``: ```cpp // Retrieve the opacity scale from the CustomMaterial. float specularScale = params.material_constants().specular_scale(); // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Entities loaded from a USDZ or .reality file use texture coordinates // with a flipped y-axis. This compensates for that. uv.y = 1.0 - uv.y; // Sample the specular texture. auto tex = params.textures(); half specular = tex.specular().sample(textureSampler, uv).r; // Multiply the tint and the sampled value from the texture and assign // the result. specular *= specularScale; params.surface().set_specular(specular); ``` For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

set · iOS 15.0+

specular

TypeScript
set specular(value: CustomMaterial_Specular)
Swift declaration
var specular: CustomMaterial.Specular { get set }

The bright highlights to apply to the entity. In physically based rendering (PBR), specular highlights primarily come from the object’s ``PhysicallyBasedMaterial/roughness-swift.property`` value. RealityKit renders materials that have a low roughness value with specular highlights based on the environment, lighting, and shape of the entity. As a result, for most materials, you don’t need to specify a `specular` value. For some types of dielectric (nonmetallic) materials, like facet-cut glass or gems, PBR algorithms don’t create bright enough specular highlights using just roughness. To accurately simulate those types of materials, the ``PhysicallyBasedMaterial/specular-swift.property`` property allows you to specify additional specularity for the entity. The following example demonstrates how to add specularity using a single value for the entire material: ```swift material.specular = .init(floatLiteral: 0.8) ``` The following code shows how to add specularity using a UV-mapped image texture: ```swift if let specularResource = try? TextureResource.load(named: "entity_specular") { let specularMap = MaterialParameters.Texture(specularResource) material.specular = .init(texture: specularMap) } ``` With custom materials, the specular ``CustomMaterial/Specular-swift.struct/scale`` and ``CustomMaterial/Specular-swift.struct/texture`` are available to the material’s shader functions, but RealityKit doesn’t automatically use the values you set. To render a custom material with additional specular highlights, set ``CustomMaterial/lightingModel-swift.property`` to ``CustomMaterial/LightingModel-swift.enum/lit`` or ``CustomMaterial/LightingModel-swift.enum/clearcoat``, and call `params().surface().set_specular()` from its surface shader. The following Metal code demonstrates using the specular scale and texture values, simulating the behavior of the shaders that render a ``PhysicallyBasedMaterial``: ```cpp // Retrieve the opacity scale from the CustomMaterial. float specularScale = params.material_constants().specular_scale(); // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Entities loaded from a USDZ or .reality file use texture coordinates // with a flipped y-axis. This compensates for that. uv.y = 1.0 - uv.y; // Sample the specular texture. auto tex = params.textures(); half specular = tex.specular().sample(textureSampler, uv).r; // Multiply the tint and the sampled value from the texture and assign // the result. specular *= specularScale; params.surface().set_specular(specular); ``` For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

get · iOS 15.0+

baseColor

TypeScript
get baseColor(): CustomMaterial_BaseColor
Swift declaration
var baseColor: CustomMaterial.BaseColor { get set }

The color of an entity unmodified by lighting. In physically based rendering, the base color of an entity is its color before RealityKit applies any lighting calculations or other rendering calculations to it. With custom materials, the base color `texture` and `tint` are available as inputs in your surface shader. With custom materials, RealityKit doesn’t automatically use the values set on the ``CustomMaterial/baseColor-swift.property`` property. The material’s surface shader is responsible for calculating or setting the actual base color value for rendering by calling `params.surface().set_base_color()`. The following code shows how to create a base color from a tint color and a texture, and then assign it to a custom material: ```swift // Load entity_basecolor.jpg from the app's bundle. if let baseResource = try? TextureResource.load(named: "entity_basecolor") { let baseColor = CustomMaterial.Texture(baseResource) customMaterial.baseColor = CustomMaterial.BaseColor(tint: .blue, texture:baseColor) } ``` In your surface shader, you can access the `tint` of the material’s base color property by calling `params.material_constants().base_color_tint()`. You can access the texture by calling `params.textures().base_color()`. The following surface shader function takes the tint and texture values from the ``CustomMaterial/baseColor-swift.property`` property, multiplies them together, and sets the resulting value as the base color for rendering, which emulates the behavior of ``PhysicallyBasedMaterial``: ```cpp #include <metal_stdlib> #include <RealityKit/RealityKit.h> using namespace metal; // Use samplers to retrieve a color value from a texture based on // UV coordinates. Samplers can be reused with different textures. // RealityKit reserves eight samplers for itself, so surface shaders should // never define more than eight samplers. constexpr sampler textureSampler(address::clamp_to_edge, filter::bicubic); [[visible]] void mySurfaceShader(realitykit::surface_parameters params) { // Retrieve the base color tint from the CustomMaterial. half3 baseColorTint = (half3)params.material_constants().base_color_tint(); // Sample a value from the CustomMaterial's base color texture // using the entity's UV coordinates. auto uv = params.geometry().uv0(); auto tex = params.textures(); half3 color = (half3)tex.base_color().sample(textureSampler, uv).rgb; // Multiply the tint and color sampled from the base color texture and // assign the result to the shader's base color property. color *= baseColorTint; params.surface().set_base_color(color); } ``` For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

set · iOS 15.0+

baseColor

TypeScript
set baseColor(value: CustomMaterial_BaseColor)
Swift declaration
var baseColor: CustomMaterial.BaseColor { get set }

The color of an entity unmodified by lighting. In physically based rendering, the base color of an entity is its color before RealityKit applies any lighting calculations or other rendering calculations to it. With custom materials, the base color `texture` and `tint` are available as inputs in your surface shader. With custom materials, RealityKit doesn’t automatically use the values set on the ``CustomMaterial/baseColor-swift.property`` property. The material’s surface shader is responsible for calculating or setting the actual base color value for rendering by calling `params.surface().set_base_color()`. The following code shows how to create a base color from a tint color and a texture, and then assign it to a custom material: ```swift // Load entity_basecolor.jpg from the app's bundle. if let baseResource = try? TextureResource.load(named: "entity_basecolor") { let baseColor = CustomMaterial.Texture(baseResource) customMaterial.baseColor = CustomMaterial.BaseColor(tint: .blue, texture:baseColor) } ``` In your surface shader, you can access the `tint` of the material’s base color property by calling `params.material_constants().base_color_tint()`. You can access the texture by calling `params.textures().base_color()`. The following surface shader function takes the tint and texture values from the ``CustomMaterial/baseColor-swift.property`` property, multiplies them together, and sets the resulting value as the base color for rendering, which emulates the behavior of ``PhysicallyBasedMaterial``: ```cpp #include <metal_stdlib> #include <RealityKit/RealityKit.h> using namespace metal; // Use samplers to retrieve a color value from a texture based on // UV coordinates. Samplers can be reused with different textures. // RealityKit reserves eight samplers for itself, so surface shaders should // never define more than eight samplers. constexpr sampler textureSampler(address::clamp_to_edge, filter::bicubic); [[visible]] void mySurfaceShader(realitykit::surface_parameters params) { // Retrieve the base color tint from the CustomMaterial. half3 baseColorTint = (half3)params.material_constants().base_color_tint(); // Sample a value from the CustomMaterial's base color texture // using the entity's UV coordinates. auto uv = params.geometry().uv0(); auto tex = params.textures(); half3 color = (half3)tex.base_color().sample(textureSampler, uv).rgb; // Multiply the tint and color sampled from the base color texture and // assign the result to the shader's base color property. color *= baseColorTint; params.surface().set_base_color(color); } ``` For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

get · iOS 15.0+

clearcoat

TypeScript
get clearcoat(): CustomMaterial_Clearcoat
Swift declaration
var clearcoat: CustomMaterial.Clearcoat { get set }

The transparent highlights that simulate a clear, shiny coating on an entity. An entity in RealityKit can display a clearcoat, which is a separate layer of transparent specular highlights used to simulate a clear coating, like on a car or the surface of lacquered objects. This property allows you to specify ``PhysicallyBasedMaterial/clearcoat-swift.property`` using a single `Float` that applies to the entire material, or a UV-mapped grayscale image to provide different values for different parts of an entity. The following example specifies `clearcoat` using a single value: ```swift material.clearcoat = .init(floatLiteral: 0.8) ``` This example shows how to specify `clearcoat` using a UV-mapped image texture: ```swift if let clearcoatResource = try? TextureResource.load(named: "entity_clearcoat") { let clearcoatMap = MaterialParameters.Texture(clearcoatResource) material.clearcoat = .init(texture: clearcoatMap) } ``` With custom materials, RealityKit doesn’t automatically use the values you set for this property to render your entity. The values from this property are available to the custom material’s surface shader, but it doesn’t render a clearcoat unless the custom material’s ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and the surface shader calls `params.surface().set_clearcoat()`. The following Metal code demonstrates how to retrieve the scale and texture from this property, and use them to enable clearcoat rendering. ```cpp // Retrieve the clearcoat scale from the CustomMaterial. float clearcoatScale = params.material_constants().clearcoat_scale(); // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Models loaded from USDZ or .reality files use texture coordinates with a // flipped y-axis. This compensates for that. uv.y = 1.0 - uv.y; // Sample the clearcoat texture using the texture coordinates. auto tex = params.textures(); half clearcoat = tex.clearcoat().sample(textureSampler, uv).r; // Multiply the scale and sampled value from the texture, and assign // the result. clearcoat *= clearcoatScale; params.surface().set_clearcoat(clearcoat); ```

set · iOS 15.0+

clearcoat

TypeScript
set clearcoat(value: CustomMaterial_Clearcoat)
Swift declaration
var clearcoat: CustomMaterial.Clearcoat { get set }

The transparent highlights that simulate a clear, shiny coating on an entity. An entity in RealityKit can display a clearcoat, which is a separate layer of transparent specular highlights used to simulate a clear coating, like on a car or the surface of lacquered objects. This property allows you to specify ``PhysicallyBasedMaterial/clearcoat-swift.property`` using a single `Float` that applies to the entire material, or a UV-mapped grayscale image to provide different values for different parts of an entity. The following example specifies `clearcoat` using a single value: ```swift material.clearcoat = .init(floatLiteral: 0.8) ``` This example shows how to specify `clearcoat` using a UV-mapped image texture: ```swift if let clearcoatResource = try? TextureResource.load(named: "entity_clearcoat") { let clearcoatMap = MaterialParameters.Texture(clearcoatResource) material.clearcoat = .init(texture: clearcoatMap) } ``` With custom materials, RealityKit doesn’t automatically use the values you set for this property to render your entity. The values from this property are available to the custom material’s surface shader, but it doesn’t render a clearcoat unless the custom material’s ``CustomMaterial/lightingModel-swift.property`` is ``CustomMaterial/LightingModel-swift.enum/clearcoat`` and the surface shader calls `params.surface().set_clearcoat()`. The following Metal code demonstrates how to retrieve the scale and texture from this property, and use them to enable clearcoat rendering. ```cpp // Retrieve the clearcoat scale from the CustomMaterial. float clearcoatScale = params.material_constants().clearcoat_scale(); // Retrieve the entity's texture coordinates. float2 uv = params.geometry().uv0(); // Models loaded from USDZ or .reality files use texture coordinates with a // flipped y-axis. This compensates for that. uv.y = 1.0 - uv.y; // Sample the clearcoat texture using the texture coordinates. auto tex = params.textures(); half clearcoat = tex.clearcoat().sample(textureSampler, uv).r; // Multiply the scale and sampled value from the texture, and assign // the result. clearcoat *= clearcoatScale; params.surface().set_clearcoat(clearcoat); ```

get · iOS 15.0+

roughness

TypeScript
get roughness(): CustomMaterial_Roughness
Swift declaration
var roughness: CustomMaterial.Roughness { get set }

The amount the surface of the 3D object scatters reflected light. In physically based rendering, the `roughness` property represents how much the surface of an entity scatters the light that it reflects. A material with a high roughness has a matte appearance, whereas one with a low roughness has a shiny appearance. With custom materials, RealityKit doesn’t automatically use the values set on this property. To render a custom material using roughness, set ``CustomMaterial/lightingModel-swift.property`` to ``CustomMaterial/LightingModel-swift.enum/lit`` or ``CustomMaterial/LightingModel-swift.enum/clearcoat``, and specify a roughness value by calling `params.surface().set_roughness()` from the surface shader. ![An illustration showing three spheres with different amounts of roughness. The sphere on the left has a low roughness and looks like shiny, polished plastic. The sphere in the middle has a matte appearance with very soft specular highlights. The sphere on the right has no highlights whatsoever.](CustomMaterial-roughness-swift-property-1) With custom materials, the `texture` and `scale` values from the ``CustomMaterial/roughness-swift.property`` property are available in your surface shader function, but RealityKit doesn’t automatically use them to render your entity. Your surface shader is responsible for calculating or setting the actual roughness value for rendering. The following example shows how to use an image and a scale value to specify roughness: ```swift if let roughnessResource = try? TextureResource.load(named: "entity_roughness") { let roughness = MaterialParameters.Texture(roughnessResource) material.roughness = PhysicallyBasedMaterial.Roughness(tint: .green, texture:roughness) } ``` The following surface shader takes the scale and texture from the ``CustomMaterial/roughness-swift.property`` property, multiplies them together, and sets the resulting value as the roughness for rendering, which emulates the behavior of ``PhysicallyBasedMaterial``: ```cpp #include <metal_stdlib> #include <RealityKit/RealityKit.h> using namespace metal; // Samplers are used to retrieve a color value from a texture based on // the entity's UV coordinates. Samplers can be reused with different textures. // Surface shader functions should define no more than eight samplers. constexpr sampler textureSampler(address::clamp_to_edge, filter::bicubic); [[visible]] void mySurfaceShader(realitykit::surface_parameters params) { // Retrieve the roughness scale from the CustomMaterial. float roughnessScale = params.material_constants().roughness_scale(); // Retrieve the sampled value from the CustomMaterial's base color texture. auto uv = getFlippedUVs(params); auto tex = params.textures(); half roughness = tex.roughness().sample(textureSampler, uv).r; // Multiply the tint and the sampled value from the texture, and assign it // to the shader's base color property. roughness *= roughnessScale; // Set the roughness value to be used by the custom material shader. params.surface().set_roughness(roughness); } ``` For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

set · iOS 15.0+

roughness

TypeScript
set roughness(value: CustomMaterial_Roughness)
Swift declaration
var roughness: CustomMaterial.Roughness { get set }

The amount the surface of the 3D object scatters reflected light. In physically based rendering, the `roughness` property represents how much the surface of an entity scatters the light that it reflects. A material with a high roughness has a matte appearance, whereas one with a low roughness has a shiny appearance. With custom materials, RealityKit doesn’t automatically use the values set on this property. To render a custom material using roughness, set ``CustomMaterial/lightingModel-swift.property`` to ``CustomMaterial/LightingModel-swift.enum/lit`` or ``CustomMaterial/LightingModel-swift.enum/clearcoat``, and specify a roughness value by calling `params.surface().set_roughness()` from the surface shader. ![An illustration showing three spheres with different amounts of roughness. The sphere on the left has a low roughness and looks like shiny, polished plastic. The sphere in the middle has a matte appearance with very soft specular highlights. The sphere on the right has no highlights whatsoever.](CustomMaterial-roughness-swift-property-1) With custom materials, the `texture` and `scale` values from the ``CustomMaterial/roughness-swift.property`` property are available in your surface shader function, but RealityKit doesn’t automatically use them to render your entity. Your surface shader is responsible for calculating or setting the actual roughness value for rendering. The following example shows how to use an image and a scale value to specify roughness: ```swift if let roughnessResource = try? TextureResource.load(named: "entity_roughness") { let roughness = MaterialParameters.Texture(roughnessResource) material.roughness = PhysicallyBasedMaterial.Roughness(tint: .green, texture:roughness) } ``` The following surface shader takes the scale and texture from the ``CustomMaterial/roughness-swift.property`` property, multiplies them together, and sets the resulting value as the roughness for rendering, which emulates the behavior of ``PhysicallyBasedMaterial``: ```cpp #include <metal_stdlib> #include <RealityKit/RealityKit.h> using namespace metal; // Samplers are used to retrieve a color value from a texture based on // the entity's UV coordinates. Samplers can be reused with different textures. // Surface shader functions should define no more than eight samplers. constexpr sampler textureSampler(address::clamp_to_edge, filter::bicubic); [[visible]] void mySurfaceShader(realitykit::surface_parameters params) { // Retrieve the roughness scale from the CustomMaterial. float roughnessScale = params.material_constants().roughness_scale(); // Retrieve the sampled value from the CustomMaterial's base color texture. auto uv = getFlippedUVs(params); auto tex = params.textures(); half roughness = tex.roughness().sample(textureSampler, uv).r; // Multiply the tint and the sampled value from the texture, and assign it // to the shader's base color property. roughness *= roughnessScale; // Set the roughness value to be used by the custom material shader. params.surface().set_roughness(roughness); } ``` For more information on creating custom materials and writing shader functions, see <doc:modifying-realitykit-rendering-using-custom-materials>.

Skipped declarations

2 declarations were excluded from these bindings. Each reason comes from the generator or the iOS SDK compiler.

CustomMaterial.withMutableUniforms(ofType:stage:_:)

Passing a Swift type itself is not supported.

CustomMaterial.withMutableUniforms(ofType:_:)

Passing a Swift type itself is not supported.

All RealityFoundation types →