I am getting images just like the one in this question:
Confused about thread_position_in_grid
The dark black color is in the lower-left corner, which means the gid.x
and gid.y
are both 0
in that part of the image. Yet the Metal docs (as well as answers like this: What is the coordinate system used in metal?) state that the origin is in the upper left corner, which means that should be where you see the dark black corner.
Why does this seem to not be the case?
I view the texture using CoreImage. I make a CIImage
like so:
CIImage(mtlTexture: kernelOutputTexture,
options: [CIImageOption.colorSpace: colorSpace])!
And then I view it in NSImageView like so:
let rep = NSCIImageRep(ciImage: image)
let nsImage = NSImage(size: rep.size)
nsImage.addRepresentation(rep)
Core Image uses a coordinate system whose origin is in the bottom-left of the image. Although you might suspect that it would account for Metal's top-left origin when wrapping a MTLTexture
, it appears this is not the case.
To create a CIImage
whose orientation matches that of the original texture, you can request a new image that has been vertically flipped:
image = image.transformed(by: image.orientationTransform(for: .downMirrored))
The orientationTransform(for:)
method was introduced in iOS 11.0
and macOS 10.13. Using it is likely more robust than composing your own affine transform, and is also quite efficient, since Core Image uses lazy evaluation rather than physically moving or copying the underlying data.