ARKit系列文章目录node
本文是Ray Wenderlich上《ARKit by Tutorials》的读书笔记,主要讲内容概要和读后感 swift
ARKit的主要局限性:session
func session(_ session: ARSession,
cameraDidChangeTrackingState camera: ARCamera) {
switch camera.trackingState {
// 1
case .notAvailable:
trackingStatus = "Tracking: Not available!"
// 2
case .normal:
trackingStatus = "Tracking: All good!"
// 3
case .limited(let reason):
switch reason {
case .excessiveMotion:
trackingStatus = "Tracking: Limited due to
excessive motion!"
// 3.1
case .insufficientFeatures:
trackingStatus = "Tracking: Limited due to
insufficient features!"
// 3.2
case .initializing:
trackingStatus = "Tracking: Initializing..."
// 3.3
case .relocalizing:
trackingStatus = "Tracking: Relocalizing..."
}
}
}
}
复制代码
能够打开AR视图的debug选项来帮助调试:app
sceneView.debugOptions = []
复制代码
可配置项以下:async
在SceneKit中可用的光照模型(着色器)以下: ide
PBR光照模型是新引入的特性,可让你的3D物体看起来更真实.工具
下面咱们来重点学习一下其中的特性:post
环境贴图是一种cube map立方体贴图,好比天空盒子shybox是这样的: 学习
环境贴图有两方面做用:一方面相似于reflection map反射贴图,能够在高反射率表面看到环境图像的反射;另外一方面,对于支持PBR的3D物体,能够提供真实的光照环境.以下: 测试
漫反射贴图提供基础颜色,无需考虑灯光和其它特效.
所谓法线,就是垂直于几何体表面的向量.能够用来计算光线的反射等效果.
法线贴图经过图片的RGB通道来定义了像素级的表面法线.用来与光线混合计算,模拟表面的凹凸效果.这样无需增长多边形及顶点数据,就模拟出了真实的表面.
高度贴图并非PBR光照模型的一部分,可是也值得你们学习.高度贴图是黑白图像,白色表明物体的最高点,黑色表明最低点.
高度贴图和法线贴图能够互相转换,网上有免费工具Normal Map Online — available at bit.ly/1ELCePX
也就是ambient occlusion map环境光闭塞贴图(OA贴图).用来阻止环境光照亮闭塞的区域,好比墙壁上的裂缝里.黑白贴图,黑色表明不可照亮,白色表明能够照亮.
定义了光照和阴影来制造一种发光效果.例如地球黑夜的灯光(须要关闭光照.PBR下停用环境贴图):
自发光贴图在其它全部效果以后才应用;能够用来给最终效果上色,增亮或变暗
在法线贴图中,咱们能够在光滑表面创造出像素级的不一样高度,但它只是幻像,只是改变了光线的反射而已.
在位移贴图中,咱们能够真正地改变表面地形.灰色到白色表示凸起,灰色到黑色表示凹陷:
PBR的主要特性就是可以展现出可见的微观细节,就是用金属度和粗糙度贴图来实现的:
金属度模拟了物体表面的属性,如反射,折射和菲涅耳反射.该灰度纹理中,黑色表明非金属,白色表明金属性表面:
粗糙度贴图模拟了真实世界表面的微观细节.产生明亮或暗淡的外观.该灰度纹理中,黑色表明最粗糙,白色表明最光滑表面:
锚点是3D物体的参考点,和UIView中的anchor锚点相似.对3D物体应用的transform变换也是相对于锚点的.
当平面检测发现平面时,会添加一个锚点,并建立一个SCNNode,并调用代理方法:
// 1
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
// 2
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
// 3
DispatchQueue.main.async {
// 4
let planeNode = self.createARPlaneNode(
planeAnchor: planeAnchor,
color: UIColor.yellow.withAlphaComponent(0.5))
// 5
node.addChildNode(planeNode)
}
}
复制代码
当锚点更新时,也会调用代理方法:
// 1
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
// 2
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
// 3
DispatchQueue.main.async {
// 4
self.updateARPlaneNode(planeNode: node.childNodes[0],
planeAchor: planeAnchor)
}
}
复制代码
首先要了解的是就是physics body物理形体的概念:
还有SceneKit内置的物体形状:
还能够调整整个场景的物理效果速度及物理模拟帧数:
scene.physicsWorld.speed = 0.05 //效果就像慢镜头
scene.physicsWorld.timeStep = 1.0 / 60.0 //每秒60帧;若是物体运动速度过快,须要增长帧数以提升精度,但也会提升CPU的负载.
复制代码
力使用3维向量SCNVector3表示,使用applyForce(_: atPosition: impluse:)方法来添加一个力,并指定位置.一个力能够同时影响线速度和角速度. impluse脉冲状只做用一次,好比踢一个球,非脉冲状的则能够持续做用. Position位置能够影响力的做用效果
更多物理效果相关内容,能够参考physics物理效果
在AR中给物体添加阴影通常有两种方法:
同时文章中还提供了,如何用代码来禁止某个物体写入颜色缓冲区.
func hideARPlaneNodes() {
// 1
for anchor in
(self.sceneView.session.currentFrame?.anchors)! {
// 2
if let node = self.sceneView.node(for: anchor) {
// 3
for child in node.childNodes {
// 4
let material = child.geometry?.materials.first!
material?.colorBufferWriteMask = []
}
}
}
}
复制代码
更多相关内容能够看我之前写的SceneKit系列文章Lights灯光, Shadows阴影以及官方Demo解读中关于阴影的官方解读苹果官方AR变色龙Demo解读
命中测试能够用来提供与3D物体的交互
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
DispatchQueue.main.async {
// 1
if let touchLocation = touches.first?.location(
in: self.sceneView) {
// 2
if let hit = self.sceneView.hitTest(touchLocation,
options: nil).first {
// 3
if hit.node.name == "dice" {
// 4
hit.node.removeFromParentNode()
self.diceCount += 1
}
}
}
}
}
复制代码
第一部分读书笔记结束!