xaled
xaled

Reputation: 45

how to apply normal map texture to custom geometry in scenekit, ios?

I'd created a custom SCNGeometry using following code:

let data = NSData(bytes: position, length: MemoryLayout<float3>.size * self.objectMesh.pointCount)
                                let vertexSource = SCNGeometrySource(data: data as Data,
                                                                     semantic: .vertex,
                                                                     vectorCount: self.objectMesh.pointCount,
                                                                     usesFloatComponents: true,
                                                                     componentsPerVector: 3,
                                                                     bytesPerComponent: MemoryLayout<Float32>.size,
                                                                     dataOffset: 0,
                                                                     dataStride: MemoryLayout<float3>.size)
                                let data2 = NSData(bytes: uvs, length: MemoryLayout<float2>.size * self.objectMesh.pointCount)
                                let tSource = SCNGeometrySource(data: data2 as Data,
                                                                semantic: .texcoord,
                                                                vectorCount: self.objectMesh.pointCount,
                                                                usesFloatComponents: true,
                                                                componentsPerVector: 2,
                                                                bytesPerComponent: MemoryLayout<Float32>.size,
                                                                dataOffset: 0,
                                                                dataStride: MemoryLayout<float2>.stride)

                                let indexData = NSData(bytes: faces, length: MemoryLayout<Int32>.size * self.objectMesh.faceCount)
                                let element = SCNGeometryElement(
                                    data: indexData as Data,
                                    primitiveType: .triangles,
                                    primitiveCount: self.objectMesh.faceCount/3,
                                    bytesPerIndex: MemoryLayout<Int32>.size)
                                let Geometry = SCNGeometry(sources: [vertexSource, tSource], elements: [element])
                                Geometry.firstMaterial?.diffuse.contents = self.MainTexture
                                Geometry.firstMaterial?.normal.contents = self.NormalTexture

now the problem is: the texture shows up but the normal texture map is not applied to the geometry. I'm not going to use per vertex normals. this texture and normaltexture are works when applied to for example SCNPlane geometry. but I don't now how to use a normal map texture with my custom geometry.

Upvotes: 0

Views: 595

Answers (1)

Xartec
Xartec

Reputation: 2415

The normal property on SCNMaterial expects a normal map in tangent space and then the effective normals are based on a combination of the normal map and the vertex normals of your custom geometry.

Model i/o includes MDLMesh which provide an addNormals method that can be used to create the normals programmatically (create an MDLMesh based on the SCNGeometry, use addNormals, and create a SCNGeometry based on the MDLMesh and use that new SCNGeometry instead). But ideally you include the normals with the custom geometry.

Upvotes: 1

Related Questions