Search code examples
iosscenekitscnnodescnmaterialscngeometry

Custom SCNGeometry not displaying diffuse contents as texture


I'm creating a custom SCNGeometry. To start, I'm developing it as a flat plane. It displays, and I can apply a colour to its' diffuse contents, but if I try and apply anything such as a UIImage, or a CALayer, it displays as white.

Code:

let positions = [
    SCNVector3(-1, 0, 0),
    SCNVector3(1, 0, 0),
    SCNVector3(-1, 0, -1),
    SCNVector3(1, 0, -1)
]

let indices: [UInt8] = [
    0, 1, 2,
    1, 3, 2
]

let vertexSource = SCNGeometrySource(vertices: positions)

let indexData = Data(bytes: indices, count: indices.count)

let element = SCNGeometryElement(
    data: indexData,
    primitiveType: SCNGeometryPrimitiveType.triangles,
    primitiveCount: indices.count / 3,
    bytesPerIndex: 1)

let geometry = SCNGeometry(
    sources: [vertexSource],
    elements: [element])

geometry.firstMaterial?.diffuse.contents = UIImage(named: "homer")

Solution

  • To be able to texture a geometry you need to also provide UV coordinates (texture coordinates) source.

    let textureCoordinates = [
        CGPoint(x: 0, y: 0),
        CGPoint(x: 1, y: 0),
        CGPoint(x: 0, y: 1),
        CGPoint(x: 1, y: 1)
    ]
    
    let uvSource = SCNGeometrySource(textureCoordinates: textureCoordinates)
    
    let element = ...
    
    let geometry = SCNGeometry(
        sources: [vertexSource, uvSource],
        elements: [element])