Video hosted by Apple at devstreaming-cdn.apple.com

Configure player

Close

WWDC Index does not host video files

If you have access to video files, you can configure a URL pattern to be used in a video player.

URL pattern

preview

Use any of these variables in your URL pattern, the pattern is stored in your browsers' local storage.

$id
ID of session: wwdc2012-504
$eventId
ID of event: wwdc2012
$eventContentId
ID of session without event part: 504
$eventShortId
Shortened ID of event: wwdc12
$year
Year of session: 2012
$extension
Extension of original filename: mov
$filenameAlmostEvery
Filename from "(Almost) Every..." gist: [2012] [Session 504] Introducing...

WWDC12 • Session 504

Introducing Scene Kit

Graphics, Media, and Games • OS X • 45:57

OS X Mountain Lion introduces Scene Kit, a high-level graphics framework enabling your apps to efficiently load, manipulate, and render 3D scenes. Gain an understanding of the Scene Kit architecture and see how easily its capabilities can be applied to a variety of application genres. Learn the objects that define the 3D scene, see how to apply animation, and discover how to use Scene Kit with related OS X technologies such as AppKit, Core Animation, and OpenGL.

Speakers: Amaury Balliet, Aymeric Bard, Thomas Goossens

Unlisted on Apple Developer site

Downloads from Apple

HD Video (511.6 MB)

Transcript

This transcript was generated using Whisper, it may have transcription errors.

And thanks for coming. My name is Thomas Goossens, and I'm going to talk about SyncIt. So what's Synkit? Synkit is a new framework on Mountain Lion, and its goal is to simplify the integration of 3D in applications. There are many use cases for 3D in applications. For instance, sometimes it is used in 3D user interfaces, like as a book template chooser in iPhoto, or CoverFlow in iTunes, and Finder, or Safari stop site, et cetera. Slideshows and presentations are another common use case for 3D to make the animation nicer and more impressive. Data visualization for scientist applications or for the 3D charting keynotes. This is another use case for 3D.

And games, obviously, where 3D is commonly used there. And so for these use cases, OS X provides some low-level APIs, which are OpenGL and its associated technologies. So these APIs are very highly performant. They have a very strong foundation. You can do a lot of things with it. However, since they are low level, they require a lot of advanced skills in computer graphics. And even if you want to do some relatively simple things, you will have to write quite a lot of complex code.

So that's why we introduce Synkit today. Synkit is a high-level API that is built on top of OpenGL and that operates on the Syngraph. And this is a key difference with OpenGL. OpenGL is a procedural API where for every frame, you call some draw commands, set some states, and you do this for each object frame per frame to render your scene. With SceneKit, you describe a scene once, you change some properties of your scene when you want, but then you let SceneKit manage everything and manage the rendering for you.

SimKit is an Objective-C API. You can use it for all the use cases I mentioned before. It is not tied to a particular use case. It's integrated with Cocoa and Core Animation for a seamless and simple integration into applications. So what can you do with SceneKit? SceneKit essentially allows you to do three things. You can load a scene from a file. You can manipulate the objects of your scene, programmatically. And finally, you can render that scene onto the screen. So let's focus on the first part for now, loading a 3D file, and see why it's important to work with 3D files.

The first reason is because it's easier to create complex scenes using 3D software. I mean, complex geometries or complex trajectories are usually created with dedicated tools. The second reason is that the more information you will put into your 3D files, the less code you will have to write. And so this will minimize the number of bugs in your code.

And the last reason is that working with a 3D file allows you to work with artists. The artist work to build the nicest 3D scene on their side while you can focus on your code and so work in parallel with artists. SendKit allows you to load three things from DAE documents. DAE stands for Digital Asset Exchange. It's an XML-based file format. It is supported by most of the major 3D software, like 3ds Max, Maya, Modo, Cinema 4D, etc., etc. And it is adopted in the industry. For instance, it is used by SketchUp, or more recently, it was adopted by iBooks and iBooks Auto for their 3D widgets.

A DAE file can describe a lot of things in your 3D scene. It can, of course, describe all the geometry information of your 3D objects. But it can also describe some animations, all the material colors, references to images, all the lighting of your scene, the different point of views to render your scene, and some advanced features like the skinning and morphing.

