如何使用RealityKit将3D模型放置在识别到的参考图像上方
核心问题排查与修改方案
- 参考图像未设置正确的物理尺寸
ARKit依赖参考图像的物理尺寸计算其在3D空间中的实际位置和比例,你现有代码中convertToReferenceImages方法如果没有给生成的ARReferenceImage设置physicalWidth参数,会导致识别后计算的transform完全失真,模型会出现在视野外导致无法看见。
修改convertToReferenceImages实现,填入你实际使用的参考图像的物理宽度(单位为米):
func convertToReferenceImages(_ images: [UIImage]) -> Set<ARReferenceImage> { var referenceSet = Set<ARReferenceImage>() for image in images { // 示例中二维码物理宽度为10cm,即0.1m,根据实际打印尺寸修改 guard let cgImage = image.cgImage else { continue } let refImage = ARReferenceImage(cgImage, orientation: .up, physicalWidth: 0.1) referenceSet.insert(refImage) } return referenceSet }
- 锚点创建和位置设置逻辑错误
你手动提取ARImageAnchor的transform创建世界锚点,没有和系统的图像跟踪能力绑定,不仅会丢失后续的锚点位置更新,重复设置transform也可能引发异常。同时模型未做位置偏移、缩放适配,很容易出现穿模、尺寸超出视野的问题。
修改委托回调和addEntity逻辑:
func session(_ session: ARSession, didAdd anchors: [ARAnchor]) { for anchor in anchors { guard let imageAnchor = anchor as? ARImageAnchor else { continue } addEntity(self.localModelPath!, imageAnchor: imageAnchor) } } func addEntity(_ modelPath: URL, imageAnchor: ARImageAnchor) { // 异步加载模型避免阻塞主线程导致掉帧 DispatchQueue.global().async { [weak self] in guard let self = self, let entity = try? Entity.load(contentsOf: modelPath) else { return } DispatchQueue.main.async { // 直接绑定系统ARImageAnchor,自动跟踪图像位置更新 let anchor = AnchorEntity(anchor: imageAnchor) // 模型沿Y轴上浮2cm,避免穿入参考图像下方 entity.position = [0, 0.02, 0] // 根据模型原始尺寸调整缩放比例,示例为缩小100倍适配10cm的参考图像 entity.scale = [0.01, 0.01, 0.01] anchor.addChild(entity) self.arView.scene.addAnchor(anchor) } } }
- 排查验证技巧
如果修改后仍然无法显示模型,可先加载系统原生立方体测试锚点位置是否正常:
// 替换Entity.load逻辑,测试锚点位置 let boxMesh = MeshResource.generateBox(size: 0.05) let redMaterial = SimpleMaterial(color: .red, isMetallic: false) let testEntity = ModelEntity(mesh: boxMesh, materials: [redMaterial])
如果红色立方体可正常显示在参考图像上方,说明是自定义3D模型的坐标原点、朝向或原始尺寸异常,调整模型对应参数即可。
内容的提问来源于stack exchange,提问作者Tim Langner
相关产品推荐
相关产品推荐

