
SCNGeometry
SCNGeometry是一个3D模型类,它的外观通过SCNMaterialProperty属性来设置,而它本身被附加到SCNNode,最终展示在场景中。
若要想在同一场景中使用不同的材料集多次显示同一geometry图形,可以使用copy。copy的副本共享底层顶点数据,但是独立地分配材质。因此,我们可以复制多个几何图形,而不会对性能造成大的影响。
另外,我们还可以对geometry作动画效果,虽然geometry关联的节点的顶点数据是不变的,但是SceneKit还是提供了以下几种方式对geometry进行动画操作。
- 可以使用SCNMorpher或SCNSkinner对象来使
geometry图形的表面发生形变。 - 由3D软件创建的动画,然后通过文件路径加载到工程中使用。
- 可以使用SCNShadable协议中的方法来添加定制的GLSL着色器程序,这些程序可以改变SceneKit对
geometry图形的呈现。
SceneKit提供了几种引入geometry对象到app中的方法:

- 由3D软件创建的3D模型,通常以.dae或.scn后缀的scene文件,我们把这些文件加载到工程中即可。
- SceneKit提供了内建的3D模型,可以直接使用。
- 由
SCNText和SCNShape构建的2d文件或曲线再创建3D模型。 - 由
SCNGeometrySource和SCNGeometryElement来创建。
SCNGeometrySource
它是一种顶点数据容器,构成三维物体或几何定义的一部分。
使用SCNGeometryElement和SCNGeometrySource对象来自定义SCNGeometry对象,或检查组成现有几何图形的数据。创建一个自定义几何使用一个三步的过程:
创建一个或多个
SCNGeometrySource对象,每个对象为几何中的所有顶点定义每个顶点的信息,如位置、表面法线或纹理坐标。创建至少一个
SCNGeometryElement对象,其中包含一个索引数组,该数组标识几何源中的顶点,并描述顶点如何连接以定义三维对象或几何图形。根据
SCNGeometrySource和SCNGeometryElement对象创建一个SCNGeometry实例。
创建多个GeometrySource:
typedef struct {
float x, y, z; // position
float nx, ny, nz; // normal
float s, t; // texture coordinates
} MyVertex;
MyVertex vertices[VERTEX_COUNT] = { /* ... vertex data ... */ };
NSData *data = [NSData dataWithBytes:vertices length:sizeof(vertices)];
SCNGeometrySource *vertexSource, *normalSource, *tcoordSource;
vertexSource = [SCNGeometrySource geometrySourceWithData:data
semantic:SCNGeometrySourceSemanticVertex
vectorCount:VERTEX_COUNT
floatComponents:YES
componentsPerVector:3 // x, y, z
bytesPerComponent:sizeof(float)
dataOffset:offsetof(MyVertex, x)
dataStride:sizeof(MyVertex)];
normalSource = [SCNGeometrySource geometrySourceWithData:data
semantic:SCNGeometrySourceSemanticNormal
vectorCount:VERTEX_COUNT
floatComponents:YES
componentsPerVector:3 // nx, ny, nz
bytesPerComponent:sizeof(float)
dataOffset:offsetof(MyVertex, nx)
dataStride:sizeof(MyVertex)];
tcoordSource = [SCNGeometrySource geometrySourceWithData:data
semantic:SCNGeometrySourceSemanticTexcoord
vectorCount:VERTEX_COUNT
floatComponents:YES
componentsPerVector:2 // s, t
bytesPerComponent:sizeof(float)
dataOffset:offsetof(MyVertex, s)
dataStride:sizeof(MyVertex)];
SCNGeometryElement
它是一个用于描述顶点如何连接以定义三维对象或几何图形的索引数据的容器。

当SceneKit渲染一个geometry时,每个GeometryElement都对应一个发送到GPU的绘制命令。因为不同的渲染状态需要单独的绘制命令,所以可以使用多个GeometryElement定义geometry图形。例如,上图所示的茶壶有四个GeometryElement(四种颜色的部分),因此您可以分配最多四个SCNMaterial对象,以不同的外观来渲染每个GeometryElement。但是,由于每个绘制命令在渲染时都会带来CPU时间开销,因此最小化自定义几何图形中的元素数量可以提高呈现性能。