【发布时间】:2015-12-21 05:46:56
【问题描述】:
我是一位经验丰富的 iOS 开发人员,但完全是 SceneKit 新手,试图在一个基本的应用程序中模拟一些行星。
为此,我将火星、金星等的高分辨率法线和漫反射贴图应用于基本球体。他们工作!它们看起来很棒,正是我想要的。
问题是,我被质量/内存权衡杀死。
我可以按比例缩小纹理的尺寸以减少内存占用,但低于一定的分辨率,结果(尤其是法线贴图)开始看起来非常糊状和糟糕。该应用程序需要能够至少缩放到地球屏幕宽度的位置,但为了保持山脉和山谷的任何清晰度,我需要使用大约 6000 x 3000 的 PNG 法线贴图(上图)。我可以缩放漫反射贴图的分辨率降低到大约 1000 x 500,但即便如此,我还是会因为一个轻轻旋转的球体而周期性的内存崩溃,只有一个灯光,没有背景,没有物理,也没有其他几何图形。
现在,我知道那是一张超高分辨率的法线贴图。我知道了。但同时,它只是一个球体,什么都不做。这甚至与我见过的其他应用程序完美执行的复杂性相比还差得很远,即使它们自己有一些非常详细的纹理。似乎必须有某种方法可以获取单个对象的高细节表面纹理,而不会导致应用程序崩溃。
所以,作为一个完全的 SceneKit 新手,我想知道:有什么技巧可以在不使用世界上所有内存的情况下获得良好的 SceneKit 纹理质量?也许是一种处理图像纹理的方法,重新编码文件,更改场景/节点设置等?有什么方法可以用较小的图像获得清晰的质量,或者用相同的图像降低内存使用量?
我很乐意引用一些代码,但现在没有什么可展示的。我以标准方式将纹理应用到 SceneKit 节点,它可以工作。我只是因为缺乏记忆或缺乏图像质量而快死了。
谁能帮帮我?
【问题讨论】:
-
几何数据不应该占用太多内存。物理/动画/粒子在记忆方面应该可以忽略不计。因此,如果一切顺利(即没有泄漏),纹理应该使用 90% 的内存使用量。您同时拥有多少个行星/大纹理?您是否尝试过根据行星与视点之间的距离来切换高分辨率/低分辨率?
-
@Toyos 我只有一个行星有两种纹理:正常和漫反射。行星正常工作和旋转,但如果我尝试做任何其他事情(比如向视图添加标签,或转到主屏幕并返回应用程序),它可能会导致内存终止。不是每次,但可能每 3-4 次中就有 1 次。始终足以令人无法接受,坦率地说,对于这样一个简单的场景有点令人困惑。至于切换分辨率,这是个好主意,但是这个应用程序中的星球一直停留在前台,所以从来没有时间切换到较低的分辨率。
-
这听起来很麻烦,对我来说。在 1000x500 时,您应该不会遇到任何问题。但我只会添加一个奇怪的东西来尝试......由于习惯的力量,我总是使用 ^2 大小的纹理。所以试试 1024x512,看看会不会有什么不同。这可能是因为纹理打包背后的想法已有数十年的历史,并且可能还没有灵活地利用涉及其他类型数字的更加多样化的世界。
-
@Confused 据我了解,不是 1000x500 漫反射纹理占用了这么多内存,而是 6000x3000 法线贴图。或者这也不是问题?
-
啊,对不起。我读到了,因为您将 1000x500 用于正常和漫反射,但仍然存在问题。不,法线贴图的 6000x3000 绝对是问题所在。你能把它限制在 4096x2048,在现代硬件上应该没问题。
标签: ios memory uiimage out-of-memory scenekit