【发布时间】:2017-03-21 06:45:38
【问题描述】:
在我的 iOS 应用程序中,我有一组行星地图作为图像,其中一些分辨率高达 14k。我可以将缩小版本应用于球体,以在 SceneKit 中创建行星模型。 但是,我希望用户能够放大以查看全分辨率图像的详细信息。我也希望能够在我的应用程序内存不足的情况下做到这一点。 有没有办法像谷歌地图那样自动将纹理平铺到球体上,并且只在需要时加载部件和分辨率?
【问题讨论】:
在我的 iOS 应用程序中,我有一组行星地图作为图像,其中一些分辨率高达 14k。我可以将缩小版本应用于球体,以在 SceneKit 中创建行星模型。 但是,我希望用户能够放大以查看全分辨率图像的详细信息。我也希望能够在我的应用程序内存不足的情况下做到这一点。 有没有办法像谷歌地图那样自动将纹理平铺到球体上,并且只在需要时加载部件和分辨率?
【问题讨论】:
mipmap 和细节层次是您可以通过很少的编程工作即可应用的两种优化技术。
如果您设置代表您的星球地图的SCNMaterial 的mipFilter 属性,您将获得一个自动生成的mipmap。
如果您为地球的SCNGeometry 提供一些SCNLevelOfDetail 实例,您将获得多边形数量大大减少的版本,从而节省内存。
这些都在 2013 年 WWDC SceneKit 演讲中提到。 SCNLevelOfDetail 在 2014 年再次被提及。2014 年的示例代码有这两个示例:AAPLPresentationViewController 中的 mipmap 生成,以及幻灯片 58 中的 LOD。
【讨论】:
您需要做的是将纹理分割成更小的部分,并根据细节级别提供不同的尺寸。当您的相机放大到足够深时,您可以使用最高分辨率的纹理,但您还需要限制要显示的纹理数量。当您放大显示行星表面时,只能在屏幕上看到一小部分,但缩小后会显示整个前表面。因此,将您的纹理分割成小块,并为其他缩放级别生成较低分辨率的纹理。您还需要创建自定义几何体并在其上分配小的高分辨率纹理块。最后,您需要根据距离或视角决定为哪个相机视图显示哪个纹理几何图形。使用视锥,您还需要决定在当前场景中可以看到哪些部分。我目前面临同样的问题。我已经使用 SCNNode 创建了所有子网格和所有较小的纹理(不要在此处加载纹理 - 它们只需要按需加载!),但是我没有一个可行的解决方案来测试哪些子节点是可见的。场景的 isvisible inside frustumof 方法在这里没有帮助,因为它只进行边界框测试并且边界框太大,它们中的大多数将始终部分位于视锥体内(所以我目前正在尝试实现我的自己的测试)。您还需要一些表面法线来测试表面的前部是否指向相机的方向。不幸的是,因为我仍然没有可行的解决方案,所以我不能在这里发布任何代码——我只能描述我的“编码计划”,它会起作用(至少使用 OpenGL,我已经在几年前实现了类似的东西)。也许解决方案背后的基本思想已经对您有所帮助?否则,也许我们可以一起找出其余的……:-)
【讨论】: