ARKit-光影特效

本文主要介绍在AR中实现光照估计、环境光反射等相关知识,提高AR中虚拟物体渲染的真实性。

ARKit中的光照估计

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

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

ARLightEstimate类属性

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

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

下面演示如何启用光照估计并获取实时的光照估计值。(我选错了材质,导致不是很明显)

 

 代码

//

// ViewController.swift

// ARImage

//

// Created by mac on 2022/11/6.

//

import UIKit

import RealityKit

import ARKit

var isPlaced = false

var times: Int = 0

class ViewController: UIViewController {

lazy var arview:ARView = {

let arView = ARView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))

return arView

}()

override func viewWillAppear(_ animated: Bool) {

super.viewWillAppear(animated)

view.addSubview(arview)

}

override func viewDidLoad() {

super.viewDidLoad()

// Do any additional setup after loading the view.

let config = ARWorldTrackingConfiguration()

config.planeDetection = .horizontal

config.isLightEstimationEnabled = true

self.arview.session.run(config)

self.arview.session.delegate = arview

}

}

extension ARView: ARSessionDelegate{

public func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {

guard let anchor = anchors.first as? ARPlaneAnchor,!isPlaced else{return}

do{

let planeAnchor = AnchorEntity(anchor: anchor)

let box: MeshResource = .generateBox(size: 0.1,cornerRadius: 0.003)

var boxMaterial = SimpleMaterial(color: .blue, isMetallic: false)

boxMaterial.baseColor = try .texture(.load(named: "Box_Texture.jpg"))

boxMaterial.roughness = 0.8

let boxEntity = ModelEntity(mesh: box, materials: [boxMaterial])

planeAnchor.addChild(boxEntity)

self.installGestures(for: boxEntity)

self.scene.addAnchor(planeAnchor)

isPlaced = true

}

catch{

print("无法加载纹理图片")

}

}

public 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)")

times += 1

}

}

除了通用的光照估计,在使用ARFaceTrackingConfiguration配置运行ARSession时,ARKit会提供更多关于环境光照的估计信息,在这里不多赘述。

环境反射(反光的实现)

在使用RealityKit渲染虚拟物体时,RealityKit默认使用了一个简单的天空盒(Skybox,即IBL环境资源贴图),所有带反射材质的物体默认会对天空盒产生反射,但在AR中,存在的一个大问题就是不真实,不能实时地反映用户使用时的真实环境。

因此,我们引入了环境探头,环境探头理论上能够实时反映动态的环境,在RealityKit中,使用,ARWorldTrackingConfiguration配置类的environmentTexturing属性设置生成环境探头的方式,支持三种方式:None、Manual、Automatic,我们一般使用自动属性,为进一步增强反射的真实性,ARKit还支持环境探头配合wantsHDREnvironmentTextures属性使用,该属性为布尔值,用于设置是否使用HDR反射,HDR图像能更真实地反射现实环境的亮度差,高保真还原真实环境信息。

使用方法:

config.environmentTexturing = .automatic

config.wantsHDREnvironmentTextures = true

在使用自动环境反射时:开发人员无需进行有关环境反射的任何操作,只需要设置自动环境反射即可,其余工作完全由RealityKit自动完成,这适用于基本的常见环境反射。但这种环境反射方案是一种普适性的反射,并没有专门针对某特定虚拟元素进行优化,在这种情况下效果并不精细,并且我们也无法进行干预调优,如一辆行驶的赛车对环境的反射就需要更精细的控制,这时就需要手动控制环境探头的生成及更新。

使用手动控制环境探头时,我们需要将配置中的environmentTexturing属性设置为manual,并决定在什么地方、什么时候设置与更新环境探头。通常而言,可以遵循以下流程:

(1)在场景中某个特定位置创建AREnvironmentProbeAnchor锚点

(2)将创建的AREnvironmentProbeAnchor锚点添加到ARSession中

(3)使用session(_:didUpdate:)代理方法根据需要更新环境探头

精彩文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: