SceneKit是苹果的3D引擎,一般用于游戏开发。除游戏外其他的应用场景一般是3D效果的物体展示,比如京东就有用,最近我们做的会展的项目有部分展品也要用到这样的场景,所以遇到些问题,与大家分享一下,也希望跟大家交流,共同进步。
SceneKit可直接加载展示的文件格式有.dae
、.scn
、和.obj
,关于加载的格式苹果官方也有说明,官方文档,除.scn
外其他两种都是3dmax导出的,.scn
格式可直接查看
.dae
在Xcode中直接查看也是渲染后的效果
而obj
格式文件实际包含3个类型文件.obj
、.mtl
和.jpg
的渲染图片,.obj
是未渲染的3D模型,.mtl
文件(Material Library File)是材质库文件,描述的是物体的材质信息。只加载.obj
文件效果是这样的
可以看到是未渲染的,而使用.dae
可以直接展示渲染后的效果,可见一种是半成品一种是渲染后的成品,那半成品如何正常展示呢?有两种方式,一种是使用Xcode工具手动合成.scn格式的文件,另一种是使用代码合成。
- 手动合成
- 1.选中obj格式文件,点开左边菜单栏,选中坐标系节点;
- 2.在右侧菜单栏,根据实际需求选择渲染样式及渲染图片。
这里主要通过调整设置SCNNode
这个场景图结构元素的Material
类型的几何外表着色属性。需要调整的主要就两个地方,一个是lighting Model
,另一个是SCNMaterialProperty
类型的属性像diffuse
、emission
、normal
等,他们都是定义不同几何表面的渲染效果,通过选择不同的渲染图片资源达到渲染的目的。
diffuse
管理物体材料的照明扩散反应。
ambient
一个对象,管理环境照明材料的响应。
specular
管理物体材料的照明反射响应。
normal
一个对象,定义了表面的名义定位在每个点用于照明。
reflective
一个对象定义的表面上的每个点的反射色。
emission
一个对象定义所发出的每个点上的表面的颜色。
transparent
确定材料中的每个点的不透明物体。
multiply
一个对象,规定乘以材料中的像素在其他所有的阴影是完整的颜色值。
ambientOcclusion
一个对象,将影响材料的环境光颜色值乘以提供。
selfIllumination
一个对象,提供颜色值代表表面的全局光照。
metalness
一个对象,提供彩色值来确定金属材料的表面看起来如何。
roughness
一个对象,确定表面外观平整度提供了颜色值。
lighting Model
有五种样式,分别是:
SCNLightingModelPhong
明暗结合环境,扩散,和镜面反射特性,在高光使用Phong公式计算。
SCNLightingModelBlinn
明暗结合环境,扩散,和镜面反射特性,在高光使用Blinn-Phong公式计算。
SCNLightingModelLambert
明暗结合环境属性和扩散。
SCNLightingModelConstant
均匀的明暗只结合环境照明。
SCNLightingModelPhysicallyBased
基于物理的灯光和材质的现实抽象底纹。
其中前4中,官方文档中有效果图
以上,通过不同的需求选择设置属性时,即会弹出提示
进行设置操作,需要先将文件转换成scn文件,点击转换原来的obj格式文件将转换为scn格式文件,然后进行属性设置即可。
- 代码合成
- 1.拿到3D模型obj格式文件的坐标系节点的场景元素结构;
SCNNode *shirtNode = [_scnView.scene.rootNode childNodeWithName:@"MDL_OBJ" recursively:YES];
- 注:
@"MDL_OBJ"
就是打开obj
或者其他格式3D模型文件时对应的坐标系节点名称,如下图。
- 2.根据需求设置着色渲染。
shirtNode.geometry.firstMaterial.lightingModelName = SCNLightingModelBlinn;
shirtNode.geometry.firstMaterial.diffuse.contents = @"art.scnassets/zhujixiang/Data/Model/Model.jpg";
shirtNode.geometry.firstMaterial.emission.contents = @"art.scnassets/zhujixiang/Data/Model/Model.jpg";
其中shirtNode.geometry.firstMaterial.emission.contents
属性是接收图片名称的赋值,根据图片的添加方式不同,名称可能是路径/名称,也可能直接写名称。以上为代码渲染合成,此时obj文件不需要转换成scn文件也可以展示。
一般3D模型展示都会要求自动旋转,自动旋转也比较简单,主要就两步,
- 1.选择3D模型obj格式文件的坐标系节点的场景元素结构;
SCNNode *ship = [_scnView.scene.rootNode childNodeWithName:@"MDL_OBJ" recursively:YES];
- 2.选择旋转绕轴和旋转时间。
[ship runAction:[SCNAction repeatActionForever:[SCNAction rotateByX:0 y:0 z:2 duration:1]]];
这里选择的是绕Z轴无限循环,当然动作执行的选项很多,具体的可到SCNAction
类的头文件中查看选择。
以上为3D模型自动旋转。
参考资料:
ios 3D引擎 SceneKit 开发(4) --关于旋转的几点问题(1)
ios 3D引擎 SceneKit 开发(5) --关于旋转的几点问题(2)
ios 3D引擎 SceneKit 开发(6) --SCNAction
ios 3D引擎 SceneKit 开发(2) --贴图篇
iOS使用SeneKit展示3D模型并施加动画
我的样例Demo地址如果有用点个星哈!
关于更多的SceneKit可查看官方文档和Demo和技术博客