我开发了一款应用程序,可以动态预览3D模型的细分结果。我有自己的catmull clark细分函数来永久修改几何体,但是我使用SCNGeometry的.subdivisionLevel属性来暂时将模型细分为预览。在大多数情况下,预览并不意味着用户会选择永久性选项。
.subdivisionLevel使用(就像MDLMesh的细分,我尝试作为一种解决方法)皮克斯的OpenSubdiv进行实际的细分和平滑。它比我自己的工作更快,但更重要的是它不会永久修改我通过SCNGeometry源提供的顶点数据。
问题是,我不能让它停止泄漏记忆。很久以前我第一次注意到这一点,认为这是我代码中的内容。我不认为它只是一个特定的IOS版本,它发生在Swift和Objective C中。最后我设置了一个小例子,只在Xcode的SceneKit游戏模板中添加1行,将船的subdivisionLevel设置为1.仪器显示立即导致内存泄漏:
我在一周前向Apple提交了一份错误报告,但我不确定我是否可以在任何时候尽快回复或修复。屏幕截图来自一个非常小型号的测试,但即使是小型号(数百到几千个顶点),它也会泄漏很多而且速度很快,并且会导致应用程序崩溃。
要重现,请在Xcode中基于SceneKit游戏模板创建一个新项目,并将以下行添加到handletap:
if result.node.geometry!.subdivisionLevel == 3 {
result.node.geometry!.subdivisionLevel = 0
} else {
result.node.geometry!.subdivisionLevel = 3
}
(删除!对于目标c) 点击船只以泄漏兆字节,再点击它并快速累加。
OpenSubdiv显然用于3D Studio max以及其他版本,它似乎是在Apple的实现中。所以我的问题是:有没有办法解决/避免这个问题而不完全放弃SceneKit的细分功能,或者是Apple的唯一回应?
答案 0 :(得分:0)
通过WWDC视频来了解Apple对OpenSubdiv的承诺以及他们修复漏洞的可能性,我发现自从最新的SceneKit更新以来,Metal可以在GPU上执行细分。
如果你想在SceneKit或Model IO中使用细分,那么必需两行(Swift):
let tess = SCNGeometryTessellator()
geometry.tessellator = tess
(来自WWDC 2017什么是Scenekit的新功能,23:45进入视频)
这将导致细分在GPU上执行(因此更快,特别是在更高级别),使用更少的内存,最重要的是,在将细分级别设置为更低或更低时释放内存。