RealityKit Basics: Modify Material Values
Changing material values is similar to changing component values, but with a few considerations.
Overview
Review Modify Component Values to see how to edit values of components.
Modifying material values is a bit more complex than component values.
// component example
subjectEntity.components.set(OpacityComponent(opacity: 0.25))Materials are not components. Instead, they are values on the ModelComponent for an entity. We can get the first material from the component. Remember to cast it as the correct material type, in this case PhysicallyBasedMaterial. We’ll edit the baseColor.tint value, then assign the material back to the ModelComponent
// material example
if var material = sphereEntity.components[ModelComponent.self]?.materials.first as? PhysicallyBasedMaterial {
material.baseColor.tint = colorChange
sphereEntity.components[ModelComponent.self]?.materials[0] = material
}For a ShaderGraphMaterial, the process is similar, but how we set the value is different. We need to use setParameter(). Name is a string that indicates the Shader Graph Input node. Value needs to be one of the MaterialParameters value types.
if var shaderMaterial = boxEntity.components[ModelComponent.self]?.materials.first as? ShaderGraphMaterial {
do {
try shaderMaterial.setParameter(name: "Basecolor_Tint", value: MaterialParameters.Value.color(colorChange))
} catch {
print("could not set parameter")
}
}
Let’s look at another example, this time with opacity.
When working with PhysicallyBasedMaterial in code, you will find there is no opacity property. There is one in Reality Composer Pro, but this seems to map to another value behind the scenes. We need to set the blending property on the material.
material.blending = .transparent(opacity: PhysicallyBasedMaterial.Opacity(floatLiteral: opacityChange))Doing the same thing for our ShaderGraphMaterial is a bit easier. We have a float input called Opacity on the material.
try shaderMaterial.setParameter(name: "Opacity", value: MaterialParameters.Value.float(opacityChange))Apple has a neat sample project that uses an extension and an inout closures to edit materials. It is definitely worth checking out and adapting it to your material types.
Video Demo
Example Code
struct Example075: View {
@State var color: Color = .stepBackgroundSecondary
@State var opacity: Float = 1.0
@State var sphereEntity = Entity()
@State var boxEntity = Entity()
var body: some View {
HStack(alignment: .center) {
Form {
ColorPicker("Color", selection: $color)
HStack {
Text("Opacity")
.frame(width: 100, alignment: .leading)
Slider(value: $opacity, in: 0...1)
}
.padding(.vertical, 4)
}
.padding()
.frame(width: 400)
RealityView { content in
guard let scene = try? await Entity(named: "MaterialEdit", in: realityKitContentBundle) else { return }
content.add(scene)
scene.scale = [0.3, 0.3, 0.3]
scene.position = [0, 0, -0.1]
// Get the entities we want to modify and save them in state
guard let sphere = scene.findEntity(named: "Sphere") else { return }
guard let box = scene.findEntity(named: "Box") else { return }
sphereEntity = sphere
boxEntity = box
} update: { content in
// Editing either of these values will trigger the update closure
let colorChange = UIColor(color) // color picker uses Color, but these materials want UIColor...
let opacityChange = opacity
// Edit the color for a PhysicallyBasedMaterial
if var pbrMaterial = sphereEntity.components[ModelComponent.self]?.materials.first as? PhysicallyBasedMaterial {
pbrMaterial.baseColor.tint = colorChange
pbrMaterial.blending =
.transparent(opacity: PhysicallyBasedMaterial.Opacity(floatLiteral: opacityChange))
sphereEntity.components[ModelComponent.self]?.materials[0] = pbrMaterial
}
// Edit the color for a ShaderGraphMaterial
if var shaderMaterial = boxEntity.components[ModelComponent.self]?.materials.first as? ShaderGraphMaterial {
do {
try shaderMaterial.setParameter(name: "Basecolor_Tint", value: MaterialParameters.Value.color(colorChange))
try shaderMaterial.setParameter(name: "Opacity", value: MaterialParameters.Value.float(opacityChange))
boxEntity.components[ModelComponent.self]?.materials[0] = shaderMaterial
} catch {
print("could not set parameter")
}
}
}
}
}
}Download the Xcode project with this and many more examples from Step Into Vision.
Some examples are provided as standalone Xcode projects. You can find those here.

Follow Step Into Vision