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
CGRectabove 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.
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
SKTexturedoesn't support .pvr type as @KnightOfDragon pointed me in the comment. So I just tried to useMTLTextureviaMTKTextureLoaderand 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 thatSKTexturecan do viaSKTexture(rect: ...<rect to grab>, in: ...<SKTexture>...). The clue I got to knowMTLTexturesupports .pvr is looking at list of pixel format it supports here.
