Lab 049 – Split Faces

Using a different material on each face of a box.

I noticed something neat in the docs this week. When we are using ModelEntity, we can generate primitive shapes and text. One the signatures for generateBox has a special option called splitFaces. When we set this to true, we can apply a different material to each face of a cube. I looked at the other generate methods for other shapes and it seems like this is only available for boxes.

let box1 = ModelEntity(
  mesh: .generateBox(width: 0.2, height: 0.2, depth: 0.2, splitFaces: true),
  materials: [mat1, mat2, mat3, mat4, mat5, mat6])

The cool part is that it still works when we set a corner radius value.

let box2 = ModelEntity(
  mesh: .generateBox(width: 0.2, height: 0.2, depth: 0.2, cornerRadius: 0.03, splitFaces: true),
  materials: [mat1, mat2, mat3, mat4, mat5, mat6])

This opens some interesting possibilities. We could have a single box entity that could render completely differently. It could get even more fun from inside the box.

Lab Code

struct Lab049: View {
    var body: some View {
        RealityView { content in

            let mat1 = SimpleMaterial(color: .green, roughness: 0.2, isMetallic: false)
            let mat2 = SimpleMaterial(color: .yellow, roughness: 0.2, isMetallic: false)
            let mat3 = SimpleMaterial(color: .orange, roughness: 0.2, isMetallic: false)
            let mat4 = SimpleMaterial(color: .red, roughness: 0.2, isMetallic: false)
            let mat5 = SimpleMaterial(color: .purple, roughness: 0.2, isMetallic: false)
            let mat6 = SimpleMaterial(color: .blue, roughness: 0.2, isMetallic: false)

            let box1 = ModelEntity(
                mesh: .generateBox(width: 0.2, height: 0.2, depth: 0.2, splitFaces: true),
                materials: [mat1, mat2, mat3, mat4, mat5, mat6])
            box1.setPosition([-0.2, 0.2, 0], relativeTo: nil)

            let box2 = ModelEntity(
                mesh: .generateBox(width: 0.2, height: 0.2, depth: 0.2, cornerRadius: 0.03, splitFaces: true),
                materials: [mat1, mat2, mat3, mat4, mat5, mat6])

            let box3 = ModelEntity(
                mesh: .generateBox(width: 0.2, height: 0.2, depth: 0.2, cornerRadius: 0.1, splitFaces: true),
                materials: [mat1, mat2, mat3, mat4, mat5, mat6])
            box3.setPosition([0.2, -0.2, 0], relativeTo: nil)

            content.add(box1)
            content.add(box2)
            content.add(box3)

            // Spin the boxex so we can see all faces
            Task {
                let action = SpinAction(revolutions: 1,
                                        localAxis: [0.5, 0.5, 0],
                                        timingFunction: .linear,
                                        isAdditive: false)
                let animation = try AnimationResource.makeActionAnimation(for: action,
                                                                          duration: 10,
                                                                          bindTarget: .transform,
                                                                          repeatMode: .repeat)
                box1.playAnimation(animation)
                box2.playAnimation(animation)
                box3.playAnimation(animation)
            }


        }
    }
}

Support our work so we can continue to bring you new examples and articles.

Download the Xcode project with this and many more labs from Step Into Vision.

Questions or feedback?