【问题标题】:How to use environment map in ARKit?如何在 ARKit 中使用环境贴图?
【发布时间】:2018-06-08 23:55:29
【问题描述】:

ARKit 2.0 添加了一个名为 AREnvironmentProbeAnchor 的新类。阅读它的说明,似乎 ARKit 可以自动收集环境纹理(立方体贴图?)。我相信我们现在可以创建一些反映真实环境的虚拟对象。

但我仍然不清楚这是如何工作的,尤其是环境纹理是如何生成的。有没有人有简单的示例代码来演示这个很酷的功能?

【问题讨论】:

    标签: swift augmented-reality arkit ios12


    【解决方案1】:

    AREnvironmentProbeAnchor(适用于 iOS 12 及更高版本)是基于图像的照明技术的锚。场景中 3D 模型的着色器可以反射周围环境的光(当然,取决于该着色器中表面的类型,所以让它成为反射铬)。原理很简单:来自 6 个照相机的 6 个正方形图像进入着色材料的 env 反射率通道。这六台摄像机(一个钻机)的方向如下:+x/-x+y/-y+z/-z。此操作 ARKit 为您提供完全免费的服务。下图说明了钻机的 6 个方向:

    相邻摄像头的 zFar 平面看起来像 Cube,不是吗?

    六个摄像头的平截头体就是这个Cube的体积。

    Texture 的补丁将在您的相机扫描表面的特定位置可用。或者,您可以使用先进的机器学习算法(它更强大,对用户来说更容易)来覆盖具有完整 360 度纹理的立方体。

    AREnvironmentProbeAnchor 用于将此照片装备定位到场景中的特定点。您需要为 AR 会话启用纹理贴图生成。有两种选择:

    ARWorldTrackingConfiguration.EnvironmentTexturing.manual 
    

    使用manual 环境纹理,您可以通过创建AREnvironmentProbeAnchor 对象并将它们添加到会话中来识别场景中需要光探测纹理贴图的点。

    ARWorldTrackingConfiguration.EnvironmentTexturing.automatic 
    

    使用automatic 环境纹理,ARKit 会自动创建、定位和添加 AREnvironmentProbeAnchor 对象到会话中。

    在这两种情况下,ARKit 都会在会话收集相机图像时自动生成环境纹理。使用诸如session(_:didUpdate:) 之类的委托方法来找出纹理何时可用,并从锚点的environmentTexture 属性访问它。

    如果您使用 ARSCNView 和 automaticallyUpdatesLighting 选项显示 AR 内容,SceneKit 会自动检索 AREnvironmentProbeAnchor 纹理贴图并使用它们来照亮场景。

    ViewController.swift 中的代码必须如下所示:

    sceneView.automaticallyUpdatesLighting = true
    
    let torusNode = SCNNode(geometry: SCNTorus(ringRadius: 2, pipeRadius: 1.5))
    sceneView.scene.rootNode.addChildNode(torusNode)
        
    let reflectiveMaterial = SCNMaterial()
    reflectiveMaterial.lightingModel = .physicallyBased
    reflectiveMaterial.metalness.contents = 1.0
    reflectiveMaterial.roughness.contents = 0
    reflectiveMaterial.diffuse.contents = UIImage(named: "brushedMetal.png")
    torusNode.geometry?.firstMaterial = [reflectiveMaterial]
    
    let configuration = ARWorldTrackingConfiguration()
    if #available(iOS 12.0, *) {
        configuration.environmentTexturing = .automatic      // WHERE A MAGIC HAPPENS
    }
    sceneView.session.run(configuration)
    
    func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
        print(anchors)
    }
    

    就是这样。希望这会有所帮助。

    附注任何 3D 相机不仅可以充当照片/摄像机,还可以充当投影仪(用于在物体上投影纹理)。

    【讨论】:

    • 嗨,安迪,感谢您的回复!我尝试设置 ARWorldTrackingConfiguration.EnvironmentTexturing 和 ARSCNView.automaticallyUpdatesLighting,但没有看到图像有任何差异。是否有演示此新功能的示例?即使是屏幕截图也会有很大帮助。
    • 我了解立方体贴图的一般工作原理。但我的问题是它如何在 ARKit 中使用这个新功能。特别是立方体贴图的生成方式以及应用程序的行为方式。例如,如果我在桌子上放一个虚拟球体,它的顶部应该反映天花板。如果我从来没有把手机竖起来,ARKit 怎么能得到天花板的图像?还是需要我在纹理可用之前将手机指向所有方向?如果是这样,应用程序将如何运行?球体会在纹理可用之前为空(白色?),而在生成立方体贴图后突然变得反光吗?
    • 是的,我使用的是 iOS 12 beta 和 XCode 10
    • 是的,它确实要求您在纹理可用之前将手机指向所有方向!
    • 您有示例代码或视频展示整个过程的样子吗?
    【解决方案2】:

    在您的 AR 项目中实现 environmentTexturing 非常简单。

    1. 将您的跟踪配置中的 environmentTexturing 属性设置为自动(ARKit 从您的摄像头获取视频以自动创建纹理贴图。您移动摄像头的次数越多,纹理贴图就越准确。机器学习用于填空)

      configuration.environmentTexturing = .automatic
      
    2. 环境纹理需要基于物理的材料才能工作。 创建一个简单的闪亮球体来测试反射

      let sphere = SCNSphere(radius: 0.1)
      sphere.firstMaterial?.diffuse.contents = UIColor.white
      sphere.firstMaterial?.lightingModel = .physicallyBased
      sphere.firstMaterial?.metalness.intensity = 1.0
      sphere.firstMaterial?.roughness.intensity = 0.0
      let sphereNode = SCNNode(geometry: sphere)
      sceneView.scene.rootNode.addChildNode(sphereNode)
      

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 1970-01-01
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      • 2020-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多