WWDC2014 Session 609

Transcript

X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
[ Applause ]
>> Thank you.
So, good morning, everyone,
and welcome to the What's
New in SceneKit session.
So, SceneKit is a
framework to help you load
and integrate 3D objects or
3D scenes in your application.
It can be used for
different purposes, like UI,
data visualization, or
presentations, like here;
and now with this release
also to build casual 3D games.
It was first introduced
on the Mac on 10.8,
and it is now available on iOS.
Yeah, thank you.
[ Applause ]
Regarding the layering, SceneKit
is a high-level Objective-C API.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Regarding the layering, SceneKit
is a high-level Objective-C API.
It's built on top of
OpenGL and OpenGL ES,
and it can collaborate well with
those aerographic technologies,
like Core Image and Core
Animation, and also,
especially now, with
SpriteKit, and I will detail
that in the next slide.
In addition of being available
in iOS, which is really great,
we also have a set of cool new
features ready for this release,
like physics, particles
in physics fields.
I will present them
in the next slides.
Before that, some
related sessions.
So, I invite you
first to have a look
at last year's presentation,
since even if SceneKit
was OS X only,
everything represented last
year is applicable now on iOS.
Then this session is about
What's New in SceneKit.
We also have a more hands-on
session at 11:30, same room,
where we will show
how we build a little
but fully functional game, and
we'll explain how we did that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but fully functional game, and
we'll explain how we did that.
Also, in case you missed it,
have a look at the
SpriteKit session
that was earlier this
week, since SceneKit
and SpriteKit can
really work well together
to achieve great results.
Okay, for this presentation,
I will start
with a very brief overview of
the SceneKit main principles.
It will be very quick.
If you want more
details, please refer
to last year's presentation.
And then I will present the
steps to create an application
that uses SceneKit and I
will present the new features
as I go along.
So, the overview.
So, a scene in SceneKit
is represented
by the SCNScene class.
If you are already
familiar with SpriteKit,
that's the equivalent
of SKScene.
So that's the top-level object,
and the scene has a root node
of the SCNNode class, and a
node represents a location
in 3D space.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
A node may have some child
nodes that are related
to their parent node, just
like SKNode are related
to their parent node, and then,
a node by itself doesn't
render anything onscreen.
It's just a location
in 3D space.
And unlike SpriteKit,
where you use subclasses
to render things onscreen,
here with SceneKit,
you attach attributes
to your nodes.
So attributes you can
attach as the following:
you can attach a light
or a camera or geometry.
And attaching a geometry to
a node means that you want
to render that geometry
at the node location.
So, if you want to
render the same geometry
in multiple places, you simply
share the same geometry instance
to multiple nodes.
So, let's go quickly
over these attributes.
So, the first one
is SCNGeometry.
It represents a geometry, so
a set of triangles, vertices,
normals, and texture
coordinates,
and it has also a
a number of materials
that controls the
appearance of the surface.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
that controls the
appearance of the surface.
Then, the second
attribute is SCNLight.
It represents a light source.
We support 4 types of lights:
to illuminate from a point,
in a direction, as a spot,
or equal in every directions
with the ambient light.
Then, next attribute, SCNCamera.
A node with a camera attached
can be used as a point of view
to render your scene,
so it's simple
as setting the pointOfView
property of your view
to one node that has
a camera attached.
For example, here is a point
of view to render the scene,
and here is another
point of view.
So, to sum up, when you
create a scene with SceneKit,
you first start by
creating nodes
and placing them in 3D space.
Then you can add a child node
that are relative to
their parent node.
Then you attach geometries
to these nodes
to render surfaces on-screen.
Then you configure the materials
to change their colors
and textures.
And finally, you can also attach
a light to one node if you want
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And finally, you can also attach
a light to one node if you want
to illuminate your scene.
So that's our very
brief introduction.
Now let's see how
to get started.
So, in Xcode 6, there is
now a new game template
from which you can choose to
create a SceneKit base game,
and this will create
a new application
with the SCNView
already set up for you.
If you already have
an application,
you can also use the
Interface Builder and drag
and drop SCNView from the
Interface Builder Library
into your application.
Note that SceneKit gives you
a view if you want to render
into a view, but there
is also SCNLayer on OS X,
and SCNRenderer if you
want to render off-screen
into an arbitrary
OpenGL context.
Now you know how
to render a scene;
let's see how to create one.
So, to create a scene, you
have basically 2 options:
you can user-create
everything programmatically,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
you can user-create
everything programmatically,
or you can load a
scene from a file.
To create a scene
programmatically,
you can use one of our
built-in parametric geometries,
like a box, a plane, a
torus, a cylinder, etcetera.
You can configure the
parameters, like width, length,
height, corner radius,
segment count, etcetera.
You also have SCNText to
create 3D text with extrusion
and chamfer and multiple
materials,
and it supports basically
all the fonts
and layouts supported
by Core Text.
You can also use SCNShape
to create a 3D object
from a 2D Bezier path by
extruding it and chamfering it.
So, for example, here
is a 2D Bezier pass,
and I can extrude it to create
a 3D object from it very easily.
And also, if you need, you can
also create your fully custom
geometry by placing
your custom vertices,
normal and texture coordinates.
So here you have
the full control
and with SCNGeometry API.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and with SCNGeometry API.
And also new in this release,
you can also now
subdivide your geometry
with the subdivisionLevel
property of SCNGeometry.
This uses Pixar OpenSubdiv
technology to achieve this.
So, for example, here
on the left you have the
model not subdivided yet,
and on the right with 1
iteration of subdivision.
Okay, so that to create
scenes programmatically; now,
you can also load a
scene from a file.
And loading a scene from a file
lets you load a scene fully
configured by your artist that
will include all the geometries,
all the nodal hierarchies,
the lightings, the textures,
the position of your cameras,
all the skin information,
etcetera.
SceneKit supports
COLLADA documents
with the extension .dae.
It's an XML-based file format.
We now also support
the Alembic file format
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We now also support
the Alembic file format
with the extension .abc.
So, Alembic is quite popular in
the video industry, for example,
and with Alembic you
can load geometries
and animations exclusively.
So, once you get your 3D
file from your artist,
you can have a preview of it in
Preview, or directly in Finder
with QuickLook, and you can
open it and have a preview
and do more with Xcode.
Xcode has a built-in
COLLADA editor
that will let you
inspect your 3D files.
To be clear, it's
not a modeling tool;
this is not where you
will create your models
and create your scene.
This is more a tool to
inspect the hierarchy of nodes,
their names, you can change the
materials, adjust the lighting,
and do the scan of
things, typically.
You can tune your scene for
your application with Xcode.
Once you have your
scene ready to load it
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Once you have your
scene ready to load it
at run time, it's easy.
You first add your COLLADA
file to your resource
as a normal resource,
and then, at runtime,
you use SCNScene sceneNamed
to load it, or Scene with URL.
New in this release, we also
provide an alternate way
to manage your assets,
and we call that
SceneKit Assets Catalogs.
An Asset Catalog
is simply a folder
with a .scnassets extension,
and what it does is that,
if you put your assets in it,
Xcode will copy this folder
at build-time by preserving
your folder hierarchy.
So, the first advantage is
that it lets you organize your
assets the way you want --
for example by having
your models in one folder,
your textures in another
one, your particles in
yet another one -- or
organize your assets by level
if you are building a game.
The second advantage is
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The second advantage is
that Assets Catalogs will
give you some options
because the Assets Catalogs
are processed at build-time,
and so you have options
to optimize your assets
at build-time by, for example,
interleaving the geometry data
to be more efficient on iOS, or
by converting the orientations
of your models, too, so
that they are all consistent
across your game.
Okay, once you have your scene
loaded to display it, it's easy.
Simply assign your scene to your
view with the scene property.
The view will automatically
display the scene, and also,
if you modify your scene graph,
the view will automatically
reflect your changes.
There is no need to call
setNeedsDisplay,
for example.
Okay, so now we have seen how
to load and display your scene;
let's see how to give
life to those scenes.
To animate your objects,
you have several options.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
You can update the position
of your objects programmatically
at every frame.
You can configure animations
for a given duration
and let it play.
New in this release,
we introduce the
concept of actions.
I will present that.
You can also set
up some constraints
between your 3D objects.
And last I will present how
you can animate your scenes
using physics.
So first, the per-frame update.
If you need to update your
objects on a per-frame basis,
it is recommended to use one
of the delegate methods here.
So here is how the game
loops look like; so,
this is what is done at every
frame when your game runs.
So it's the combination of
delegate method that we call
and you implement and some
SceneKit internal processes,
like our rendering typically.
So basically, you will
implement the update method
to implement your game logic,
and you can here move your
objects programmatically.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
and you can here move your
objects programmatically.
It is recommended to use
these callbacks essentially
for performance reasons, because
when these callback are called,
the scene is already
loaded for you to modify it.
If you do it in your own thread,
your changes will be committed
on the next transaction
and it won't be necessarily
synchronized
with the current frame.
Note that you are also have
some callbacks to be notified
when the animations did apply
and when the physics did
stimulate if you need
to do whatever actions
after these operations.
So, that's for per-frame
updates.
Now, another way is to configure
actions - animation, sorry.
So, for animations, SceneKit
uses the same programming model
as Core Animation,
which supports implicit
and explicit animations, and
almost all the properties
of the scene graph
are animatable.
So, for implicit animations, it
works just like Core Animations:
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, for implicit animations, it
works just like Core Animations:
you first start a transaction
with a given duration,
then you modify whatever
property you want
on the scene graph, and
last you commit your changes
and it animates implicitly.
For explicit animations,
here we use directly the APIs
of Core Animation.
We support CABasicAnimation,
CAKeyFrameAnimation,
and CAAnimationGroup.
For example, here I set up
a simple basic animation
that targets the
rotation of my node,
then I configure its duration,
its destination value,
and set it to repeat forever,
and finally, I add my animation
with addAnimation forKey -
so, just like Core Animation.
And it makes my nodes to
rotate forever like this.
Okay, don't worry.
So, note that we also have
some extensions, some additions
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, note that we also have
some extensions, some additions
in Core Animation animations.
The first one is
animation events.
Animation events lets you
trigger a custom block of code
at some specific
progress of you animation.
A typical example, for
example, is to play a sound
at some progress
in the animation.
For example, here, I'm playing
a sound at 60% of my animation,
so if I press Next, you
can see it calls my block
at 60% and plays that sound.
So that's the first addition,
and the second addition
is smooth transitions.
So this is useful to blend
one animation onto another.
So, for example, here,
the monster is playing
an idle animation.
If I press Next, I will start an
attack animation on top of it.
By default, without any fade-in
and fade-out duration,
it looks like this.
Okay, I will do it one more
time; look carefully at the end
of the attack animation.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
of the attack animation.
Okay, so this is not super
smooth, not really great,
and if I simply configure
the fadeInDuration
and fadeOutDuration of
the attack animation,
it will make the effect
of the attack animation
to smoothly increase
at the beginning
and smoothly decrease
at the end.
So, now look at the same thing.
Okay, one more time.
So now it's smooth,
so it's much better.
Yeah, thank you.
[ Applause ]
So that's much better, and also
that's super easy to configure.
So that's for animations.
Now, actions.
So, if you're already
familiar with SpriteKit,
you already know SKAction.
Here, SCNAnimations
just work the same.
And the main advantage
over animations is
that it makes really
easy to sequence group
and repeat simple actions.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
However, it's limited to a
set of predefined actions
that works on SCNNode.
With animations, you can
really target whatever property
of the scene graph.
So to give you an example of how
easy it is to write an action,
here is an action that makes
my node to rotate forever.
So with just one line of
code, it's the equivalent
of the previous slide with Core
Animation with 6 lines of code.
So that's much simpler.
Here are some of the
predefined actions.
You can move your objects,
rotate, make them fade in,
fade out, remove
from the scene graph.
And note that you can also
implement your custom actions
by providing your
custom block if you want.
One difference between
animations and actions is
that actions directly target
the presentation tree.
If you are familiar
with Core Animation,
you know already the
concept of the model tree
versus the presentation tree.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
So, model tree contains
the value you set
and get programmatically,
and the presentation tree
contains the in-flight value
of any running animation.
So, the red dot here
presents node.position.
You can see that, with actions,
node.position corresponds
to the position of the
cube on the screen.
With animations, node.position
corresponds to the position
of the cube at the
end of the animation.
If you want to know the
position of the cube onscreen
with animations, you have to do
node.presentationNode.position,
just like Core Animation.
Okay, so that's about actions.
Now, physics.
SceneKit now has a
built-in physics engine,
zeroprode [phonetic].
So, the API is very
similar to SpriteKit.
To make a node physicalize, you
set the physics body property
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
To make a node physicalize, you
set the physics body property
of your node to a
SCNPhysicsBody instance.
For example, here I have a cube
that is not physicalized yet,
and by setting the physicsBody
property to a dynamic body,
it will automatically animate
with the physics simulation.
Now, dynamic bodies
automatically bounce
and collide together based on
their physicsBody properties,
it's automatic, and
then if you want
to manipulate those objects,
you should not set the position
programmatically directly.
Instead, you have to use forces
to manipulate those objects.
SCNPhysicsBody has some
methods for you to apply forces
and angular forces
to your objects.
So for example here, if I
apply a force from the center
of the scene to all these cubes,
I will make them to go away.
Okay.
So, that's dynamic bodies.
We also have static bodies.
Static bodies participate
to the physics simulation,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Static bodies participate
to the physics simulation,
but they never move;
they are static.
So for example here, these boxes
here are set to a static body,
and if I have some
dynamic spheres,
you can see that
they collide together
but that the static
objects don't move.
[ Blows Sharply ]
[ Laughter & Applause ]
My son loves that, too.
One last kind of physics
body: kinematics body.
Kinematics bodies participate
to the physics simulation.
They don't move in
response to collision.
However, the difference here is
that you can move kinematics
bodies programmatically
by setting their
position or rotation.
For example here, I
have a rotating box
that is set as a kinematic body.
I can make it to rotate
with an action, for example,
and you can see that it
automatically collides
with dynamic spheres here
and make them bounce.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
with dynamic spheres here
and make them bounce.
Okay, so that's for
physics bodies.
Now, one note about
PhysicsShape.
The PhysicsShape is a
geometry that is used
by the physics engine to
perform the physics simulation.
By default, SceneKit will
automatically create a shape
for you.
So for example, if I had
some teapots, let's say,
SceneKit will automatically
build a shape for these teapots
by building the convex
hull for you.
That said, you can still
customize the physics shape
if you want.
The main reason can
be for performance.
If you use a built-in
primitive for the shape,
it will be more efficient
than the convex hull,
and the second reason can
be for better correctness.
Let's say you want to have an
object that rolls on the floor.
You will have better correctness
if you use a sphere or cylinder
than using a discretized
geometry.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
than using a discretized
geometry.
So, here are the primitives
that are natively supported
by the physics engine,
so spheres as usual,
spheres and boxes, etcetera.
Okay, next.
And, okay, next,
PhysicsBehavior.
The PhysicsBehavior
lets you customize the
physics simulation.
For example, we have a set of
joints available in the APIs
for you to connect objects
together, for example.
For instance here, these boxes
are connected by hinge joints.
To add a joint, simply use
addBehavior on the physicsWorld
of your scene, and the joint
will reference the two nodes it
has to connect.
To remove the behavior,
simply use removeBehavior,
and it will remove the joints.
Okay, so there are definitely
much more things I didn't cover
about physics, like
PhysicsFields for example,
but definitely a lot of
cool things to play with.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
but definitely a lot of
cool things to play with.
Now I will just show you a
quick demo, still about physics.
So, here is a little
sample code available
on the developer website that
is to illustrate the physics
in general and vehicles
in particular.
Vehicles have a specific
behavior.
When I touch the screen, I will
apply a force on the wheels
and so we'll be able
to start to drive.
Then I can control the
steering of my vehicle
with the accelerometer and
also with the game controller,
and the first thing
you can see , well,
the first thing you can see
is that I'm not a good driver,
but the second thing
you can see is
that vehicles automatically
collide
with dynamic bodies
and make them bounce.
Second thing, it also
works with static bodies.
So, for example, if I hit the
wall, the walls are static, ah,
oops, missed, woo, like that.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And -- okay, then you can also
notice the train here is made
of several objects that
are connected with joints,
so if I hit the train
you can see
that the objects move like that.
Also notice the smoke effect,
and we explain how we do
that later in the slides.
Now, we'll try to do one gentle.
Let me restart the game
like that and try to jump.
Woo! Okay, quite good.
Thank you, thank you.
[ Applause ]
Okay, and also note that this
game has some little overlays
on top of it.
They are made with SpriteKit;
we will explain how
we do that later.
So I'm talking about the
speed gauge on the right
and the camera button
on the left.
And so they are rendered
by SpriteKit,
but they are also
fully functional.
So, for example, if I click
the camera button here,
it is clickable, and
I can change the point
of view now to drive like that.
Ah! Okay, and you can
see that the transition
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
Ah! Okay, and you can
see that the transition
between the 2 point of view is
smooth because it's just done
between using an
implicit transaction,
and so that's really
super easy to do.
So this sample code
is available.
It is very small - sorry
- it's about 600 lines
of code, so very easy to do.
Thank you.
[ Applause ]
Okay, so still related to
animations and interactivity
in general, now constraints.
You can set an array of
constraints to a node.
These constraints will
be applied sequentially,
and they will be
applied at render time.
So, that means that the
constraints will never modify
your model tree, so
models that you set
and get programmatically,
it will be applied
at the very last
moment of the rendering.
We support custom constraints
where you can program your block
and apply whatever transform you
want on the node's transform.
We also support some
predefined constraints,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We also support some
predefined constraints,
like the LookAtConstraint.
So, LookAtConstraint forces a
node to look at another node.
For example here, if
I set LookAtConstraint
to these arrows, it will
make my arrows to look
into the direction
of the sphere here,
and note that I'm doing it
inside an implicit transaction
to make a smooth transition.
And since it is done at render
time, I can just move my sphere
and you can see that
the constraints
automatically update.
Then a typical use case
is to use this constraint
on the node that
owns the camera.
For example, now to have my
camera to follow that node.
And since everything
are nodes in SceneKit,
you can also set this
constraint on the node
that owns the spotlight,
and now you can see
that I have my spotlight that
can follow this node as well.
Thank you.
[ Applause ]
New in this release, we are
adding one more constraint
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
New in this release, we are
adding one more constraint
that we named SCNIKConstraint.
IK stands for inverse
kinematics, and this one is hard
to explain by a French
guy, but I'll try.
IK constraints apply
on a node chain.
The node chain is specified as
a base node and a root node,
and the 2 nodes must be
in the same hierarchy.
The IK constraints
will force your node
to keep the same
original related distance
between each other.
So to give an example
here, I have a character
that is playing an
idle animation,
and when I press Next, it does
an attack animation like this.
So IK are often used to control
articulated things like the arm
of robots or characters.
Now, let's say I want to do
the same attack animation,
but this time I want
to hit this target.
By default, it will
just miss the target.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
By default, it will
just miss the target.
Now, I can use an IK
constraint to move the lift
of my node chain in the
direction of that target,
and the IK constraint will
automatically make sure
that the hand and the elbow and
the shoulder stay consistent.
And I can also modulate the
effect of the IK constraints
over time by modifying
the influence factor
of the IK constraint to make
its effect increase during
the animation.
So for example here, by
combining the attack animation
and the IKConstraint, I
can do something like this.
Hit the target.
Note that here I'm also using
a LookAtConstraint for the head
of the character
to make it to look
in the direction of the target.
So, if I move the target down,
you can see that the head
of the character
follows the target.
I can still use the
IK constraints
to hit the target like this.
I will do it one last
time because it's fun.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
I will do it one last
time because it's fun.
And beam! Okay.
[ Applause ]
Okay, now one note
about scriptability.
Note that in this release,
now SceneKit is fully bridged
with JavaScript using
JavaScript call APIs.
It's simple to set up: just
call SCNExportJavaScriptModule
and pass a JavaScript
Core Context.
This will set up the
JavaScript Core Context
with all the SceneKit
symbols and classes,
and once this is done you
can reference your 3D objects
from JavaScript and even write
whatever script you want.
To give you an idea
of how SceneKit looks
like in JavaScript,
you can do everything:
you can allocate objects, modify
whatever properties of course,
you can modify the
scene graph if you want,
and you can even start
implicit transaction
to do implicit animations with
JavaScript, and this is cool.
And JavaScript is very handy
for tools and debugging.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
And JavaScript is very handy
for tools and debugging.
For example, if you want to
have at any time to be able
to write a script in a
console to debug your game
or to have it console
in your own tools,
this is very convenient.
Okay? So that's all
for animations,
and so there are
definitely a lot
of things I did not cover
yet, like the skinning,
for example, the
morphing as well.
For this, please refer to
last year's presentation.
Now, I hand it over to Aymeric
for the rest of the
presentation.
Thank you.
[ Applause ]
>> Thanks, Thomas.
Good morning, everyone.
My name is Aymeric, and I'm
going to talk about rendering.
Thomas already showed
you how to load a scene
or create it from scratch.
We now see how you can make it
visually nice using material.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
We now see how you can make it
visually nice using material.
While geometry defines
the shape of a node,
material defines its appearance.
That means its color, its
transparency, and interactions
with light like diffuse
and specular reflections.
SceneKit uses the SCNMaterial
class to represent material.
You can imagine it
as a toolbox full
of properties controlling an
underlying optimized shadow.
Here is an example of a
nicely configured material.
A satellite image is used
as a diffuse map while
the oceans are masked
as the only specular areas.
A normal map is used
to simulate a mountain,
while an emission maps display
the city lights shining even
in the dark.
Finally, a cloud layer has been
added using a transparent map
on a separate object.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
on a separate object.
All these properties
uses instances
of SCNMaterialProperty class.
Let's see how we can
fill our contents.
First, we can set a plain color
using an NSColor or CGColorRef.
Then, of course, we
can set an image.
The easiest way to set an
image is using an image path,
either using an NS
string or an NS URL.
This is the most optimized way.
Simply save an extra copy of
the image in the system memory.
Of course, you can set image
using NSImage or UIImage,
but new in this release
we also support SKTexture.
This will allow you to use the
cool features of SpriteKit,
like [inaudible],
procedural node generation,
and automatic normal
map generation.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
For dynamic contents, we
still support CALayer and,
new in this release,
SpriteKit Scene.
This video is played
using a SKVideo node.
For the reflective property,
we also support cube maps.
Cube maps are useful
to represent a complete
environment.
To set a cube map
on the property,
simply set an array
of 6 separate images.
If you want to customize the
standard materials of SceneKit,
you may want to use
shader modifiers.
Modifiers are little
snippets of GLSL code
that can be injected
at specific stages.
You can apply modifiers directly
into materials or
onto a geometry.
In this case, every
material used
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
In this case, every
material used
by the geometry will
be modified.
Here are some examples
of shader modifiers.
The first, Ripple Effect is
working at the geometry stage.
The Liquid Noise Effect's
working at the surface stage,
while the Rim Lighting Effect is
obviously at the lighting stage.
Finally, we fake an old TV interlacing
mode using a fragment modifier.
For more information, for more
details about shader modifiers,
please refer to last
year's session.
If you want to completely
replace a specific material,
you can do so by
using SCNProgram.
These are GLSL programs like
Vertex and Fragment shaders,
and new this year but
only on OS X, geometry
and tessellation shaders
are supported too.
This will allow you to take the
full control of the rendering.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
SceneKit only provides
you geometry attributes
like position, normal,
and texture coordinates,
and transform uniforms
like model view
and projection matrices.
For even more control, you can
inject OpenGL code directly
before or after the
scene rendering.
This allows effects
like this vortex tunnel
that was done using
a full screen quad
on a custom fragment program.
You can also inject OpenGL
code on a specific node basis,
allowing you to inject code
during scene rendering among
those objects.
So, new in this release also,
we support overlaying a
SpriteKit scene directly
onto the SceneKit scene.
This is how we did
the speedometer
in the toy car demo
Thomas showed you earlier.
This is the preferred
way to all your UI needs,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
This is the preferred
way to all your UI needs,
because you only will have
to write once your event
and link code in SpriteKit, and
it will work on iOS, on OS X,
and it also quite performant
because SpriteKit nodes are
directly rendered in our buffer,
saving on extra compositing.
So, that's all for rendering
and rendering customization.
Let's now browse the effects
available in SceneKit to dress
up your scenes, starting
with particles.
Particle systems are commonly
used in movies and videogames
to simulate a large class
of effects, like fire, rain,
smoke, and explosions.
In this release, we introduce
a new SCNParticleSystem class
that will allow you all
of these effects and more.
Because particles have a
large number of properties,
we also provide you with
this new release of Xcode,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
a new 3D particle editor
that will allow you
to tweak almost all
properties of ParticleSystem.
So, let's see what kind of
effect we can achieve with it.
Here is a hot fire
effect that is done
with a flame texture
set as a particle image.
We animate the color
and the size
of the particle over
the lifespan.
We also use an additive
blending,
but we could also have used
a screen blending among other
blend modes.
ParticleSystem can be
local, like the one
in the background moving
as a [inaudible] or global
like the one in the front,
where particles are directly
emitted in workspace.
Particles can be
affected by gravity.
They can also collide
with nodes of any shapes.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
They can also collide
with nodes of any shapes.
Just beware of your
triangle counts, though.
Particles can be
affected by physics fields
like this turbulence field
or this vortex field.
ParticleSystem can also generate
subsystems on specific events,
like particle bursts,
deaths or collision.
Here, each raindrop
generates a sub-splash system
when hitting the floor.
You can even apply custom
block on this particle event
or on each simulation step.
Here, the confettis are
laid down and stand still
when they touch the floor.
ParticleSystem can be
emitted from inside
or from the surface
of any shape.
These shapes are represented
using standard geometries.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
These shapes are represented
using standard geometries.
Please note that we recommend
that you use parametric
geometries
as they will provide
the best performances
and a better spatial
distribution.
Here are some kinds of
parametric geometries.
As I've said earlier, it
is the recommended way
to create ParticleSystem is
through the 3D Particle
Editor built into Xcode.
Starting from the provided
templates, you will be able
to tweak and customize
your system.
Then, you will save them as
.scnp files that you'll be able
to later load in your app.
One of the most important
visual cue regarding depths
and contact is shadows,
and SceneKit provides
several ways to do shadows.
The first way is to
directly bake your shadow map
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The first way is to
directly bake your shadow map
into your authoring tool.
Then, you will use them
on the Multiply properties
of your receiving materials.
While this provides the
best looking shadows,
and they are quite efficient
as well, the effect will break
if you try to move your shadow
casters or even the light.
But SceneKit also
supports dynamic shadows.
All you have to do is enable
castsShadow on the spotlight or,
new this release, a
directional light.
Then your receivers, caster,
and even the light will be able
to move as the shadow map
will be generated each frame.
If you want to move
your shadow casters
but have a limited GPU budget,
you can also use
projected shadows
where a simple texture will fake
soft shadow when set on a gobo
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
where a simple texture will fake
soft shadow when set on a gobo
with a ShadowModeModulated.
The next session will
cover this in more detail.
New in this release, we also
added a global fog on the scene.
Just set a fog color,
the range you want it
to operate, and you're done.
You can even control or
animate the density of the fog.
Another commonly used effect
in games is the use
of depth of field.
Here again, with SceneKit
it's really easy to do.
All you have to do is tweak
a few focal properties
on the camera and you can
achieve effects like out
of focus in the background
or in the foreground.
It's that simple.
[ Applause ]
The integration of Core
Image also allows you
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The integration of Core
Image also allows you
to use several screen-space
fancy effects.
Applying on a single node or
hierarchy, you can do effects
like Gaussian blurs, distortion
like this Pixelate Effect,
or any kind of color
processing you want.
The last big new thing in this
release that I wanted to talk
about is the addition
of multi-pass technique.
Shadows, Core Image
filter, depth of field,
all of these are internally
built using techniques.
And now, with this release, we
offer you to create your own.
So, what is a technique?
A technique is a
sequence of passes.
Each pass can render the
scene, a specific object
or full-screen quad,
using custom vertex
and fragment programs.
Techniques have outputs, like
a color or depth render target.
They usually have inputs
that can be constant textures
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
They usually have inputs
that can be constant textures
or other passes render target.
They can also modify
states like blend states.
So, this passes from a graph
where render targets are
produced and consumed.
Techniques were designed
to be data-driven.
They can be entirely configured
through a property list
referencing external vertex
and fragment shader.
This setup allows
you quick iterations
and tweaking your effects
without rebuilding
your application.
Let's see how to
create a technique.
The easiest way is to load it
from a dictionary usually coming
from a property list, but
you can also create technique
by chaining several
techniques together.
When you have a technique,
simply set it
to a view and you're done.
Here's an example
of a simple depth
of field done using techniques.
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
The first pass here
renders the scene normally,
writing into a color
on a depth buffer.
Then a second pass takes the
color buffer from the first one
and generates a blurred
version of it.
Finally, the third pass
combines the normal color buffer
and the blurred one
using the depth buffer
as a blending factor.
So, that's all for techniques.
So let's sum up what you should
take away from this session.
SceneKit now is available
on iOS.
It is ready for casual
games thanks to physics,
actions and animations.
It's also lot
of rendering possibilities using
standard materials and effects
like particles, and it has
a lot of control for you
to customize its
rendering with things
like shader modifiers
and techniques.
One last thing is, as
you may have guessed,
X-TIMESTAMP-MAP=MPEGTS:181083,LOCAL:00:00:00.000
One last thing is, as
you may have guessed,
this session was created
entirely in SceneKit,
and we are happy to give
it to you as a sample code.
[ Applause ]
So, I strongly encourage you to
download it and give it a try.
It's almost as fun as Swift.
[ Laughter & Applause ]
For more information,
please contact our
Evangelist Allan and Filip.
We have a brand new
documentation for you
in the developer website
and also a dedicated forum.
Thanks.
[ Applause ]