SKTexture wrongly recognizes .pvrtc texture size used with SceneKit

204 Views Asked by At

I've tried texturetool and GUI of PVRTexTool to generate .pvrtc texture with 4 bit per pixel format to be loaded with SceneKit via Swift through SKTexture, then finally be supplied to use as diffuse texture for SCNSphere like following code

let diffuse_cloudTexture = SKTexture(imageNamed: "dc_4096.pvr")
let node = SCNNode()
node.geometry = SCNSphere(radius: 1)
node.geometry!.firstMaterial!.diffuse.contents = SKTexture(rect: CGRect(x: 0, y: 0, width: 4096, height: 2048), in: diffuse_cloudTexture)
node.geometry!.firstMaterial!.normal.contents = UIImage(named: "normal")
node.geometry!.firstMaterial!.isDoubleSided = false
node.geometry!.firstMaterial!.shininess = 10
node.geometry!.firstMaterial!.isLitPerPixel = true
scene.rootNode.addChildNode(node)
... <other unrelated code left out>

I specified CGRect above to specify sub-texture inside. I included 2 textures inside the source texture to be generated. Upper is cloud texture, and lower is diffuse texture.

For texturetool I used the following command

texturetool -e PVRTC --channel-weighting-linear --bits-per-pixel-4 -o dc_4096.pvrtc -f PVR -p dc_4096_preview.png source_4096.png 

For PVRTexTool I did try both formats => PVRTC 4bpp, and PVRTCII 4bpp both for OpenGL 2.0.

One notable difference is this tool generated into .pvr but the former generated into .pvrtc. Thus I use corresponding suffix in code as such depending on which tool used to generate such texture.

No matter what I do, it's all empty and transparent. The sphere has no texture. From debugging log, I print out something via

print(diffuse_cloudTexture.debugDescription)
print(diffuse_cloudTexture.textureRect())
print(diffuse_cloudTexture.size())

and it shows

<SKTexture> 'dc_4096.pvr' (128 x 128)
(0.0, 0.0, 1.0, 1.0)
(128.0, 128.0)
top: 0.0, bottom: 0.0

why it recognizes only 128x128 in size. I instead have 4096x4096 in size.


In additional, if use use the following code instead

let diffuse_cloudTexture = SKTexture(imageNamed: "dc_4096.pvr")
let node = SCNNode()
node.geometry = SCNSphere(radius: 1)
node.geometry!.firstMaterial!.diffuse.contents = diffuse_cloudTexture
node.geometry!.firstMaterial!.normal.contents = UIImage(named: "normal")

It shows weird result as follows.

enter image description here

It should be normal globe texture.


What might be the problem? and How can I use .pvrtc texture with SceneKit no matter through SKTexture or not?

edit

(searching for solution is still developing)

  • firstly thanks to @KnightOfDragon as seen in the comment. Weird texture as loaded is default X image when it cannot find texture to load. Now I see SKTexture: Error loading image resource: "dc_4096.pvrtc". So that 128x128 resolution of texture should be of that X default image.
  • That's right. Seems like SKTexture doesn't support .pvr type as @KnightOfDragon pointed me in the comment. So I just tried to use MTLTexture via MTKTextureLoader and be able to render texture onto sphere now. The problem i'm facing next is how to grab just partial of full texture in the same way that SKTexture can do via SKTexture(rect: ...<rect to grab>, in: ...<SKTexture>...). The clue I got to know MTLTexture supports .pvr is looking at list of pixel format it supports here.
0

There are 0 best solutions below