代码之家  ›  专栏  ›  技术社区  ›  halileohalilei

使用MTLTexture作为SCNScene的环境映射

  •  31
  • halileohalilei  · 技术社区  · 7 年前

    我想设定一个 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 它可以得到,但这也不起作用。

    编辑:您可以在中查看示例项目 this 回购并使用它复制此用例。

    1 回复  |  直到 3 年前
        1
  •  2
  •   Andy Jazz    3 年前

    使用MTK纹理照明SCN环境

    在iOS 15.4应用程序的macOS 12.3.1上使用Xcode 13.3.1。


    诀窍是,环境照明需要立方体纹理,而不是平面图像。

    • 为MetalKit立方体纹理创建6个方形图像

    enter image description here

    • 在Xcode中 Assets 文件夹创建立方体纹理集

    enter image description here

    • 将纹理放置到相应的槽中

    enter image description here

    • 如果需要,水平和垂直镜像图像

    enter image description here

    粘贴代码:

    import ARKit
    import MetalKit
    
    class ViewController: UIViewController {
    
        @IBOutlet var sceneView: ARSCNView!
        
        override func viewDidLoad() {
            super.viewDidLoad()    
            let scene = SCNScene()
            
            let imageName = "CubeTextureSet"
            let textureLoader = MTKTextureLoader(device: sceneView.device!)
    
            let environmentMap = try! textureLoader.newTexture(name: imageName, 
                                                        scaleFactor: 2, 
                                                             bundle: .main, 
                                                            options: nil)
            
            let daeScene = SCNScene(named: "art.scnassets/testCube.dae")!
    
            let model = daeScene.rootNode.childNode(withName: "polyCube", 
                                                 recursively: true)!
            
            scene.lightingEnvironment.contents = environmentMap
            scene.lightingEnvironment.intensity = 2.5
            scene.background.contents = environmentMap
    
            sceneView.scene = scene
            sceneView.allowsCameraControl = true
            scene.rootNode.addChildNode(model)
        }
    }
    

    将金属材料应用于模型。现在MTL环境照明已打开。

    enter image description here

    如果需要程序性skybox纹理,请使用 MDLSkyCubeTexture

    而且 this post 可能对你有用。