Loading such DAE file is straightforward with SceneKit. It can be done with just one single line of code. So typically, you will start by getting the URL to your DAE document using NSBundle. And once you have your URL, you can load your scene using sceneWithURL options error on the SCNScene class. This will load the DAE file and return a new instance of for SCN Sinscene.

Once you have your scene loaded, you may want to render it, for instance, in a view. To do that, SceneKit provides a SCNView object. A SCNView is a subclassary of an NSView that has a capability to render a 3D scene. So just allocate a SCNView and then set your scene previously loaded to your view using the scene property of the SCNView. Another way to create a SCN view is to use interface builder. So, to do this, just drag and drop SCN view object from the interface builder library into your user interface and then you are done. So, let me show you those two first things in a quick demo.

So for this first demo, I will start with a very basic example. Let's say I want to build a simple slideshow to show my images from the iPhoto library or whatever source. into a nice 3D animation for my slideshow. So I asked my artist to build a nice animation in his 3D tool, and he sent me a DAE document. So here, there is myslideshow.dae. And since no Leopard, you can preview DAE files using Quick Look or Preview. So if I double-click on the DAE file, I can open it in preview.

And I can even play the animations to have an idea of what the designer made. So here, I'm just having a preview of the DAE document. So you can see that the DAE file can describe a lot of things. It can describe the 3D objects that are my photo frames. It describes all the lighting information, the movements of the cameras. So everything here is described in the DAE file. So as an engineer, I understand that I want to integrate that in my slideshow application. And that I will have later to replace the two pictures by some photos that comes from my iPhoto library, for instance. So let's see how to integrate that into an application.

So here is a new-- make it slightly bigger. So here's a new application, a new project that I created from scratch. So there is no code at all yet. So the only thing I did was to link with Synkit in the build phases here. And I added my DAE document to my resources. So here you can see mysledshow.dae in the sidebar of Xcode. So the first thing I would want to do is to edit the interface builder file. So here is my window. And from the interface builder library, I can search for my SCN view that is here. Can drag and drop it into my window. Make it slightly bigger.

And the SCN view in Interface Builder comes from with an inspector here that allows you to set some options. For instance, I can directly type the name of the file I want to load at launch. So here I want to load myslideshow.dae. It auto completes, okay. And I can also set up a few steps, like I want the animations to play at launch and loop. So here, if I run my application-- I see that I see the 3D animation playing in my application. And so this was done without having to write any line of code. So let's switch back to the slides.

So you can render a scene into a SCN view if you want to render that in a window with views. But it also provides SCN layer if you want to render a 3D scene into a layer tree. And the SCNRenderer, if you want to render this releasing into an arbitrary OpenGL context.

So that's for loading and rendering a scene. Now you may want to manipulate the objects in your scene to add some interactivity to all that. And that's what I'm going to show now. So first, SceneKit allows you to access all the objects and all the properties of your scene. So you can, of course, move, scale, and rotate the objects in your scene. But you can also add some animations, change the colors or change the textures, adjust the lighting, et cetera, et cetera.

To do this, you need to know what are the objects, the data structures that describe a 3D scene. And that's what I'm going to show now. So a 3D scene is represented by the SCN scene class. And the SCN scene class has a tree of nodes. A node is represented by the SCN node class. And the tree of node is similar to a tree of layers in Core Animation or a tree of views in the AppKit. A node has a position, rotation, and scale that define a 3D coordinate system that is relative to its paramount node. So it's exactly like a layer that has a frame that represents a 2D coordinate system that is relative to its super layer.

So if you want to, for instance, move a node in the 3D space, you just need to set its position to a given vector. So for instance, here I move my node to the origin. I set its position to the vector 0, 0, 0. And managing the hierarchy of nodes is very similar to managing a hierarchy of layers or views with the usual add child and remove from parent methods.

Then a node doesn't represent anything in the 3D space. I mean, nothing that can be rendered on the screen. It's just a location in 3D space on which you can attach some attributes. The attributes you can attach to a node are the following. You can attach a camera. You can attach a light or a geometry. I will explain each of them, but you can already notice that you can share one attribute to multiple nodes. This can be useful if you want a given attribute to be visible at different locations in the 3D scene at the same time. So let's see the first one, camera.

A camera is a point of view that is used by the renderers, so by the SCN view, SCN layer, or SCN renderer. The illustration here show a single scene rendered by SceneKit, but rendered from different point of views. The camera also have a couple of parameters, like the field of view, for instance, if you want to increase or decrease the perspective effect. So second attribute you can attach to a node are the lights.

There are different kind of lights. For instance, the ambient light is a light that illuminates in every direction, and so it illuminates equally all the objects in the scene. An omni light originates from a single point. A directional light illuminates in a given direction. And a spotlight originates from a single point but spreads outward in a cone direction.

So light have a couple of parameters, like the attenuation distances, the intensity, the color, et cetera. But one thing important about light is that it illuminates the entire scene, and not only the node it is attached to. The last attribute you can attach to a node is a geometry, and the geometry represents a surface that can be rendered on the screen.

The surface is made of triangles that are connected together to build the surface. So triangles are connected to vertices. So vertices have a normal that indicates the direction of the surface. Geometry may have some UVs, sometimes named texture coordinates, that tells how an image should be mapped onto the 3D object.

And last, geometry as an array of materials that defines the final appearance of the surface. Note that it is an array of materials and not just a material, because sometimes a geometry is split into several elements, and each element can have a separate material. So now the materials. The material defines the appearance of the surface. It is represented by the SCN material class.

And the material is made of eight properties. A property is represented by the SCNMaterialProperty class. And each property can have a color or an image. The head properties of a material are the following. And the combination of the settings of these head properties produce the final appearance of your surface.

So for instance, the diffuse here can be considered as the base color of your material. More precisely, it's the color that the material will reflect when it is hit by lights. It can be an image like here, or it can be a simple color if you set an NSColor or CGColor ref.

Then the ambient is the color that the material reflects when it is hit by ambient light only. It can be again an image or a color. The specular and shininess controls the specular highlight of shiny materials. The shininess controls the shape of the specular highlight. Reflective is an image that is used as a reflective environment for your material. The transparent property allows you to set, to define the transparent areas of your material.

So normal property allows you to set a normal map, sometime called bump map, and which is a popular technique to add some details to your surface without having to add more polygons. The multiply property allows you, for instance, to set some light maps or shadow maps, which is a popular technique that designers are familiar with.

And last, the emission is an emissive color. That means that it can be visible even when the material doesn't receive any light. So for instance here, the circle image is visible even on the sides of the cube that doesn't receive any light, and it's because it is emissive.

So with materials, we can control how it reacts to light. And this can be done with some lighting models that SynKit support. With a constant lighting model, the constant lighting model doesn't react to any light. It's just a uniform color. Lambert reacts to light but has no specular highlight. And Blinn and Fong have a different specular highlight. So now, to sum up and give an example of all these data structures, let's say I want to change a material of one on my object. I will first get the geometry from my node.

Then I will create a new material, let's say here a red material, by setting the diffuse contents to a red color. And then I can set this material to my geometry as the first material by setting it to the first material property of my geometry. So that's for the overview of all the data structures in ThinKit. Now I hand over to Amaury to talk about the steps to create an application using ThinKit. Thank you.

Thanks, Thomas. Hi. My name is Amaury, and I think it's time for you to build your first app using SyncKit. As said before, you will use DAE documents that describe an entire 3D scene. OS X has a built-in support for these files, and as said before, preview and quick look have allowed you to open and play scenes no leopards. But for many reasons, viewers are not sufficient, so today we are introducing a new SyncKit editor.

The new SyncKit editor is built into Xcode. It allows you to have a deep comprehension of your 3D scene. This is really useful when dealing with files you do not know, either downloaded from an online library or simply handed by an artist. First, the editor allows you to have an idea of your scene graph. Check the name of your nodes, check what their attributes are and how they are positioned relative to each other. It allows you to preview animations and test performances. We wanted to make it really useful, really easy, for you to collaborate with your artist. And we think the editor will be a default of your typical workflow. Artists will design objects in their favorite authoring tool, improve them with great materials, add lights and cameras to their scene.

