Phi
Phi

Reputation: 157

Textures always flipped and inverted with SceneKit Custom Geometry

I've been able to create custom geometry in SceneKit, but I always get flipped/inverted textures.

I've tried a lot of other people's example code for custom geometry and still ended up with the flipped/inverted texture issue. Any help would be greatly appreciated!

flipped/inverted texture screenshot

  // v1 +----+ v0
  //    |    |
  // v2 +----+ v3

let positions: [Float] = [
     5.0,   5.0,  0.0,
    -5.0,   5.0,  0.0,
    -5.0,  -5.0,  0.0,
     5.0,  -5.0,  0.0
]

let normals: [Float] = [
    0.0,  0.0,  1.0,
    0.0,  0.0,  1.0,
    0.0,  0.0,  1.0,
    0.0,  0.0,  1.0
]

let tcoords: [Float] = [
    1.0,  1.0,
    0.0,  1.0,
    0.0,  0.0,
    1.0,  0.0
]

let positionsData = Data(bytes: positions, count: positions.count * 4)

let positionSource = SCNGeometrySource(data: positionsData,
                                       semantic: SCNGeometrySource.Semantic.vertex,
                                       vectorCount: positions.count / 3,
                                       usesFloatComponents: true,
                                       componentsPerVector: 3,
                                       bytesPerComponent: 4,
                                       dataOffset: 0,
                                       dataStride: 12)

let normalsData = Data(bytes: normals, count: normals.count * 4)

let normalSource = SCNGeometrySource(data: normalsData,
                                       semantic: SCNGeometrySource.Semantic.normal,
                                       vectorCount: normals.count / 3,
                                       usesFloatComponents: true,
                                       componentsPerVector: 3,
                                       bytesPerComponent: 4,
                                       dataOffset: 0,
                                       dataStride: 12)

let tcoordsData = Data(bytes: tcoords, count: tcoords.count * 4)

let tcoordSource = SCNGeometrySource(data: tcoordsData,
                                     semantic: SCNGeometrySource.Semantic.texcoord,
                                     vectorCount: tcoords.count / 2,
                                     usesFloatComponents: true,
                                     componentsPerVector: 2,
                                     bytesPerComponent: 4,
                                     dataOffset: 0,
                                     dataStride: 8)

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

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

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

let geometry = SCNGeometry(sources: [positionSource, normalSource, tcoordSource],
                           elements: [indexElement])

Upvotes: 2

Views: 528

Answers (1)

mnuages
mnuages

Reputation: 13462

you'll want to flip the texture coordinates in tcoords. SceneKit follows the convention that the origin of texture coordinates is at the top left of the texture.

In Metal, the origin of the pixel coordinate system of a framebuffer attachment is defined at the top left corner. Similarly, the origin of the pixel coordinate system of a framebuffer attachment is the top left corner.

Upvotes: 3

Related Questions