SceneKit基础之实现一个太阳系场景(一)

在这篇博文中,我们将实现下面这样的一个效果:

在上面的效果中,使用SceneKit创建了一个 3D 的太阳系场景。在这个场景中,有我们常见的行星,然后我们还给场景设置了一个全场景的背景。最后就是通过下面的左右切换按钮可以切换视角查看不同的行星。

创建一个项目

在 Xcode 中,使用通用的模板创建一个 SwiftUI 的项目。然后在项目中创建一个SceneKit Scene File,即SceneKit 的场景文件

创建完成后,文件的扩展名为.scn

接着,到ContentView文件中,定义一个名为makeScene的静态函数用来通过这个文件名加载场景:

1
2
3
4
static func makeScene() -> SCNScene? {
let scene = SCNScene(named: "Solar.scn") // 通过场景文件创建一个场景
return scene
}

将这个函数返回场景赋值给到一个变量,供后续使用。

1
var scene: SCNScene? = makeScene()

body部分,通过SceneView来展示这个场景:

1
SceneView(scene: scene, options: [.allowsCameraControl, .autoenablesDefaultLighting])

此时通过预览或者编译运行项目,就能看到场景文件所展示的内容了。因为现在我们的场景文件中除了一个背景什么都没有,所以我们只能看到一个简单的效果。

通过场景编辑器(Scene Editor)来编辑布局场景

回到新建的.scn文件中,在这个文件中,Xcode 给我们提供了一个场景编辑器的功能,让我们可以直接通过界面的方式编辑一个场景。

Scene Editor的左边区域,可以看到整个场景中包含的节点,新建的场景中摸下情况下只有一个相机(Camera)节点。让我们先来看一下 Apple 官方对场景(SCNScene)的定义:

A container for the node hierarchy and global properties that together form a displayable 3D scene.

在这个定义中,我们可以知道一个SCNScene是一系列节点的容器。这些节点属于SCNNode类型。

文档示例图

每个节点都有很多的属性可以在Scene Editor中进行设置,选中任意一个节点后,展开 Xcode 右侧的观察器

熟悉UIKit中Storyboard界面编辑的同学会发现,这里多了很多的观察器

  • Node inspector: 节点观察器,可以设置节点的基本属性,例如位置和大小;
  • Attributes inspetor:属性观察器;
  • Material inspector:材质观察器,可以设置节点的材质样式;
  • Physics inspector: 物理观察器,给节点添加物理效果时用到;
  • Scene inspector: 场景观察器,可以对场景进行设置。

接下来,我们首先来调整一下场景中相机节点的相关属性。选中相机节点后,点击右侧的Node inspector,设置下面的属性:

在我们的场景中,每个节点都会有这些属性,每个属性都可以进行设置:

  • Identity: 节点名称,在代码中可以通过这个节点名获取到这个节点;
  • Position:节点在场景中相对于父节点的位置;
  • Euler: 节点相对于父节点的旋转;
  • Scale :在 x、y、z三个轴上的变换尺寸

当我们改变了场景中相机节点的相关属性之后,可能看不到这个节点,可以通过对场景的缩放来查看找到节点。

向场景中添加其他节点或对象

Scene Editor中,点击Xcode顶部的**+**按钮:

然后,我们选择一个Sphere球体对象拖入到场景中:

此时,如果运行项目,我们是无法在场景中查看这个球体的,因为这个场景并不在相机的视野范围内容。我们可以来调整一下这个球体节点的属性。

修改节点材质

选中节点后,在观察器面板选择Materials inspector(材质观察器)

接着,点击Diffuse的颜色选择选择器,设置一个Hex Color为**#F2FF2C,这样一来我们就给这个对象添加了一个颜色的材质效果。然后设置Illumination的颜色为white**,设置这个属性可以调整光在节点上的照明度,即便这个节点被和光源隔离,它依然能收到灯光。

修改节点的大小和相机节点视野

为了让这个节点显得更大一点,可以在Attributes inspectorRadius调整为10即可。

此时,我们会注意到这个节点依然没有在相机节点的视野内。一方面可以调整这个节点相对于相机的位置;另一方面可以直接调整相机的Z Clipping 属性。

这个属性有两个值,一个是Near,另一个是Far。这里我们将Far的值调整为300。此时的效果如下:

添加其他的节点

按照上面相同的方式添加其他的节点,同时设置节点的位置、大小、节点名、节点颜色材质以及节点光照效果。以下所有的节点均为Sphere

Mercury
  • Name:mercury
  • Position: x:0,y:0, z:15
  • Diffuse: #BBBBBB
  • Roughness:节点粗糙度1,取值范围为 0~1。0 表示光滑,反光越多;1 表示粗糙,反光越少。
Venus
  • Name:venus
  • Position: x:0,y:0, z:35
  • Diffuse: #59B1D6
  • Radius:2
  • Roughness:节点粗糙度1
Earth
  • Name:earth
  • Position: x:0,y:0, z:50
  • Diffuse: #2F5CD6
  • Radius:2
  • Roughness:节点粗糙度1
Mars
  • Name:mars

  • Position: x:0,y:0, z:75

  • Diffuse: #C65B2C

  • Radius:2

  • Roughness:节点粗糙度1

Saturn
  • Name:saturn
  • Position: x:0,y:0, z:150
  • Diffuse: #D69D5F
  • Radius:5
  • Roughness:节点粗糙度1
给土星添加星环

众所周知,土星有一个与众不同支持在于它有一个自己独特的星环。所以我们接下来要给saturn节点添加一个星环的子节点。

点击 Xcode 顶部的**+按钮,选择或者搜索一个Tube**形状节点添加到saturn节点上。添加完成后,在节点管理中中的结构如下:

接着,我们调整Tube形状的以下属性:

  • Inner raduis: 7
  • Outer radius:9
  • Height:0.1

然后,就是让这个Tube 节点使用和saturn相同的材质效果。在TubeAttritubes insepector中,找到Materials属性,

点击左边的➕按钮,选择对应的材质即可。

此时的场景中效果如下: