首页 > 其他分享 >【iOS ARKit】光照估计

【iOS ARKit】光照估计

时间:2024-01-29 17:38:08浏览次数:33  
标签:估计值 frame iOS ARKit session let estimatLight 光照

光照估计

        AR与VR 在光照上最大的不同在于VR 世界是纯数字世界,有一套完整的数学模型,而AR则是将计算机生成的虚拟物体或关于真实物体的非几何信息叠加到真实世界的场景之上实现对真实世界的增强,融合了真实世界与数字世界。就光照而言,VR中的光照完全由开发人员决定,光照效果是一致的,即不会受到运行时其他因素的影响,而AR 中则不得不考虑真实世界的光照与虚拟的3D光照信息的一致性,举个例子,假如在AR 3D应用中设置了一个模拟太阳的高亮度方向光,而用户是在晚上使用这个 AR应用,如果不考虑光照一致性,那么渲染出来的虚拟物体的光照与真实世界其他物体的光照反差将会非常明显,由于人眼对光照信息的高度敏感性,这种渲染可以说是完全失败的,完全没有沉浸感。在AR 中,由于用户与真实世界的联系并未被切断,光照的交互方式也要求更自然,如果真实世界的阴影向左而渲染出来的虚拟物体图影向右,这也是让人难以接受的,所以在 AR 中,必须要能达到虛拟光照与真实光照的一致,虚拟物体渲染出来的阴影应与真实环境中的阴影基本保持一致,这样才能提商虛拟物体的可信度和真实感。

ARKit 中的光照估汁

     ARKit 支持对用户所处环境光照信息的估计,在 ARConfiguration 类中定义了 isLightEstimationEnabled 布尔属性用于开启和关闭光照估计,该功能默认为启用状态。由于 ARConfiguration 是所有其他配置类的父类,因此 ARKit所有的配置类都支持光照估计功能。

     当设置 isLightEstimationEnabled 值为true 时,ARKit 每帧都会对从设备摄像头中采集的图像进行光照估计计算,并且将估计值保存在 frame. lightEstimate 属性中,frame. lightEstimate 是 ARLightEstimate类的实例,ARLightEstimate类只包含两个属性,

  1. 环境光强度值 (ambientIntensity) 取值范围[0,2000],在光照条件良好的环境中,该值约为1000,0表示环境非常黑暗,2000表示环境非常明亮
  2. 环境光温度值(ambientColorTemperature) 单位开尔文(K),纯白光次6500,低于该值表示环境更温暖,更偏向于黄光或者橘黄光,而高于该值表示环境更冷,更偏向于蓝光

     在 RealityKit 中,一般情况下开发人员无须关注 frame. lightEstimate 中的值,当设置 isLightEstimationEnabled值为 true 时,RealityKit 会自动使用环境光照估计值渲染虚拟元素的光照。但在使用自定义渲染时,开发人员必须自行处理光照估计。

    但在一些情况下,我们也可能需要实时获取当前环境光照估计值,如根据环境光照动态调整特效类型,下面演示如何启用光照估计并获取实时的光照估计值,如代码所示。

//
//  LightEstimate.swift
//  ARKitDeamo
//
//  Created by zhaoquan du on 2024/1/29.
//

import SwiftUI
import ARKit
import RealityKit
import Combine

struct LightEstimate: View {
    @State var isFaceTracking = false
    var body: some View {
        LightEstimateContainer(isFaceTracking: isFaceTracking)
            .overlay(content: {
                VStack{
                    Spacer()
                    
                        Button {
                            isFaceTracking.toggle()
                        } label: {
                            
                            Text( !isFaceTracking ? "人脸追踪光照": "普通光照估计")
                                .frame(width:150,height:50)
                                .font(.system(size: 17))
                                .foregroundColor(.black)
                                .background(Color.white)
                            
                                .opacity(0.6)
                                
                        }
                            
                        .cornerRadius(10)
                        Spacer().frame(height: 40)
                    
                    

                }
            })
            .edgesIgnoringSafeArea(.all)
            .navigationTitle("光照估计")
    }
}

