I created a 3D object using blender and exported it as an OBJ file and I tried to render it using Metal by following this http://metalbyexample.com/modern-metal-1 tutorial. But some of my 3D object parts are missing. They are not rendered properly.
Here is my 3D object in blender :-
Here is my rendered object in Metal :-
Here is my blender file :- https://gofile.io/?c=XfQYLK
How should i fix this?
I already rendered some other shapes like, rectangle, Circle, Star successfully. But the problem is with this shape. I did not change the way i create the shape nor the way it is exported from the blender. Even though I did everything in same way problem still there.
Here is how i load the OBJ file
private var vertexDescriptor: MTLVertexDescriptor!
private var meshes: [MTKMesh] = []
private func loadResource() {
let modelUrl = Bundle.main.url(forResource: self.meshName, withExtension: "obj")
let vertexDescriptor = MDLVertexDescriptor()
vertexDescriptor.attributes[0] = MDLVertexAttribute(name: MDLVertexAttributePosition, format: .float3, offset: 0, bufferIndex: 0)
vertexDescriptor.attributes[1] = MDLVertexAttribute(name: MDLVertexAttributeNormal, format: .float3, offset: MemoryLayout<Float>.size * 3, bufferIndex: 0)
vertexDescriptor.attributes[2] = MDLVertexAttribute(name: MDLVertexAttributeTextureCoordinate, format: .float2, offset: MemoryLayout<Float>.size * 6, bufferIndex: 0)
vertexDescriptor.layouts[0] = MDLVertexBufferLayout(stride: MemoryLayout<Float>.size * 8)
self.vertexDescriptor = MTKMetalVertexDescriptorFromModelIO(vertexDescriptor)
let bufferAllocator = MTKMeshBufferAllocator(device: self.device)
let asset = MDLAsset(url: modelUrl, vertexDescriptor: vertexDescriptor, bufferAllocator: bufferAllocator)
(_, meshes) = try! MTKMesh.newMeshes(asset: asset, device: device)
}
Here is my vertex and fragment shaders :-
struct VertexOut {
float4 position [[position]];
float4 eyeNormal;
float4 eyePosition;
float2 texCoords;
};
vertex VertexOut vertex_3d(VertexIn vertexIn [[stage_in]])
{
VertexOut vertexOut;
vertexOut.position = float4(vertexIn.position, 1);
vertexOut.eyeNormal = float4(vertexIn.normal, 1);
vertexOut.eyePosition = float4(vertexIn.position, 1);
vertexOut.texCoords = vertexIn.texCoords;
return vertexOut;
}
fragment float4 fragment_3d(VertexOut fragmentIn [[stage_in]]) {
return float4(0.33, 0.53, 0.25, 0.5);
}
And here my CommandEncoder :-
func render(commandEncoder: MTLRenderCommandEncoder) {
commandEncoder.setRenderPipelineState(self.renderPipelineState)
let mesh = meshes[0]
let vertexBuffer = mesh.vertexBuffers.first!
commandEncoder.setVertexBuffer(vertexBuffer.buffer, offset: vertexBuffer.offset, index: 0)
let indexBuffer = mesh.submeshes[0].indexBuffer
commandEncoder.drawIndexedPrimitives(type: mesh.submeshes[0].primitiveType,
indexCount: mesh.submeshes[0].indexCount,
indexType: mesh.submeshes[0].indexType,
indexBuffer: indexBuffer.buffer,
indexBufferOffset: indexBuffer.offset)
commandEncoder.endEncoding()
}
Presenting to the drawable is handled in a different place.
How should i properly render my 3D object using Metal?