5

The docs for RealityKit include the structs: OcclusionMaterial, SimpleMaterial, and UnlitMaterial for adding materials to a ModelEntity.

Alternatively you can load in a model with a material attached to it.

I want to add a custom material/texture to a ModelEntity programmatically. How can I achieve this on the fly without adding the material to a model in Reality Composer or some other 3D Software?

Halil Ozel
  • 346
  • 1
  • 13
iicaptain
  • 772
  • 1
  • 6
  • 29

1 Answers1

9

Updated: May 22, 2022

RealityKit materials

There are 6 types of materials in RealityKit 2.0 and RealityFoundation at the moment:

To apply these materials use the following logic:

import Cocoa
import RealityKit

class ViewController: NSViewController {        
    @IBOutlet var arView: ARView!
    
    override func awakeFromNib() {
        let box = try! Experience.loadBox()
        
        var simpleMat = SimpleMaterial()
        simpleMat.color = .init(tint: .blue, texture: nil)
        simpleMat.metallic = .init(floatLiteral: 0.7)
        simpleMat.roughness = .init(floatLiteral: 0.2)
        
        var pbr = PhysicallyBasedMaterial()
        pbr.baseColor = .init(tint: .green, texture: nil) 

        let mesh: MeshResource = .generateBox(width: 0.5, 
                                             height: 0.5, 
                                              depth: 0.5, 
                                       cornerRadius: 0.02, 
                                         splitFaces: true)

        let boxComponent = ModelComponent(mesh: mesh,
                                     materials: [simpleMat, pbr])

        box.steelBox?.children[0].components.set(boxComponent)
        box.steelBox?.orientation = Transform(pitch: .pi/4, 
                                                yaw: .pi/4, 
                                               roll: 0).rotation
        arView.scene.anchors.append(box)
    }
}

enter image description here


How to create RealityKit's shaders similar to SceneKit's shaders

We know that in SceneKit there are 5 different shading models, so we can use RealityKit's SimpleMaterial, PhysicallyBasedMaterial and UnlitMaterial to generate all these five shaders that we've been accustomed to.

Let's see how it looks like:

SCNMaterial.LightingModel.blinn           – SimpleMaterial(color: . gray,
                                                        roughness: .float(0.5),
                                                       isMetallic: false)

SCNMaterial.LightingModel.lambert         – SimpleMaterial(color: . gray,
                                                        roughness: .float(1.0),
                                                       isMetallic: false)
  
SCNMaterial.LightingModel.phong           – SimpleMaterial(color: . gray,
                                                        roughness: .float(0.0),
                                                       isMetallic: false)

SCNMaterial.LightingModel.physicallyBased – PhysicallyBasedMaterial()


SCNMaterial.LightingModel.constant        – UnlitMaterial(color: .gray)
Andy Jazz
  • 36,357
  • 13
  • 107
  • 175
  • 1
    I can confirm this works perfectly in iOS 13! Thanks @ARGeo – iicaptain Jul 03 '19 at 03:35
  • 2
    It does work, yes. Making the alpha channel work seems to rely on a workaround as of now: [Apple forums](https://forums.developer.apple.com/thread/119265) – HelloTimo Sep 17 '19 at 16:12
  • 1
    Is there any way to add 6x face textures to a box? – Jayden Irwin Jun 10 '21 at 05:00
  • 1
    Yeah, I’m not sure how to use 3D software. I was hoping there was a easy way to do it in code. Like SceneKit can take an array of 6 textures to put on each face of a box. – Jayden Irwin Jun 10 '21 at 05:16
  • Hi @JaydenIrwin, I've updated my answer. There's a `splitFaces: Bool` parameter that could help you apply 6X texture. – Andy Jazz May 22 '22 at 20:01