struct LightEstimateContainer: UIViewRepresentable {
    var isFaceTracking: Bool = false
    init(isFaceTracking: Bool = false) {
        self.isFaceTracking = isFaceTracking
    }
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)
        
        
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
        if isFaceTracking {
            
            let config = ARFaceTrackingConfiguration()
            config.isLightEstimationEnabled = true
            uiView.session.delegate = context.coordinator
            context.coordinator.times = 0
            uiView.session.run(config, options: [.resetTracking,.removeExistingAnchors])
            return
        }
        
        let config = ARWorldTrackingConfiguration()
        config.planeDetection = .horizontal
        config.isLightEstimationEnabled = true
        
        context.coordinator.arView = uiView
        uiView.session.delegate = context.coordinator
        uiView.session.run(config)
        
        
    }
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    
    class  Coordinator: NSObject,ARSessionDelegate {
        var arView:ARView? = nil
        var isPlaced = false
        var times = 0
        var parent: LightEstimateContainer
        init(parent: LightEstimateContainer) {
            self.parent = parent
        }
        
        func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
            guard let anchor = anchors.first as? ARPlaneAnchor,!isPlaced else {
                return
            }
            do {
                let planEntity = AnchorEntity(anchor: anchor)
                let mesh = MeshResource.generateBox(size: 0.1, cornerRadius: 0.003)
                let texture = MaterialParameters.Texture.init(try TextureResource.load(named: "Box_Texture.jpg"))
                var meterial = SimpleMaterial(color: .blue,roughness: 0.8 ,isMetallic: false)
                meterial.color = .init(tint:.blue,texture:texture)
                
                let modelEntity = ModelEntity(mesh: mesh, materials: [meterial])
                planEntity.addChild(modelEntity)
                
                arView?.installGestures(for:modelEntity)
                arView?.scene.addAnchor(planEntity)
                
            }catch{
                print("无法加载纹理")
            }
        }
        
        func session(_ session: ARSession, didUpdate frame: ARFrame) {
            guard let estimatLight = frame.lightEstimate , times < 10 else {return }
            print("light intensity: \(estimatLight.ambientIntensity),light temperature: \(estimatLight.ambientColorTemperature)")
            if let estimatLight = frame.lightEstimate as? ARDirectionalLightEstimate {
                print("primary light direction: \(estimatLight.primaryLightDirection), primary light intensity: \(estimatLight.primaryLightIntensity)")
            }
            times += 1
            
        }
    }
}

        代码中代码逻辑非常清晰,我们使用 session(:didUpdate frame:)代理方法实时地获取每一帧的光照估计值,并打印了光照估计值强度及色温信息。运行代码,在检测到的水平平面上加载木箱物体后,改变真实环境中的光照,可以看到虚拟的木箱光照信息也发生了明显的变化。

  • 经过测试,发现在使用 RealityKit 渲染时,即使设置 isLightEstimation Enabled 为 false 也会在渲染虛拟元素时考虑光照估计,但此时无法从 frame. lightEstimate 中获取光照估计值。

      除了通用的光照估计,在使用 ARFaceTrackingConfiguration 配置运行 ARSession 时,ARKit 会提供更多关于环境光照的估计信息。在使用 ARFace TrackingConfiguration 配置运行 ARSession,当设置 isLightEstimationEnabled 值为 true 时,ARKit 每帧都会对从设备摄像头中采集的图像进行光照估计计算,并且将估计值保存在 frame. lightEstimate 属性中,但此时 frame. lightEstimate 为 ARDirectionalLightEstimate 类的实例,ARDirectionalLightEstimate类为 ARLightEstimate 的子类,不仅包括 ARLightEstimate 中的属性,还包含另外3个光照估计值属性。

  • primary LightDirectio 场景中最强光线的方向向量,这是一个在世界空间中归一化的向量
  • primary LightIntensit  场景中最强光线的光照强度,单位为流明,取值范围[0,2000],在光照条件良好的环境中,该值约在1000,0表示环境非常黑暗,2000表示环境非常明亮
  • spherical HarmonicsCoefficients  对环境中多个光源方向与强度的综合表达。球谐因子提供了一种在某点反映全局环境光照信息的简洁紧凑模型,描述了在该点的多个光源光照分布与颜色值。在IML. 渲染中,球谐因子非常高效。ARKit 光照估计提供二级(Second level)红、绿、蓝分离的3通道球谐因子,总数据包括3级9个因子,总计27个32位的浮点值。

      在Reality Kit 中,开发人员亦无须关注这些光照估计值,当设置 isLightEstimationEnabled 值为 true5,Reality Kit就会自动使用环境光照估计值渲染虚拟元素。但在使用自定义谊染时,开发人员必须自己处理光照估计。下面代码是演示在使用 ARFaceTrackingConfiguration 配置时,启用光照估计并获取实时的光照估计值。

​

​func updateUIView(_ uiView: ARView, context: Context) {
        
            
            let config = ARFaceTrackingConfiguration()
            config.isLightEstimationEnabled = true
            uiView.session.delegate = context.coordinator
            context.coordinator.times = 0
            uiView.session.run(config, options: [.resetTracking,.removeExistingAnchors])
            return
        
        
        
    }
 
 
