如何从磁盘文件中指定与 iOS 模拟器兼容的金属纹理格式?

How do you specify a Metal texture format that's compatible with the iOS Simulator from an on-disk file?

为起点,我正在尝试做类似的事情。从 post 中提取 .jpg 纹理,我的代码在真实设备上运行得很好,但在模拟器中却失败了。原因似乎是因为图像格式。

Apple's documentation here 中所述,您不能使用 MTLPixelFormat.r8Unorm_srgb 格式,我相信该纹理的编码格式基于以下错误:

failed assertion `pixelFormat (11) is not a valid MTLPixelFormat.'

正在尝试了解如何更改格式,但不知道如何着手。我不知道它是否可以在创建时加载到特定颜色 space,或者我是否必须在 Photoshop 中做一些特定的事情,甚至可能完全改变文件类型,但即使在那里,我也做不到查看如何关闭颜色配置文件,只需将它们更改为其他内容即可。

那么,有没有人知道如何 create/load 一种也与模拟器兼容的纹理?

更新

有人问,我是这样设置纹理的。

let noiseImage = UIImage(resourceName: "Noise", extension: "jpg")!
myMaterial.setValue(SCNMaterialProperty(contents: noiseImage), forKey: "noiseTexture")

这是上面使用的便利初始化器...

extension UIImage {

    convenience init?(resourceName:String, extension:String? = nil, bundle:Bundle? = nil) {

        let bundle = bundle ?? Bundle.main

        guard let resourceFileName = bundle.path(forResource: resourceName, ofType: `extension`) else {
            return nil
        }

        self.init(contentsOfFile: resourceFileName)
    }
}

这似乎是 SceneKit 中的一个错误,它没有说明 iOS 模拟器不支持某些像素格式这一事实。您可以通过使用 MetalKit 手动创建金属纹理来解决它:

let textureLoader = MTKTextureLoader(device: scnView.device!)

let noiseImage = UIImage(resourceName: "Noise", extension: "jpg")?.cgImage
let texture = try! textureLoader.newTexture(cgImage: noiseImage!, options: [:])
myMaterial.setValue(SCNMaterialProperty(contents: texture), forKey: "noiseTexture")