Saturday, September 13, 2014

SceneKit Tutorial Part 3 - Geometry and Material

When I was writing this part of SceneKit Tutorial, Xcode 6.0 GM was released. Compared to former Xcode 6.0 beta versions, Xcode 6.0 GM start supporting iPhone6 and iPhone 6 plus iOS simulators:
New iPhone simulators

 Alright, let me start the main topics of this tutorial. In this part, I will show you some subclasses of SCNGeometry. These subclasses presents kinds of geometry shapes like Sphere, Pyramid, Tube etc. Besides that, I will present the material property of the geometry shapes in SceneKit. The material property of a geometry shape refers to a list of objects of SCNMaterial class. To make a material shown up, we need attach the material to a geometry shape first, then connect the shape to a SCNNode and then put the object of SCNNode into an object of SCNScene.

Everyone can get the source code of Part 3 of SceneKit Tutorial at this link.

You may have seen that I created a box in Part 2.  At first of this part, I will show you two types of geometry shapes: Sphere and Pyramid. Similar to box I've shown before, we use SCNSphere and SCNPyramid to create the two types of shapes:


And then put a camera to view the two shapes:

Here we use the default light from scene, so the geometry figures will look like this:
Really Plain Sphere and Pyramid

OK, it is really plain for the two shapes. We want to add more colors and  textures on the two figures. How to do that? We can add materials to the geometry shapes. Here we use these code to add stars to the geometry:

Now the program will show something like this:
Sphere and Pyramid with Star

One thing I want to mention that when assigning materials to a geometry shape, we use a list of materials. Which means we can assign several materials to a shape. But, not all the materials can be shown up. That depends on how many surface a geometry shape could have. For example, if we assign 2 materials to a sphere, because a sphere has only one surface so the second material in the list will be discarded. Here let me try to create another material with a single color and assign two materials to both sphere and pyramid:

Now one side of the pyramid will looks different, but the sphere keeps the same:
After assigning 2 materials to Sphere and Pyramid
Well, you may say that the 2 figures looks so plain and ugly. The reflective property of SCNMaterial can make the figures looks better. Which means, when the light shining on the geometry shape, the material could reflect something so that the geometry looks more like a real object. For example, I want to the Star image reflect blue light and the blue surface to reflect white light, the code looks like:

myStar.reflective.contents = UIColor.blueColor()
myBlue.reflective.contents = UIColor.whiteColor()

Now the scene will look like this:
Geometry Shapes with Reflective Materials
OK, next I will show you some other subclasses of SCNGeometry, these shapes have there specific features than others.

SCNFloor is usually used in a scene as an infinite plain. In a game it usually shows a wall, a background or a land. Objects of SCNFloor has the feature of reflection, so you can see the shadow of the shapes above and beneath the floor. To create a simple floor, here is the code:


Now the scene will looks like this:
Add a Floor to the Scene
Now let me introduce some properties of reflection of SCNFloor.

//
// Use reflectivity properties of SCNFloor
//
myFloor.reflectivity = 0.9
myFloor.reflectionResolutionScaleFactor = 1.0
myFloor.reflectionFalloffStart = 2.0
myFloor.reflectionFalloffEnd = 10.0

Here the property reflectivity specifies the contrast of the reflection compared to the original object. If its value equals to 1,  the floor looks like a mirror.

The property reflectionResolutionScaleFactor specifies the resolution scale factor of the buffer used to render the reflection, the bigger value will cost more effort to render the reflection.

The property reflectionFalloffStart specifies the distance from the floor where scene contents are reflected at full intensity, and reflectionFalloffEnd specifies the distance from the floor where scene contents are no longer reflected.

By using the values from above code, the result will looks like this:
Effect of a Floor with Reflection Properties
Now let's add materials to the floor, remember that the floor only have one surface, so we can just only see one materials if we assign more than one materials to the geometry:

myFloor.materials = [myStar, myBlue]

It will be:
Set Material to the Floor
If you see the floor from another side of surface(from the space beneath the floor), the floor will be invisible:
Ah, the floor disappeared seen from the another side of the floor.
OK, now the discussion on SCNFloor stops here. Let me introduce another useful subclass of SCNText,  this is used for creating 3D texts in the scene. To create some words in the scene, here is an example:

From above code, we initialized an object of SCNText with a string that will be shown in the scene. And set the font of the string in line 5 and the material of the string in line 6. By setting the text's orientation and position, the stuff in the scene will looks like this:
Add Text in the Scene
It is really cool, isn't it? We can see the reflection of the text on the floor.

This part will end at here. In next part, I will dig into the animation in SceneKit.

Monday, September 1, 2014

SceneKit Tutorial Part 2 - Camera and Lights

In Part 1 of this Tutorial, I've created a simple box with yellow light shining on it. In this part, I will introduce SCNCamera which is another important class in SceneKit. And I will also dig into SCNLight and show you the 4 different types of lights in SceneKit. The project to demo the samples in this part of tutorial could be found at here.

As you can read from SceneKit Framework Reference ,  the default camera is orthogonal to the scene plain. Like a real camera, we also want to put it to a point in the 3D space and set its orientation. The position and orientation of a camera is controlled by the SCNNode which contains the camera. Also we also care if the camera has a broad field to view a wider space in the scene. The camera's field is defined by two properties of SCNCamera: xFov and yFov (Fov is short for Field of view). If you give xFov and yFov a bigger value, you will get a broader view to the scene.

Here is the code to create a camera and put it into a scene:

If you've created a box and put it in the center of the scene and enabled the default light like this:

You will see the box from another point of view instead in the front of box:


Notice that the orientation property of a SCNNode is defined by a quaternion.  If you feel complex to calculate the number or confused on how to get the 4 numbers for orientation, a property from SCNView can help you when you set allow camera control to true:

myView?.allowsCameraControl = true

Then you can drag and drop the scene to control the camera, or even zoom in and zoom out the view for the camera. If you want to get the camera's properties like position and orientation when you controlling the camera, you can customize the touchedEnded delegate in view controller:

When you feel the view looks what you expected, you can release the touch and see the position and orientation of the camera in console, and you can use the positions and orientations shows in console in your code. So it is easier than calculating the values by yourself.

Next, I will add different types of lights to the box to demonstrate the light effects in SceneKit.

There are 4 types of light. The first type of light is omni(omnidirectional light) and type is SCNLightTypeOmni, which presents a point light, a light of this type illuminates all directions from a single point. I've used this type of light in Part 1.  Because lights are tied with nodes, this type of light just care about position of the node, the orientation is ignored. Here is the snippet of code to create an omni light:

The second type of light is SCNLightTypeAmbient, this type of light illuminates from all directions with equal effect. So the orientation and position of its node are ignored. Here is the snippet to create an ambient light:

The third type of light is SCNLightTypeDirectional, this type of light illuminates from one direction. So the position of its node is ignored. The orientation of the node defines the light comes from which direction. Here is the snippet to create a directional light:

The fourth type of light is SCNLightTypeSpot, this type of light illuminates a cone-shaped area. The orientation and the position of the light are defined by its node's properties:

Now here are the snapshots of the results of the 4 types of lights using above snippets:
Omni Light
Ambient Light(with default light)
Spot Light
Directional Light

Now I've done my demo in this part, you may now have intuitive feelings on camera and light in SceneKit. But this is just a small set of features offered by SceneKit. You may need more time to investigate other features by yourself.

In next part of this tutorial, I will talk about the materials in SceneKit.