func session(_ session: ARSession, didUpdate frame: ARFrame) {
            guard let estimatLight = frame.lightEstimate , times < 10 else {return }
            print("light intensity: \(estimatLight.ambientIntensity),light temperature: \(estimatLight.ambientColorTemperature)")
            if let estimatLight = frame.lightEstimate as? ARDirectionalLightEstimate {
                print("primary light direction: \(estimatLight.primaryLightDirection), primary light intensity: \(estimatLight.primaryLightIntensity)")
            }
            times += 1
            
        }

 

具体代码地址:https://github.com/duzhaoquan/ARkitDemo.git

 

 

标签:估计值,frame,iOS,ARKit,session,let,estimatLight,光照
From: https://www.cnblogs.com/duzhaoquan/p/17994952

相关文章

  • iOS ARKit 光照效果之光源
    光照   在现实世界中,光扮演了极其重要的角色,没有光万物将失去色彩,没有光世界将一片漆黑。在3D数字世界中亦是如此,3D数字世界本质上是一个使用数学精确描述的真实世界复本,光照计算是影响这个数字世界可信度的极其重要的因素。光源   顾名思义,光源即是光的来源,常见......
  • 【教程】iOS 手机抓包工具介绍及教程
    ......
  • iOS应用崩溃了,如何通过崩溃手机连接电脑查找日志方法
    ​在iOS应用开发过程中,调试日志和奔溃日志是开发者必不可少的工具。当iOS手机崩溃时,我们可以连接电脑并使用XcodeConsole等工具来查看日志。然而,这种方式可能不够方便,并且处理奔溃日志也相当繁琐。克魔助手的出现为开发者带来了极大的便利,本文将详细介绍其功能和使用方法。克魔......
  • 2024最新苹果iOS17.3微信分身详解分享
    微信是目前最流行的社交软件之一,拥有庞大的用户群体。然而,对于一些需要同时使用多个微信账号的用户来说,使用官方版微信就显得有些不方便。iOS分身微信软件可以解决这个问题,它可以让用户在同一台设备上同时登录多个微信账号,从而实现工作生活两不误。iOS分身微信软件的优势iOS......
  • iOS 17.4 测试版包含大模型相关代码
    外界普遍预计苹果将在6月份通过iOS18推出主要的新人工智能功能。不过根据9to5Mac的报道,他们在iOS17.4第一个测试版中发现的代码表明,苹果正在开发由大语言模型技术支持的Siri新版本,并得到了其他来源的一些帮助。所谓其他来源是指苹果似乎正在使用OpenAI的ChatGPTA......
  • BIOS
    BIOS(BasicI/OSystem,基本输入输出系统)是计算机启动时自动执行的一组程序,位于计算机主板上的ROM(只读存储器)中.BIOS的主要功能是初始化计算机硬件,并进行自检,确保硬件设备正常运作.此外,BIOS还负责加载操作系统,为操作系统提供硬件控制和管理功能.BIOS在计算机启动过程中分为......
  • 描述文件错误:如何屏蔽 iOS 软件自动更新,去除更新通知和标记
    描述文件错误:如何屏蔽iOS软件自动更新,去除更新通知和标记适用于iOS、iPadOS和watchOS,即iPhone、iPad和AppleWatch通用请访问原文链接:https://sysin.org/blog/disable-ios-update/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org如何禁用iPhone、iPad和A......
  • 标准光照Shader
    思路《Shader入门精要》看到第九章,试着结合前面的知识实现一个标准光照模型,采用Blin-Phong模型,分为三大部分环境光,漫反射,高光反射。实现过程中加入凹凸效果,阴影效果。注释部分是透明效果,采用透明度测试的方法实现。具体细节见代码代码//UpgradeNOTE:replaced'mul(UNITY_MAT......
  • iOS 中 深拷贝和浅拷贝的区别
    在iOS开发中,深拷贝和浅拷贝是两种不同的对象复制方式,它们在处理NSArray、NSMutableArray以及其他集合类型时尤为重要。浅拷贝(ShallowCopy)浅拷贝仅复制对象的指针,而不复制对象本身。如果你对一个对象进行浅拷贝,新对象和原对象将指向相同的内存地址。这意味着如果你修改了其中一......
  • 【iOS ARKit】同时开启前后摄像头BlendShapes
       在上一节中已经了解了iOSARkit进行BlendShapes的基本操作,这一小节继续实践同时开启前后摄像头进行人脸捕捉和世界追踪。   iOS设备配备了前后两个摄像头,在运行AR应用时,需要选择使用哪个摄像头作为图像输人。最常见的AR体验使用设备后置摄像头进行世界跟踪、......