Using the editor, they will be able to have a preview of how the scene will be rendered in your app. And since they are artists, and since they know what looks good, we wanted to provide them with a tool to make fine visual adjustments. The editor allows them to tweak materials. And by iterating between the editor and the authoring tool, they will be able to craft the perfect-looking scene for your app. than you as a developer takeover.

You will have the scene right within all your other application files. And by iterating between the editor and your code, you will be able to essentially add the programmatic layer that will make the scene dynamic and your app great. So let's have a demo. So starting from Thomas' demo, let's have a look at this scene.

The first thing you see is a viewport. It gives you a preview of what you will get in your app. On the left side, you have the scene graph. Let's take a look at this node, the floor node. I can tell it has geometry attached to it because of this little teapot icon. The node just below has a camera attached to it. And somewhere in each of the nodes, there's a light. Let's have a look. Oh, there are three nodes, and each of them has a light attached to it. But let's get back to the frame. In addition to the inspector you're familiar with, Synkit adds three new of them. The node inspector, the node attributes inspector, and the material inspector. The node inspector allows us to inspect the many properties of a node. For example, I could change this name's name.

I could also change its rotation. Whatever, I think best suits. Let's go back to the light. I want to improve the scene because I don't like this spot. Using the node attributes inspector, I can see this one is a spot. I'm happy with its color, but not with its illumination code. I can easily tweak its outer angle to make it good.

Now I have a scene that I think looks perfect. What I want to do is add some programmatic layer to change the pictures that are displayed. To do this, we will probably have to tweak materials. So let's take a look. This one has three materials: one for the wood, one for the paper frame, and one for the picture.

We have a reflective map for the glossy effect, and the actual picture is set in the diffuse property. Okay, that's all we need to know to add the programmatic layer. First, First, we have the name of our node, then second material, and then diffuse property. We will also have to change the pick, yeah, pick value. We also have to change the picture displayed at the back. So let's rename this guy.

Let's go to our app delegate. The first thing we will want to do is have an entry point to our scene. This will be done by accessing the root node of our scene. Self.SceneView.Scene.RootNode. We have an IBOclet set to the scene, which is named SceneView. On this root node, we will call the child node we've named recursively selector to retrieve our node, photo1. And we will do the same for the horizontal frame.

The next thing we want to do is to retrieve the materials. We'll take the second material for the vertical frame. We'll do the same for the horizontal frame. Now let's add some debug material. some big bug code and let's display a blue picture and a green picture to see if it works.

resources, I have these pictures. And now I want to show this one, this one, this one, and this one. Let's get rid of this data code. And the way we will display the new images So by having a simple index, build a name for the image, and set the diffuse property of our material to be that image. Of course, We do the same for the horizontal picture. We want to loop. That is to mean we want to display pictures and when they are at the back of the scene, we will change them so that the user doesn't notice anything. So let's go back. to our scene and checks for its duration. Seven seconds, 33, okay.

animation duration will be seven seconds 33, and we will set up a timer. To call that method, that swaps images. But because this is for the frontmost frame, we will have to add a slight delay to change the images when they are at the back. We do this. We do this at the middle of the animation duration. And of course, we do this for the second picture as well. pictures we are used to see, and the new pictures.

And that's how easy it is to build a dynamic app, dynamic 3D app using SyncIt. So let's have a quick recap. You will start by retrieving nodes using their names that you can check in the editor. You will retrieve the materials, and finally, we'll tweak them to make them look great. And with that, I'm calling Eric to talk about more advanced features in SyncIt. Thank you.

Thanks, Amaury. Hi, everyone. I'm Emre, and I'm going to show you how to go further with SyncKit. First, I will talk about one of the main features of SceneKit, animations. Then I will present several ways to customize its rendering using OpenGL or GLSL. Then I browse through the various parametric geometries SceneKit has to offer for constructing programmatically your scene. And finally, I will review the possible interactions between SceneKit and Core Animation.

It is crucial for a 3D engine to provide a solid animation system. People expect to see things move and change fluidly in 3D. And SceneKit does provide an amazing animation system. Almost every property of every object are animatable. And this will be done in two ways. Either using implicit animation. By implicit, I mean that no actual animation object are created. As you will see in the code example later, you just have to change the animation, the property you want to animate. The second way is using explicit animations. This time, an actual animation object is created and played when the time is right.

