How can I programmatically load a custom material from Reality Composer Pro?
Asked Answered
C

3

3

I have created a custom shader material in Reality Composer Pro (RCP). I can attach it to models in RCP without a problem, but my issue is that I am creating my models in code. I can not figure out how to reference the material in my RCP project.

I'm trying this but getting no luck. I suspect the "Package" string could be incorrect, but the docs don't make it very clear what the string should actually be.

if let puzzleMaterial = try? ShaderGraphMaterial.load(named: "MyCustomMaterial", from: "Package", in: realityKitContentBundle) {
    // Do something with the material
} else {
    // No luck
}
Cyclopedia answered 17/7, 2023 at 4:56 Comment(1)
Did you find a solution to this? I am sensing that you need to create an Entity via Entity(named: "MyEntity", in: realityKitContentBundle) and then somehow get the material component? I haven't found the right recipe yet.Cooks
C
2

I don't know if this is best practice or not but I made a copy of the PuzzleMaterial.usda file created by Reality Composer Pro and added it to the app's main bundle. Then I just load that into into a Data blob and used ShaderGraphMaterials init(named: from:) initializer. I peaked at the usda text file to get the "path" to the material shader:

var puzzleMaterial : ShaderGraphMaterial? = nil
do {
    let materialURL = Bundle.main.url(forResource: "PuzzleMaterial", 
                                      withExtension: "usda")
    if let materialURL = materialURL {
       let materialData = try Data(contentsOf: materialURL)
       puzzleMaterial = try await 
             ShaderGraphMaterial(named:"/PuzzleMaterial/PuzzleMaterial", 
                                  from: materialData)
    }
} catch {
    print("PuzzleMaterial load failed: \(error)")
}

I hope some one comes up with a more canonical answer that uses the Swift Package that bundles the usda file. This works for now.

Cooks answered 19/1, 2024 at 1:10 Comment(0)
Q
2

You cannot access a material at this time unless it is assigned to a mesh in Reality Composer Pro.

For my project we assigned all "loose" materials to individual cubes in Reality Composer Pro. In Xcode find the cube and make a new Model Component with the mesh you want to assign the material that was on the cube.

Quincy answered 12/8, 2023 at 0:22 Comment(0)
C
2

I don't know if this is best practice or not but I made a copy of the PuzzleMaterial.usda file created by Reality Composer Pro and added it to the app's main bundle. Then I just load that into into a Data blob and used ShaderGraphMaterials init(named: from:) initializer. I peaked at the usda text file to get the "path" to the material shader:

var puzzleMaterial : ShaderGraphMaterial? = nil
do {
    let materialURL = Bundle.main.url(forResource: "PuzzleMaterial", 
                                      withExtension: "usda")
    if let materialURL = materialURL {
       let materialData = try Data(contentsOf: materialURL)
       puzzleMaterial = try await 
             ShaderGraphMaterial(named:"/PuzzleMaterial/PuzzleMaterial", 
                                  from: materialData)
    }
} catch {
    print("PuzzleMaterial load failed: \(error)")
}

I hope some one comes up with a more canonical answer that uses the Swift Package that bundles the usda file. This works for now.

Cooks answered 19/1, 2024 at 1:10 Comment(0)
M
0

You can import material in your Reality Composer Pro project into SwiftUI by:

try await ShaderGraphMaterial.load(named: "/MyMaterial", from: "path/to/MyMaterial.usdz", in: realityKitContentBundle)

where "path/to/MyMaterial.usdz" is relative to your RealityKitContent.rkassets folder (e.g. if you put it in the top level, it'll just be "MyMaterial.usdz").

Alternatively, you can add the material to a scene and import it by:

try await ShaderGraphMaterial.load(named: "path/to/MyMaterial", from: "path/to/MyScene.usda", in: realityKitContentBundle)

where "path/to/MyMaterial" is relative to the scene (e.g. "/Root/MyMaterial"). You can look it up in Reality Composer Pro's hierarchy panel on the left.


Re @wcochran, if your Xcode project uses USD files not added to your Reality Composer Pro project, it's strongly recommended by Apple to put them into an .rkassets directory of a Swift package for faster runtime loading.

Mic answered 6/4, 2024 at 3:14 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.