SKTexture mipmaps on a 3x device?

Let's assume that usesMipmaps actually works. Would it still work on a 3× device?


I am unsure because mipmaps only work on images that are sized by a power of two, and measured in pixels, no 3× image is so sized. If it doesn't work with 3× images, I am not sure it would work on 3× devices at all.


Let’s say you have 512×512 pt texture in 2× (1024×1024 px) and 3× (1536×1536 px). Let’s further say that it needs to be displayed at 150×150 pt.


On a 2× device, the texture would need to be displayed at 300×300 px. The 1024×1024 px texture would have a mipmapped version at 512×512 px, and presumably only that one would need to be resident in texture memory. (That’s my understanding of why mipmaps are even a thing—to reduce active-set texture memory usage.)


But now let’s look at 3× devices, where the texture needs to be displayed at 450×450 px. On a 3× device, the assets are usually thinned. There won’t be a 2× version, and the 3× version isn’t a power of two, so it won’t be mipmapped, which means it’ll be saved in texture memory at full size and scaled down each time it is displayed, right?


If you only supply a 2× texture or only supply a “Single Scale” texture, I believe that Xcode will automatically upscale that at build time to a 3× asset when delivering to a 3× device. The app bundle still won’t have a 2× asset.


But I could be wrong about that. In this cases, the app would only have the 2× power-of-two texture. When displaying the texture in this scenario, I think the results would depend on the actual order of operations:

  • Texture → Mipmap → Render → Screen scale. The system mipmaps the 2× texture down to 512×512 px and renders it to 450×450 px, accounting for displayed texture size and screen scale at the same time. This is the happy path.
  • Texture → Screen scale → Mipmap → Render. The system finds the 2× texture, notes that this is a 3× screen, upscales it to 1536×1536 px, and then submits it to the rendering pipeline, which can’t mipmap it.


If the app has both 3× and 2× textures available, it would only end up on the happy path if it sees that it should scale down the 2× (1024×1024 px) texture to 450×450 px rather than the 3× (1536×1536 px) texture. I think it does, but I don’t know for sure.


Long story short, mipmapping on a 3× device could work—if and only if you can ensure that it has a 2× or Single Scale asset—but does it?

Replies

Also, you can of course create your 3x texture at, say, 2048x2048 px. Then everything is clearly mipmappable on a 3x device, but not on a 2x or 1x device. My assumption here is that you'll want all textures to have the same point size, to keep the measurements in SpriteKit the same.