使用MTLTexture作为SCNScene的环境映射

时间:2017-12-10 13:14:23

标签: ios swift scenekit metal mtlbuffer

我想将MTLTexture对象设置为场景的环境贴图,因为根据documentation似乎是可能的。我可以使用以下代码将环境贴图设置为UIImage

let roomImage = UIImage(named: "room")
scene.lightingEnvironment.contents = roomImage

这很有效,我看到了金属物体上图像的反射。我尝试将图像转换为MTLTexture,并使用以下代码将其设置为环境贴图:

let roomImage = UIImage(named: "room")
let loader = MTKTextureLoader(device: MTLCreateSystemDefaultDevice()!)
let envMap = try? loader.newTexture(cgImage: (roomImage?.cgImage)!, options: nil)
scene.lightingEnvironment.contents = envMap

然而,这不起作用,我最终得到一个空白的环境地图,没有反射我的物体。

此外,我没有将options设置为nil,而是尝试将MTKTextureLoader.Option.textureUsage密钥设置为可以获得的every possible value,但这也不起作用。< / p>

编辑:您可以查看this repo中的示例项目,并使用它来重现此用例。

1 个答案:

答案 0 :(得分:0)

我认为问题是用于创建MTLTexture对象的标准分配和初始化技术。

使用MTLTexture协议–一种内存分配,用于存储GPU可以访问的格式化图像数据。

  

纹理数据可以同步或异步加载。 MTKTextureLoader方法返回符合MTLTexture协议的对象,但是该类不会为您管理该对象。 请勿使用标准的分配和初始化技术来创建MTLTexture对象。

在iOS中,MTLBuffer协议的makeTexture(descriptor:offset:bytesPerRow:)方法创建并返回一个新的纹理对象,该对象共享源缓冲区对象的存储分配作为其纹理图像数据。由于它们共享相同的存储空间,因此新纹理像素的任何更改都会反映在源缓冲区中,反之亦然。

let mtlTex = buffer.makeTexture(descriptor: descriptor, 
                                    offset: 0, 
                               bytesPerRow: array.count * MemoryLayout.size)