I want to stress out that SyncKit uses the same programming model as CoreAnimation, using the adoption for those of you that already know it. Here is an example of an implicit animation. So first, you have to begin a transaction. Please note that this is an SCN transaction and not a CA transaction, but it has exactly the same API. So for example, if I want to set its duration, I use the set animation duration selector. Bend. Change any property on any object you need. And finally, commit the transaction. The animation will start right away in its own thread and its own pace. You can also add a completion block to be notified where your animation is complete or has been interrupted.

Synkit also supports explicit animations. This time, explicit animations are actual objects that are created upfront and played at your convenience. For example, animations created with 3D modeling tools, such as Maya or Max, and exported to DAE files, are loaded as explicit animations. SceneKit supports three kinds of explicit animation. The simplest one is CA basic animation. It will allow you to animate one property of one object at a time. Then we also have keyframe animation. This time, instead of just providing a final target, you will provide intermediate values along with key times.

The last type of animation supported is the animation group, and it will allow you to synchronize multiple animation on multiple properties. Here you can see an animation controlling the position along with another controlling the opacity. Let's see an example of an explicit animation, creation and usage, here with a CA basic animation. First, you have to create your animation targeting the property you want to animate. Here, the opacity again.

Then you configure it by setting its duration, but you could also set its begin time, its speed, or timing function if you want. Then set the destination value for your property. Finally, set your animation to the node you want to animate. The animation will start right away, but always in its own thread. So you've seen several ways to animate your objects and their properties. Let's now talk about rendering.

Thomas talked earlier about all the different rendering aspects of SceneKit, covering different type of lights, and a large number of material properties. While we made the SyncKit renderer as complete as possible, we know that it won't suit everyone's needs. Therefore, we provided three different ways to you guys to inject custom OpenGL and GLSL code. inside SceneKit's renderer at the scene, at the node, or on a material level.

First of all, on the closest level, you will be allowed to inject code before or after the scene rendering using a scene delegate renderer. It will allow you, for example, to have an animated background or to layer a 2D interface over your scene. Let's see how this will be done.

The effect you just saw is a full-screen CRUD rendered with a custom GLSL shader. In the setup phase, we created our full-screen CRUD and stored it in a vertex array object, along with a vertex and fragment shader that we also wrote. This is a selector that is called before the actual scene rendering. When it is called, we are ensured that no vertex buffer object, no texture, or no program are bound. So we just have to bind what we need. So here, I bind my vertex array object on my program. And I don't forget to unbind it at the end of the delegate. Concerning other GL states, you will have to set them to your convenience, but restore them to SyncKit's default after a while. Here, I don't want my background effect to alter the depth buffer, so I disable the depth testing and restore it at the end.

Next, if you want to render something in the scene among other objects, you may want to use the nodeRenderer delegate. It will allow you, for example, to create position special effects like particle system that simulate fire or smoke. Let's see an example of that. In this scene, the torch is rendered with such a delegate, and everything else is rendered using SceneKit's own renderer, and the two cohabit nicely.

This is a selector that is called on each node that are using your delegate. The node is provided, obviously, along with the necessary transform needed to render the scene as the view, the projection matrices that are given in the arguments dictionary. Lastly, if you want to have a specific appearance for your materials, you can always provide custom programs to send kit materials. This is done by writing your own vertex and fragment shader.

Here is an example of such an effect, a simple like Fresnel effect that could not be achieved using standard SyncKit materials. Let's see how that can be done. First, you have to create an SCN program instance. Then it is the programmer's responsibility to load its vertex and fragment shader code as an A-string, usually from the application bundle.

and you assign it to your custom programs, and finally assign your program to the material you want to customize. These are the shader curves of the effect you just saw. I won't go into the details of the shader, but I want you to notice that there are two special kind of inputs.

The first kind of parameters are the ones that are automatically set by SyncKit. These are the geometry attributes, like position, normals, and texture coordinates, and the transforms, like the models, the view, and projection matrices that are given as uniforms. To make this work, you have to bind your own GLSL variable with SyncIt on Semantic. And this is how it's done. For example, here we are binding the SCN geometry source semantic vertex with our GLSL variable, a position.

