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
}
}
}
}
}
複製代碼
第一部分讀書筆記結束!