You can get it to work with a custom geometry: create a cube (http://ronnqvi.st/custom-scenekit-geometry/ is a good place to get started) and you can add some custom texture mapping on top. It's a bit tricky to get the indices right (was for me), but at the end it worked fine:
func getSimpleCubeGeo() -> SCNGeometry {
let halfSide = Float(0.5)
/* The cube vertex are like:
5---------4
/. /|
/ . / |
7---------6 |
| . | |
| . | |
| 1......|..0
| . | /
|. |/
3---------2
*/
let _positions = [
SCNVector3(x:-halfSide, y:-halfSide, z: halfSide),
SCNVector3(x: halfSide, y:-halfSide, z: halfSide),
SCNVector3(x:-halfSide, y:-halfSide, z: -halfSide),
SCNVector3(x: halfSide, y:-halfSide, z: -halfSide),
SCNVector3(x:-halfSide, y: halfSide, z: halfSide),
SCNVector3(x: halfSide, y: halfSide, z: halfSide),
SCNVector3(x:-halfSide, y: halfSide, z: -halfSide),
SCNVector3(x: halfSide, y: halfSide, z: -halfSide),
]
// points are tripled since they are each used on 3 faces
// and there's no continuity in the UV mapping
// so we need to duplicate the points
//
// we'll use the first third for the faces orthogonal to the X (left) axis,
// the second for the Y (top) axis and the third for the Z (front) axis
let positions = _positions + _positions + _positions
let X = 0
let Y = 8
let Z = 16
let indices = [
// bottom
0 + Y, 2 + Y, 1 + Y,
1 + Y, 2 + Y, 3 + Y,
// back
2 + Z, 6 + Z, 3 + Z,
3 + Z, 6 + Z, 7 + Z,
// left
0 + X, 4 + X, 2 + X,
2 + X, 4 + X, 6 + X,
// right
1 + X, 3 + X, 5 + X,
3 + X, 7 + X, 5 + X,
// front
0 + Z, 1 + Z, 4 + Z,
1 + Z, 5 + Z, 4 + Z,
// top
4 + Y, 5 + Y, 6 + Y,
5 + Y, 7 + Y, 6 + Y,
]
// get the points in the texture where the faces are split
var textureSplitPoints = [CGPoint]()
for i in 0...12 {
let x = Double(i % 4)
let y = Double(i / 4)
textureSplitPoints.append(CGPoint(x: x / 3.0, y: y / 2.0))
}
let textCoords = [
textureSplitPoints[4],
textureSplitPoints[6],
textureSplitPoints[5],
textureSplitPoints[5],
textureSplitPoints[8],
textureSplitPoints[10],
textureSplitPoints[9],
textureSplitPoints[9],
textureSplitPoints[5],
textureSplitPoints[4],
textureSplitPoints[1],
textureSplitPoints[0],
textureSplitPoints[7],
textureSplitPoints[6],
textureSplitPoints[11],
textureSplitPoints[10],
textureSplitPoints[2],
textureSplitPoints[1],
textureSplitPoints[2],
textureSplitPoints[3],
textureSplitPoints[6],
textureSplitPoints[5],
textureSplitPoints[6],
textureSplitPoints[7],
]
let vertexSource = SCNGeometrySource(vertices: positions)
let textSource = SCNGeometrySource(textureCoordinates: textCoords)
let indexData = NSData(bytes: indices, length: sizeof(Int) * indices.count)
let elements = SCNGeometryElement(
data: indexData as Data,
primitiveType: SCNGeometryPrimitiveType.triangles,
primitiveCount: indices.count / 3,
bytesPerIndex: sizeof(Int)
)
return SCNGeometry(sources: [vertexSource, textSource], elements: [elements])
}