感謝小伙伴的到來~~~
(一)前言
上章對ARKit進行了一個簡單介紹
一、ARKit初探索
沒有看過的小伙伴可以點擊了解一下。
本章我會來帶大家了解一下SCNGeometry使用頂點信息創建幾何體
(二) SCNGeometry
1、介紹
在SceneKit中,附加到SCNNode對象的幾何形狀形成場景的可見元素,并且SCNMaterial連接到幾何的對象決定其外觀。
2、創建方法
描述 | 了解更多 |
---|---|
從使用外部3D創作工具創建的場景文件加載 | SCNScene、SCNSceneSource |
使用和自定義SceneKit的內置原始形狀 | SCNPlane、SCNBox、SCNSphere、SCNPyramid、SCNCone、SCNCylinder、SCNCapsule、SCNTube和SCNTorus |
從2D文本或Bézier曲線創建3D幾何 | SCNText、SCNShape |
從頂點數據創建自定義幾何 | SCNGeometrySource、 SCNGeometryElement、init(sources:elements:)或是管理形狀數據 |
本章主要是用 init(sources:elements:)的方法來創建自定義幾何體
3、SCNGeometry init(sources:elements:)
本章我主要使用頂點來創建幾何體。法線和紋理映射坐標將在下章介紹
參數說明
sources 描述幾何及其屬性中的頂點的SCNGeometrySource對象數組。
elements 描述如何連接幾何的頂點的SCNGeometryElement對象數組。
幾何的可見內容來自幾何源的組合,其中包含描述其頂點的數據、幾何元素、描述頂點如何連接以形成曲面的數據。
每個SCNGeometrySource對象描述由源的屬性識別的幾何中的所有頂點的屬性(頂點位置,表面法線矢量,顏色或紋理映射坐標)semantic。要創建自定義幾何,您必須提供至少一個源,用于vertex。通常,您還提供用于照明和陰影的法線和紋理坐標的來源。
頂點,正常和顏色語義的來源必須是唯一的 - 如果sources數組中的多個對象具有相同的語義,則SceneKit僅使用第一個。幾何可能有多個texcoord來源-sources陣列中的紋理坐標源的順序決定了在附加材料時用于屬性的值mappingChannel。
每個SCNGeometryElement對象描述幾何源的頂點如何組合成多邊形以創建幾何體的形狀。創建自定義幾何需要至少一個元素。如果數組包含多個elements對象,則它們的順序決定了幾何圖形材料的排列方式有關詳細信息,請參閱materials。
4、使用頂點坐標創建線、面和幾何體
(1)線
let indices: [UInt8] = [0, 1]//需要特別注意 [UInt8]可以使用UInt8、UInt16、UInt32,不能使用UInt64,否則什么幾何圖像都繪制不出來,具體原因還在查看
我這里索引都不會很大所以使用的UInt8,請注意變量最大取值范圍
//使用SCNVector3創建頂點索引
let geometrySources = SCNGeometrySource(vertices: [
SCNVector3(x: 0.1, y: 0.0, z: -0.1),
SCNVector3(x: 0.1, y: 0.1, z: -0.1),
])
//indices:一組索引值,每個索引值都標識幾何源中的一個頂點(連接頂點的順序)
//primitiveType:渲染幾何元素時連接頂點的繪圖方式(SCNGeometryPrimitiveType)
/*
SCNGeometryPrimitiveType:
case triangles
幾何元素的數據是一系列三角形,每個三角形由三個新的頂點描述。
case triangleStrip
幾何元素的數據是一系列三角形,每個三角形由一個新頂點和前三角形的兩個頂點描述。
case line
幾何元素的數據是一系列線段,每個線段由兩個新頂點描述。
case point
幾何元素的數據是一系列未連接的點。
*/
let indices: [UInt8] = [0, 1]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .line)
//根據頂點和索引數據 創建幾何形狀
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
(2)繪制平面
在介紹代碼之間我們先了解一下關于圖形的一些基本知識
在3D空間中繪制的大部分內容都包含大量三角形,他是具有表面的最小形狀。三點形成一個表面,我們可以用四點形成一個矩形實際上只是兩個三角形。
每個表面都有前面和后面,"前面以逆時針方向指定"。SCNMaterial渲染器默認只渲染前面(isDoubleSided屬性默認NO),這是一個常見的優化,因為后面很多時候是被幾何體中的其他表面遮蔽。
①繪制三角形
注意:頂點個數n至少要大于3,否則不能繪制任何三角形。
let geometrySources = SCNGeometrySource(vertices: [
SCNVector3(x: 0.1, y: 0.0, z: -0.1),
SCNVector3(x: 0.1, y: 0.1, z: -0.1),
SCNVector3(x: -0.1, y: 0.0, z: -0.1),
])
let indices: [UInt8] = [0, 1, 2]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangles)
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
運行代碼會看到一個面向我們的三角形,而從三角形的背面看是透明的
②繪制長方形
我們將使用三角形兩種不同的頂點索引方式來分別拼合一個長方形
case triangles 幾何元素的數據是一系列三角形,每個三角形由三個新的頂點描述。
case triangleStrip
幾何元素的數據是一系列三角形,每個三角形由一個新頂點和前三角形的兩個頂點描述。
A、triangles
以每三個頂點繪制一個三角形。如果頂點的個數n不是3的倍數,那么最后的1個或者2個頂點會被忽略。
let geometrySources = SCNGeometrySource(vertices: [
SCNVector3(x: 0.1, y: 0.0, z: -0.1),
SCNVector3(x: 0.1, y: 0.1, z: -0.1),
SCNVector3(x: -0.1, y: 0.0, z: -0.1),
SCNVector3(x: -0.1, y: 0.1, z: -0.1),
])
//正面向前,逆時針索引每個三角形,三個一組
//0->1->2 2->1->3
let indices: [UInt8] = [0, 1, 2,
2, 1, 3]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangles)
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
A、triangleStrip
構建當前三角形的頂點的連接順序依賴于要和前面已經出現過的2個頂點組成三角形
一般用在"三角帶"上,三角帶是一個三角形列表,其中每個三角形都與前一個三角形共享一邊。下圖顯示了一個三角帶
下圖中,注意到,頂點順序在順時針和逆時針間不斷變換。
let geometrySources = SCNGeometrySource(vertices: [
SCNVector3(x: 0.1, y: 0.0, z: -0.1),
SCNVector3(x: 0.1, y: 0.1, z: -0.1),
SCNVector3(x: -0.1, y: 0.0, z: -0.1),
SCNVector3(x: -0.1, y: 0.1, z: -0.1),
SCNVector3(x: -0.1, y: 0.0, z: 0.0),
SCNVector3(x: -0.1, y: 0.1, z: 0.0),
])
//0->1->2(逆) 1->2->3(順) 2->3->4(逆) 3->4->5(順)
let indices: [UInt8] = [0, 1, 2, 3, 4, 5]
let geometryElement = SCNGeometryElement(indices: indices, primitiveType: .triangleStrip)
let geometry = SCNGeometry(sources: [geometrySources], elements: [geometryElement])
)
(3) 繪制幾何體
繪制立方體其實就是兩個三角形拼接成一個方形面,六個正方形面拼接成閉合的立方體。需要注意的是立方體每個面的正反面。
代碼已經上傳其中已經打好注釋在這里不做過多解釋了: github
(三)創建SCN文件 拖拽模型
最后簡單的給大家截圖看一下創建SCN文件拖裝一些模型,然后用SCNScene(named:)加載模型文件
本章內容就到這里感謝小伙伴們的到來~
下章我將給大家介紹SCNGeometry曲面的繪制、法線以及紋理映射坐標的內容。我會盡量加快更新速度~~~
代碼已經上傳github