Errata for Metal by Tutorials, 2nd Edition

Screen Shot 2020-05-13 at 4.40.39 PM

In Chapter 4, my computer found an error with the Final code running the matrices transform using, “let vertex = matrix * float4($0, 1)”

Hi - Did you try rebooting your computer? Sometimes playgrounds can get confused.

Also, could you provide more details about the Xcode version and your hardware, please? My playground works on a MacBook Pro 2019 (GPU Vega 20) and Xcode 11.4.1

An alternative you could try is:

let vertex = matrix * float4($0.x, $0.y, $0.z, 1)

I ended up retrying and updating my mac os. Trying tonight again to see if it works.

1 Like

@kekquistador Do you still have issues with this?

In the Camera.swift file we have the ArcballCamera class and we override the rotation variable. When the user wants to pan or rotate the view this variable is updated in the overridden rotate function at the bottom of the class. The problem is that when you try to rotate the view it throws the following error:

EXC_BAD_ACCESS(EXC_I386_GPFLT)

From what I can tell this is thrown when there is memory protection. So I assume we are accessing the rotation variable incorrectly (as the error suggests). But here comes the interesting part… I decided to check if I can print out to the console want is stored in the rotation variable. When I do that I can access the variable and see what the current value is.

My solution was to add print statements before each update of the rotation variable inside the rotate function like so:

Screen Shot 2020-07-11 at 3.31.05 AM

For some reason this actually works and I can’t figure out why. FYI if I remove any of those print statements, the very next access of rotation throws the same error as before. Also this only works if I specifically say “print(rotation.y)” or “print(rotation.x)”, and it throws the error if is simply say “print(rotation)”. It just seems so strange that this what fixes it. What is a better way of fixing this issue?

This should be fixed in Xcode 12?

The solution is to assign the whole [x, y, z] float3 value to the rotation at one time.

override func rotate(delta: float2) {
  let sensitivity: Float = 0.005
  var x = rotation.x + delta.y * sensitivity
  x = max(-Float.pi/2, min((x), Float.pi/2))
    
  let y = rotation.y + delta.x * sensitivity

  // Need to assign the whole [x, y, z] float3 value to the rotation at one time
  rotation = [x, y, 0]
  _viewMatrix = updateViewMatrix()
}
1 Like

Alternatively @barnetta came up with another solution here SIMD BADACCESS Error? - #18 by barnetta

ah, nope, my solution breaks in chapter 8 when the additional server is added to node, but yours still works

1 Like

If you want to overwrite the vertex array before drawing it, you need to have two separate data buffers.

Chapter 4, page 102

Shouldn’t this read “If you don’t want to overwrite the vertex array before drawing it, you need to have two separate data buffers?”

It actually should read “If you want to”, but perhaps the rest of the sentence could be better. How about:

“If you want to draw the same vertex array but in two different positions, then you’ll need two different buffers.”

Let me explain.

You want to draw the vertices twice. First in one position and then in another. Your code says

  1. set vertex positions in vertex array
  2. draw
  3. override the new vertex positions in the same vertex array
  4. draw

In a serial world, that would work. However, when drawing on the GPU, all draws are batched together. So steps 2 and 4 might be done simultaneously. This means that you need to maintain two different data sources to be able to do the drawing.

1 Like

Thanks for the quick response! And thanks for clarifying. This book has been amazing so far :smiley:

1 Like

I’m so glad you’re enjoying it :smiley:

I have been working through the 3D Graphics with Metal video course and this issue (EXC_BAD_ACCESS(EXC_I386_GPFLT)) appears in all of the projects after the ArcballCamera class was introduced.

@ericjenkinson - This should be fixed in the new Xcode beta - or does the post above help?

The solution above resolves the issue. I was just noting that it was present in the video course as well.

1 Like

Have anyone else had trouble running the starter (or final) playground in Ch4?

It looks like it’s having trouble reading Shaders.metal from the bundle.

This is the error I’m seeing:

**Fatal error: Unexpectedly found nil while unwrapping an Optional value: file N3DTransforms_Sources/Utility.swift, line 21**

1 Like

Hi @cisforcojo - thanks for bringing this to our attention :slight_smile:

It looks as if Apple have changed the way playgrounds access Metal shaders. You used to have to access it via the bundle, but it seems that we can now just use makeDefaultLibrary() as we do in an app.

So:

public func createLibrary() -> MTLLibrary {
  device.makeDefaultLibrary()!
}
1 Like

Wow, thanks so much for the quick response!

1 Like

Chapter 21 starter project.

Renderer.swift: vertexDescriptor should be defined:

  lazy var vertexDescriptor: MDLVertexDescriptor = {
    let vertexDescriptor = MDLVertexDescriptor()
    vertexDescriptor.attributes[0] =
      MDLVertexAttribute(name: MDLVertexAttributePosition,
                         format: .float3,
                         offset: 0, bufferIndex: 0)
    vertexDescriptor.attributes[1] =
      MDLVertexAttribute(name: MDLVertexAttributeNormal,
                         format: .float3,
                         offset: 0, bufferIndex: 1)
    vertexDescriptor.layouts[0] = MDLVertexBufferLayout(stride: MemoryLayout<float3>.stride)
    vertexDescriptor.layouts[1] = MDLVertexBufferLayout(stride: MemoryLayout<float3>.stride)
    return vertexDescriptor
  }()

The normal vertex attribute was defined as a float2, when it should be a float3.

1 Like