7

I'm a fairly experienced iOS developer but a total SceneKit newbie, trying to simulate some planets in a basic app.

To that end, I'm using high-res normal and diffuse maps of Mars, Venus, etc, applied to basic spheres. And they work! They look awesome, exactly what I was going for.

enter image description here enter image description here

The problem is, I'm getting killed by the quality/memory tradeoff.

I can scale down the dimensions of the textures to reduce the memory footprint, but below a certain resolution the results (especially the normal map) start to look really mushy and terrible. The app needs to be able to zoom at least to where the planet is screen-width, but to maintain any crispness in the mountains and valleys I need to use a PNG normal map (above) at about 6000 x 3000. I can scale the diffuse map way down to about 1000 x 500, but even so, I'm getting periodic memory crashes from a single sphere gently rotating, with a single light, no background, no physics, and no other geometry.

Now, I know that's a super-high-res normal map. I get it. But at the same time, it's just one sphere, doing nothing. That's not even close to some of the complexity I've seen other apps execute flawlessly, even with some pretty detailed textures of their own. It seems like there must be some way of getting high-detail surface textures for a single object, without crashing the app.

So, being a total SceneKit newbie, I'm wondering: are there any tricks for getting good SceneKit texture quality without using ALL the memory in the world? Maybe a way of handling the image textures, re-encoding the files, changing the scene/node settings, etc? Any way at all to get crisp quality with smaller images, or lower memory usage with the same images?

I'd happily quote some code, but right now there isn't much to show. I apply the textures to the SceneKit node the standard way, and it works. I'm just dying from either a lack of memory, or lack of image quality.

Can anyone help me out?

Nerrolken
  • 1,975
  • 3
  • 24
  • 53
  • geometry data should not take much memory. physics/animation/particles should be negligible memory-wise. So if everything goes well (i.e no leak) 90% of your memory usage should be used by your textures. how many planets/large textures do you have at the same time? did you try switching high res/low res based on the distance between a planet and the point of view? – Toyos Sep 23 '15 at 22:09
  • @Toyos I only have one planet with two textures: normal and diffuse. The planet works and spins properly, but if I try to do anything else (like add labels to the view, or go to the home screen and return to the app) it risks a memory termination. Not every time, but maybe 1 out of every 3-4 times. Consistently enough to be unacceptable, and frankly a little bewildering for such a simple scene. As for switching resolutions, it's a good idea but the planet in this app stays in the foreground all the time, so there's never a time to switch to lower res. – Nerrolken Sep 24 '15 at 13:56
  • This sounds very buggy, to me. At 1000x500 you shouldn't be having any kinds of problems. But I'll just add one weird thing to try... by force of habit I always use ^2 sized textures. So try 1024x512, see if that makes a difference. It might because the ideas behind texture packing are decades old, and maybe haven't been flexed to take advantage of a more diverse world involving other types of numbers. – Confused Sep 25 '15 at 06:12
  • @Confused As I understand it, it isn't the 1000x500 diffuse texture that's eating up so much memory, it's the 6000x3000 normal map. Or should that also not be a problem? – Nerrolken Sep 25 '15 at 13:19
  • argh, sorry. I read that as you were using 1000x500 for both normal and diffuse and still having the problem. No, 6000x3000 for your normal map is the problem, most definitely. Can you restrict it to 4096x2048, that should be ok on the modern hardware. – Confused Sep 26 '15 at 03:25
  • Did you resolve your issue yet? May I ask how many FPS you achieve (on which device)? I'm also trying to use high-res (diffuse) textures, but my frame rate drops rapidly to about 20 FPS. A thing that might work for both of us is tiling the texture into smaller chunks so that SceneKit may load/unload those chunks not currently on screen, or optimize some other way. What did you do so far? – Double M Jan 13 '17 at 13:29
  • @DoubleM I ultimately just had to scale down the textures. I realized that scaling down the diffuse map didn't look too bad if the normal map was still pretty high-res, because it created the illusion that the diffuse map was sharper. So I kept the normal map as low as I could without losing too much quality, and dropped the diffuse even father. My experiments show that it's the normal map that causes the memory issues for the most part: even a small drop in resolution helps a lot. I also added per-device and per-iOS-version differentiation code, so lower textures are used on older devices. – Nerrolken Mar 12 '17 at 21:36

1 Answers1

0

I think the idea is to segment the sphere texture wise so it's only displaying perhaps 60degrees of texture at anyone time, similar to how you display pictures at high resolutions when zooming. I'm not sure how to go about doing that, but that is my guess.

Sean
  • 189
  • 3
  • 7