You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在RealityKit中为USDZ内的现有ModelEntity添加简单材质?

在RealityKit中为USDZ内的OBJ部件设置材质与属性

我导入了一个包含OBJ文件作为图层的USDZ文件,其中的对象无结构、材质与颜色,需在运行时单独设置。我已通过SceneKit实现该功能,代码如下:

// 获取所有部件
guard let scene = SCNScene(named: "art.scnassets/allParts.usdz") else { return }
// 隐藏所有部件
scene.rootNode.childNodes.forEach { child in
    child.isHidden = true
}

// 显示并配置需要的部件(位置与分组)
let part1 = scene.rootNode.childNode(withName: "part1_abc2", recursively: true)!
part1.isHidden = false
part1.childNodes.first?.geometry?.firstMaterial?.diffuse.contents = UIColor.red
part1.localRotate(by: SCNQuaternion(0, 0, 0, 0))
part1.localTranslate(by: SCNVector3(0, 0, 0.216))
...

我希望在RealityKit中实现相同行为,编写了如下代码:

let modelEntity = try! ModelEntity.load(named: "art.scnassets/allParts.usdz")
modelEntity.children.forEach { child in
    child.isEnabled = false
}

guard let part1 = modelEntity.findEntity(named: "part1_abc2") else { return }
part1.isEnabled = true
part1.orientation = Transform(pitch: 0, yaw: 0, roll: 0).rotation
part1.transform = Transform(translation: [0, 0, 0.216])

但不知如何为部件分配颜色或材质。我知道可通过如下方式初始化带材质的ModelEntity:

let mesh = MeshResource.generateBox(size: 0.5, cornerRadius: 0.1)
let material = SimpleMaterial(color: .red, roughness: 0.15, isMetallic: true)
let model = ModelEntity(mesh: mesh, materials: [material])

但如何为已有的OBJ部件后续添加材质?


UPDATE 1:
我发现ModelEntity.load返回的是Entity而非ModelEntity,需要获取USDZ文件中每个图层/部件的ModelEntity,恳请指点方向。


UPDATE 2:
我尝试了如下代码,但模型完全消失:

let modelEntity = try! Entity.loadModel(named: "art.scnassets/allParts.usdz")
modelEntity.model?.materials = [UnlitMaterial(color: .red)]

我猜测需为每个子图层设置材质,但如下代码仍返回Entity:

guard let part1 = modelEntity.findEntity(named: "part1_abc2") else { return }
part1.isEnabled = true
part1.orientation = Transform(pitch: 0, yaw: 0, roll: 0).rotation
part1.transform = Transform(translation: [0, 0, 0.216])

UPDATE 3:
针对Andy Jazz的回答,我测试后发现:若将USDZ加载为ModelEntity,层级结构完全为空,导致类型转换失败:

let modelEntity = try! Entity.loadModel(named: "art.scnassets/allThePartsOf.usdz")
print(modelEntity)

print("will downcasting")
guard let uw = modelEntity.findEntity(named: "RealModel") as? ModelEntity else {
    print("downcasting failed")
    return
}
print("did downcasting")

控制台输出:

▿ '' : ModelEntity
  ⟐ Transform
  ⟐ SynchronizationComponent
  ⟐ ModelComponent

will downcasting
downcasting failed

若将USDZ加载为Entity,能获取层级树,但类型转换仍失败:

let modelEntity = try! ModelEntity.load(named: "art.scnassets/allThePartsOf.usdz")
print(modelEntity)

控制台输出:

▿ '/' : Entity, children: 110
  ⟐ Transform
  ⟐ SynchronizationComponent
  ▿ 'RealModel' : Entity, children: 1
    ⟐ Transform
    ⟐ SynchronizationComponent
    ▿ 'RealModel' : ModelEntity
      ⟐ Transform
      ⟐ ModelComponent
      ⟐ SynchronizationComponent
  ▿ 'RealModel_1' : Entity, children: 1
    ⟐ Transform
    ⟐ SynchronizationComponent
    ▿ 'RealModel_1' : ModelEntity
      ⟐ Transform
      ⟐ ModelComponent
      ⟐ SynchronizationComponent
.
.
.

will downcasting
downcasting failed

内容的提问来源于stack exchange,提问作者lobax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:14:53