The other kind of special inputs are the ones that are not bound to SyncIt semantic. These are usually the custom parameters for your programs. And this is the selector that is called for each one of them. Here we only have one, the U-frenel factor that we set to some arbitrary values.

So we've seen several ways to customize the rendering using OpenGL and GLSL. I will now talk about populating your scene with parametric geometries. If you're not really at ease with a 3D modeling tool, or if you don't have one, you'll be happy to know that SceneKit does provide ready-to-use and easy-to-use parametric geometries.

It starts with a bunch of parametric primitives, such as planes, cubes, cylinders, tubes, spheres, and so on. And they are really easy to use. Here's an example of them. Here, I just create an SCN cylinder, giving it a radius and a height, adjust its tessellation factor, and then set it on the geometry in the node in my scene. That's it. SyncGit also provides dynamic 3D text with the same text capabilities as OS X.

Here again, really simple. Just create an SCN text instance, set its font using a standard NSFont object, assign it typing a text as a string, or you can even use an NS attributed string if you want to have different styles rendered, like italic or bold. Adjust it-- Thank you.

I just extrusion and their materials because there's several material for the front, back, and extrusion and chamfering part of the text. And all of this is animatable. And insert it into your scene and voila. You will also be happy to have a ready-to-use reflective floor, infinite floor. Here again, really simple. Just create an SCN floor object, adjust its reflectivity and its follow-up factors, assign any kind of material you want. Here we would just want a black color floor. And set it in your scene. Your world scene will reflect on it with nothing else to do.

Lastly, you can create your own meshes by providing position, normals, and texture coordinates. It can come in handy if you have your own mesh loader or if you want to do some data visualization application. One last nice thing about SendKit I wanted to talk about is its tight integration with Core Animation. And it works both ways. That means that you can render a scene inside a Core Animation layer and the other way around, that you can have a Core Animation layer used as a texture. Let's see that through some samples.

Here, I create an instance on this NCN layer and assign it a scene, then insert it in an existing co-animation layer tree. As the SCN layer is a subclass of a core animation layer, I can use any effect on it. Here you can see a white border color on a drop shadow. But I could have also used any core image filter. The other way, here I have an animation of multiple coanimation layers. And I set this layer tree as a diffuse content of my material. SceneKit will automatically create a texture and update it only when it has to.

I will now illustrate all of these features we've seen so far in a demo. So, for this demo, we wanted to create an example of a 3D user interface displaying photo albums in 3D photo frames. So you've already seen the photo frames in the previous demos, but this time we cloned it multiple times to reflect the event in the iPhoto library.

Then the frames are arranged in a radial layout among a reflective floor. And they are lit by several lights. One of them is casting shadow. And I can browse through them by swiping. or by clicking on it using the SyncKit picking feature. On the top of the window, there is a search field that will allow me to filter for my frames. For example, up.

Using implicit animation, the visible set of frames have been reduced in a smaller circle with just a few line of code. Let's filter some more. There again, using implicit animation, the entire layout has changed into a CoverFlow-like manner. And I can still swipe through it smoothly. OK, one more filtering.

Yet another layout. Here you can see that the lighting and the camera position have changed, always using implicit animation. And I can switch-- between my front and back frames using explicit animation because of a more complex movement. This is the photo album I wanted to show you. As we are using a core animation layer for the content. It enables transition like fade and swipe. And it also enables movie playing with just a few lines of code. By the way, this is my son. And boom. One last thing I wanted to show you with this demo is the custom rendering facility.

Here you can see some fireflies that are rendered using the node renderer delegate I just talked about. As there are lights attached to these nodes, you can see that they impact the lighting of the scene. So that's it for the demo. OK, let's do a quick recap. So you've seen how to give life to your scene using animation. It's really easy. They're really fast. So use them extensively.

We've also seen how to customize your rendering using delegates and custom programs. Use them wisely. We've seen how to populate easily your scene by using the provided parametric geometries. And finally, how to get the best of both worlds by using the tight integration of core animation. information, please contact our evangelists, Alan Sheffer and Mike Jerevitz. You can find online our reference API, and we have set up a Synkit-dedicated forum on our DevForums website. Thank you.