在 SceneKit 中加载巨大的动画 3D 模型会导致内存问题
Loading huge animated 3D model in SceneKit causes memory issues
我对 ARKit
有疑问。我的 3D 模型是 197MB 的 DAE 格式(没有 20MB 的纹理)。当我尝试在没有纹理的 SceneKit
中加载我的模型时,一切都很好,但是当我加载带有纹理的模型时,我的应用程序出现内存问题。我的纹理文件在 100kB 到 4MB 之间。当加载纹理时,我的应用程序在我的 phone (iPhone X) 上使用 1.84 GB RAM,这会导致内存问题。我一直在互联网上搜索,但找不到任何解决方案。有人可以给我帮助或建议吗?
我的代码:
self.shipNode = SCNNode(daePath: "art.scnassets/s.scn")!
extension SCNNode {
convenience init?(daePath: String) {
self.init()
guard let scene = SCNScene(named: daePath) else {
return
}
DispatchQueue.main.async { [weak self] in
for childNode in scene.rootNode.childNodes {
self!.addChildNode(childNode)
}
}
}
}
我是如何使用它的:
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
DispatchQueue.global().async { [weak self] in
if let imageAnchor = anchor as? ARImageAnchor {
let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width,
height: imageAnchor.referenceImage.physicalSize.height)
plane.firstMaterial?.diffuse.contents = UIColor(white: 1, alpha: 0.8)
self?.planeNode = SCNNode(geometry: plane)
self?.planeNode.eulerAngles.x = -.pi / 2
self?.shipNode.position = SCNVector3Zero
self?.shipNode.position.z = 0.05
DispatchQueue.main.async { [weak self] in
self?.planeNode.addChildNode(self!.shipNode)
self!.node.addChildNode(self!.planeNode)
}
}
}
return node
}
High-poly models with huge texture maps are not suitable for robust AR experience. Augmented Reality frameworks (such as ARKit or ARCore) are very processor-intensive, so there's no need to additionally increase a burden on CPU, GPU and memory.
为什么 ARKit 应用如此CPU密集?
您的 ARKit 应用程序使用 4 个传感器以 60 fps 的速度跟踪周围环境,并同时渲染(在 SceneKit 或 RealityKit 的帮助下)具有所有纹理、灯光和阴影的动画 3D 模型,然后渲染,它通过后置摄像头的高分辨率 RGB 视频实时合成模型的 2D 渲染(RGBAZ 模式)。这对您的设备来说太多了,不是吗?
因此,任何具有巨大纹理的高多边形模型不仅会导致内存和 CPU/GPU 问题,而且会很快耗尽电池电量。并且,请考虑 - iPhone X 只有 3 GB 的 RAM,其中 iOS 使用超过 1 GB,因此在您的特定情况下很可能出现内存问题。
因此,我对创建 3D 模型以获得强大的 AR 体验的建议如下:
- 低多边形几何体(通常每个模型 10,000 个多边形 就可以了)
- UV 贴图纹理分辨率 – 不超过 1024 x 1024 像素
- 最好,预烘焙 UV 贴图阴影 用于静态元素
- 纹理使用 压缩率为 0% 的 JPEG 格式(PNG 更大)
- 不要在场景中使用太多 PBR 着色器(具有 金属度 属性)
我对 ARKit
有疑问。我的 3D 模型是 197MB 的 DAE 格式(没有 20MB 的纹理)。当我尝试在没有纹理的 SceneKit
中加载我的模型时,一切都很好,但是当我加载带有纹理的模型时,我的应用程序出现内存问题。我的纹理文件在 100kB 到 4MB 之间。当加载纹理时,我的应用程序在我的 phone (iPhone X) 上使用 1.84 GB RAM,这会导致内存问题。我一直在互联网上搜索,但找不到任何解决方案。有人可以给我帮助或建议吗?
我的代码:
self.shipNode = SCNNode(daePath: "art.scnassets/s.scn")!
extension SCNNode {
convenience init?(daePath: String) {
self.init()
guard let scene = SCNScene(named: daePath) else {
return
}
DispatchQueue.main.async { [weak self] in
for childNode in scene.rootNode.childNodes {
self!.addChildNode(childNode)
}
}
}
}
我是如何使用它的:
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
DispatchQueue.global().async { [weak self] in
if let imageAnchor = anchor as? ARImageAnchor {
let plane = SCNPlane(width: imageAnchor.referenceImage.physicalSize.width,
height: imageAnchor.referenceImage.physicalSize.height)
plane.firstMaterial?.diffuse.contents = UIColor(white: 1, alpha: 0.8)
self?.planeNode = SCNNode(geometry: plane)
self?.planeNode.eulerAngles.x = -.pi / 2
self?.shipNode.position = SCNVector3Zero
self?.shipNode.position.z = 0.05
DispatchQueue.main.async { [weak self] in
self?.planeNode.addChildNode(self!.shipNode)
self!.node.addChildNode(self!.planeNode)
}
}
}
return node
}
High-poly models with huge texture maps are not suitable for robust AR experience. Augmented Reality frameworks (such as ARKit or ARCore) are very processor-intensive, so there's no need to additionally increase a burden on CPU, GPU and memory.
为什么 ARKit 应用如此CPU密集?
您的 ARKit 应用程序使用 4 个传感器以 60 fps 的速度跟踪周围环境,并同时渲染(在 SceneKit 或 RealityKit 的帮助下)具有所有纹理、灯光和阴影的动画 3D 模型,然后渲染,它通过后置摄像头的高分辨率 RGB 视频实时合成模型的 2D 渲染(RGBAZ 模式)。这对您的设备来说太多了,不是吗?
因此,任何具有巨大纹理的高多边形模型不仅会导致内存和 CPU/GPU 问题,而且会很快耗尽电池电量。并且,请考虑 - iPhone X 只有 3 GB 的 RAM,其中 iOS 使用超过 1 GB,因此在您的特定情况下很可能出现内存问题。
因此,我对创建 3D 模型以获得强大的 AR 体验的建议如下:
- 低多边形几何体(通常每个模型 10,000 个多边形 就可以了)
- UV 贴图纹理分辨率 – 不超过 1024 x 1024 像素
- 最好,预烘焙 UV 贴图阴影 用于静态元素
- 纹理使用 压缩率为 0% 的 JPEG 格式(PNG 更大)
- 不要在场景中使用太多 PBR 着色器(具有 金属度 属性)