# iOS 8 Metal Tutorial with Swift Part 2: Moving to 3D

**URL:** <https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637>\
**Category:** 🎓 Courses & Articles\
**Created:** [March 4, 2016, 10:57am UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637 "2016-03-04T10:57:18Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![haawa](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/haawa/32/97362_2.png) [@haawa](https://forums.kodeco.com/u/haawa)\
**Post date:** [March 4, 2016, 10:57am UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/1 "2016-03-04T10:57:18Z")

</div>

Learn how to use matrices and 3D transformations in this iOS 8 Metal Tutorial with Swift!

* * *
 This is a companion discussion topic for the original entry at [https://www.raywenderlich.com/2205-ios-8-metal-tutorial-with-swift-part-2-moving-to-3d](https://www.raywenderlich.com/2205-ios-8-metal-tutorial-with-swift-part-2-moving-to-3d)

---

<div class="post-metadata">

**Author:** ![oposum](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/oposum/32/5649_2.png) [@oposum](https://forums.kodeco.com/u/oposum)\
**Post date:** [March 6, 2016, 11:10am UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/2 "2016-03-06T11:10:05Z")

</div>

Hello,  
I’m interested in depth testing faces for render. Backface culling is great but only for covex types of geometry. More complex types will show errors at render.  
Tnx

---

<div class="post-metadata">

**Author:** ![mrjingles](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/mrjingles/32/6069_2.png) [@mrjingles](https://forums.kodeco.com/u/mrjingles)\
**Post date:** [March 7, 2016, 12:38pm UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/3 "2016-03-07T12:38:54Z")

</div>

Very nicely done tutorial. I would be very much interested in more.  
And can all of this also be done without Shaders? Or is everything honed to work in only this way?

Problem with the tutorial at this point is that seemingly only one object can be visualized. If I create another cube, only one of them is drawn. I can draw both if I get myself a new drawable from the Metal Layer, but then the objects kind of flicker.

MrJingles

---

<div class="post-metadata">

**Author:** ![amarincas](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/amarincas/32/11380_2.png) [@amarincas](https://forums.kodeco.com/u/amarincas)\
**Post date:** [March 25, 2016, 1:23pm UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/4 "2016-03-25T13:23:51Z")

</div>

@mrjingles

I know this is late reply but I was asking myself the same question after first reading this tutorial. I think both cubes should be encoded into the same command buffer by the same render encoder. So the render pass descriptor, the command buffer and the render encoder should belong to the ViewController and each Node should receive the render encoder to render into by drawing its primitives. After all nodes did their drawPrimitives() then the ViewController should finalize rendering, i.e. endEncoding() on the render encoder, presentDrawable() on the command buffer and finally commit() the command buffer.

---

<div class="post-metadata">

**Author:** ![wilshipley](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/wilshipley/32/37482_2.png) [@wilshipley](https://forums.kodeco.com/u/wilshipley)\
**Post date:** [July 22, 2016, 11:27pm UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/5 "2016-07-22T23:27:40Z")

</div>

Thanks for writing this tutorial!

However, I don’t think you can safely use Matrix4 to make your projection matrix. Metal has a different device space definition than OpenGL - z goes -1…1 in Metal, and 0…1 in GL.

If you use a GL projection matrix it will work if you have TONS of extra room on your ‘near’ value, but doing that ends up making your rendering less precise because it squishes the values in the z buffer.

---

<div class="post-metadata">

**Author:** ![rahulsan](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/rahulsan/32/37564_2.png) [@rahulsan](https://forums.kodeco.com/u/rahulsan)\
**Post date:** [July 24, 2016, 3:47pm UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/6 "2016-07-24T15:47:57Z")

</div>

Thanks for this tutorial and a great introduction to Metal. Just one question, after I refactor from the previous tutorial a triangle renders on only half the view. What could be the reason ?

---

<div class="post-metadata">

**Author:** ![haawa](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/haawa/32/97362_2.png) [@haawa](https://forums.kodeco.com/u/haawa)\
**Post date:** [August 9, 2016, 7:00am UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/7 "2016-08-09T07:00:48Z")

</div>

Thanks for reaching out! I will investigate this question.

---

<div class="post-metadata">

**Author:** ![iphonebell](https://s3.amazonaws.com/cdn.raywenderlich.com/community/forum-assets/noun-game-ghost-878668.png) [@iphonebell](https://forums.kodeco.com/u/iphonebell)\
**Post date:** [August 11, 2016, 11:28pm UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/8 "2016-08-11T23:28:37Z")

</div>

I have gone through this tutorial again but with the latest Xcode beta and iOS 10 beta and there is an issue just after creating the worldModelMatrix.  
When run, the app crashes and the following message is displayed (regarding the render method):

“fatal error: unexpectedly found nil while unwrapping an Optional value”

It is objectToDraw = (HelloMetal.cube!) nil which is the issue.

---

<div class="post-metadata">

**Author:** ![sarbartha](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/sarbartha/32/39929_2.png) [@sarbartha](https://forums.kodeco.com/u/sarbartha)\
**Post date:** [August 29, 2016, 5:24am UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/9 "2016-08-29T05:24:58Z")

</div>

Well I was trying to get the depth Buffer and finally able to do it myself. Sharing it here for other’s help:

In ViewController add the following variable:

> ```
> var depthStencilState: MTLDepthStencilState! = nil
> 
> ```

Then add the following lines in the viewDidLoad() function:

> let depthStencilDescriptor = MTLDepthStencilDescriptor()  
> depthStencilDescriptor.depthCompareFunction = .Less  
> depthStencilDescriptor.depthWriteEnabled = true  
> depthStencilState = try! device.newDepthStencilStateWithDescriptor(depthStencilDescriptor)

In Node.swift Update the signature of renderer function signature to

> func render(commandQueue: MTLCommandQueue, pipelineState: MTLRenderPipelineState,depthStencilState: MTLDepthStencilState, drawable: CAMetalDrawable, parentModelViewMatrix: Matrix4, projectionMatrix: Matrix4, clearColor: MTLClearColor?)

Now fine the following line in that function:

> ```
> renderEncoder.setRenderPipelineState(pipelineState)
> 
> ```

and add the following line right after the above line:

> ```
> renderEncoder.setDepthStencilState(depthStencilState)
> 
> ```

Finally update the calling statement as follows:

> objectToDraw.render(commandQueue, pipelineState: pipelineState,depthStencilState: depthStencilState, drawable: drawable, parentModelViewMatrix: worldModelMatrix, projectionMatrix: projectionMatrix, clearColor: nil)

---

<div class="post-metadata">

**Author:** ![jly122](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/jly122/32/44835_2.png) [@jly122](https://forums.kodeco.com/u/jly122)\
**Post date:** [October 20, 2016, 4:01am UTC](https://forums.kodeco.com/t/ios-8-metal-tutorial-with-swift-part-2-moving-to-3d/6637/10 "2016-10-20T04:01:09Z")

</div>

You should check the following code in Node.swift  
`renderEncoderOpt.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: 3, instanceCount: 1)`

it must be replaced as:

`renderEncoderOpt.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: vertexCount, instanceCount: 1)`
