{"id":12064,"date":"2014-06-26T08:00:08","date_gmt":"2014-06-26T12:00:08","guid":{"rendered":"http:\/\/blog.xamarin.com\/?p=12064"},"modified":"2014-06-26T08:00:08","modified_gmt":"2014-06-26T12:00:08","slug":"3d-in-ios-8-with-scene-kit","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/3d-in-ios-8-with-scene-kit\/","title":{"rendered":"Lights, Camera, Action &#8211; 3D in iOS 8 with Scene Kit"},"content":{"rendered":"<p>\t\t\t\t<strong>Scene Kit<\/strong> is a powerful 3D graphics API that makes working with 3D a snap. It was first introduced in OS X 10.8, and has now come to iOS 8. With Scene Kit, creating immersive 3D visualizations and casual 3D games no longer requires expertise in <a href=\"http:\/\/www.opengl.org\/\" title=\"opengl.org\" target=\"_blank\">OpenGL<\/a>. Building on common scene graph concepts, Scene Kit abstracts away the complexities of OpenGL and OpenGL ES, making it very easy to add 3D content to an application. However, if you are an OpenGL expert, Scene Kit has great support for tying in directly with OpenGL as well. It also includes numerous features that complement 3D graphics, such as physics, and integrates very well with several other Apple frameworks, such as Core Animation, Core Image and Sprite Kit.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12071\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/earth.png\" alt=\"3D earth\" width=\"258\" height=\"542\" \/><\/p>\n<p>Scene Kit is extremely easy to work with. It is a declarative API that takes care of rendering. You simply set up a scene, add properties to it, and the magic of Scene Kit brings it all to life.<\/p>\n<p>To work with Scene Kit you create a scene graph using the <strong>SCNScene<\/strong> class. A scene contains a hierarchy of nodes, represented by instances of <strong>SCNNode<\/strong>, defining locations in 3D space. Each node has properties such as geometry, lighting and materials that affect its appearance.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12073\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/nodetree.png\" alt=\"node tree\" width=\"432\" height=\"324\" \/><\/p>\n<p>To make a scene appear on screen, you add it to an <strong>SCNView<\/strong> by assigning it to the view&#8217;s <strong>Scene<\/strong> property. Additionally, if you make any changes to the scene, <strong>SCNView<\/strong> will update itself to display the changes.<\/p>\n<pre class=\"lang:csharp decode:true\">\nscene = SCNScene.Create ();\nsceneView = new SCNView (View.Frame);\nsceneView.Scene = scene;\n<\/pre>\n<p>Scenes can be populated from files exported via a 3d modeling tool, or programmatically from geometric primitives. For example, this is how to create a sphere and add it to the scene:<\/p>\n<pre class=\"lang:csharp decode:true\">\nsphere = SCNSphere.Create (10.0f);\nsphereNode = SCNNode.FromGeometry (sphere);\nsphereNode.Position = new SCNVector3 (0, 0, 0);\nscene.RootNode.AddChildNode (sphereNode);\n<\/pre>\n<h2>Let There Be Light<\/h2>\n<p>At this point the sphere won&#8217;t display anything because there is no light in the scene. Lights in Scene Kit are created by attaching <strong>SCNLight<\/strong> instances to nodes. There are several types of lights ranging from various forms of directional lighting to ambient lighting. For example the following code creates an omni directional light on the side of the sphere.<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/ omni-directional light\nvar light = SCNLight.Create ();\nvar lightNode = SCNNode.Create ();\nlight.LightType = SCNLightType.Omni;\nlight.Color = UIColor.Blue;\nlightNode.Light = light;\nlightNode.Position = new SCNVector3 (-40, 40, 60);\nscene.RootNode.AddChildNode (lightNode);\n<\/pre>\n<p>Omni directional lighting produces a diffuse reflection resulting in an even lighting, sort of like shining a flashlight. Creating ambient light is similar, although it has no direction as it shines equally in all directions. Think of it like mood lighting \ud83d\ude42<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/ ambient light\nambientLight = SCNLight.Create ();\nambientLightNode = SCNNode.Create ();\nambientLight.LightType = SCNLightType.Ambient;\nambientLight.Color = UIColor.Purple;\nambientLightNode.Light = ambientLight;\nscene.RootNode.AddChildNode (ambientLightNode);\n<\/pre>\n<p>With the lights in place, the sphere is now visible in the scene.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12075\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/sphere1.png\" alt=\"sphere\" width=\"258\" height=\"542\" \/><\/p>\n<h2>Adding a Camera<\/h2>\n<p>Adding a camera (<strong>SCNCamera<\/strong>) to the scene changes the point of view. The pattern to add the camera is similar. Create the camera, attach it to a node and add the node to the scene.<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/ camera\ncamera = new SCNCamera {\n\tXFov = 80,\n\tYFov = 80\n};\ncameraNode = new SCNNode {\n\tCamera = camera,\n\tPosition = new SCNVector3 (0, 0, 40)\n};\nscene.RootNode.AddChildNode (cameraNode);\n<\/pre>\n<p>As you can see from the code above, Scene Kit objects can be created using constructors or from the <strong>Create<\/strong> factory method. The former allows using C# initializer syntax, but which one to use is largely a matter of preference.<\/p>\n<p>With the camera in place, the entire sphere is visible to the user.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12077\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/sphere2.png\" alt=\"sphere\" width=\"258\" height=\"542\" \/><\/p>\n<p>You can add additional lights to the scene as well. Here is what it looks like with a few more omni-directional lights:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12079\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/sphere3.png\" alt=\"sphere\" width=\"258\" height=\"542\" \/><\/p>\n<p>Additionally, by setting <code>sceneView.AllowsCameraControl = true<\/code>, the user can change the point of view with a touch gesture.<\/p>\n<h2>Materials<\/h2>\n<p>Materials are created with the <strong>SCNMaterial<\/strong> class. For example to add an image onto the sphere&#8217;s surface, set the image to the material&#8217;s diffuse contents.<\/p>\n<pre class=\"lang:csharp decode:true\">\nmaterial = SCNMaterial.Create ();\nmaterial.Diffuse.Contents = UIImage.FromFile (&quot;monkey.png&quot;);\nsphere.Materials = new SCNMaterial[] { material };\n<\/pre>\n<p>This layers the image onto the node as shown below.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12081\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/sphere4.png\" alt=\"sphere\" width=\"258\" height=\"542\" \/><\/p>\n<p>A material can be set to respond to other types of lighting too. For example, the object can be made shiny and have a its specular contents set to display specular reflection, resulting in a bright spot on the surface.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12083\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/sphere5.png\" alt=\"sphere\" width=\"258\" height=\"542\" \/><\/p>\n<p>Materials are very flexible, allowing you to achieve a lot with very little code. For example, instead of setting the image to the diffuse contents, set it to the reflective contents instead.<\/p>\n<pre class=\"lang:csharp decode:true\">\nmaterial.Reflective.Contents = UIImage.FromFile (&quot;monkey.png&quot;);\n<\/pre>\n<p>Now the monkey sits visually within the sphere, independent of the point of view, creating a monkey in a psychedelic 1960s sphere so to speak.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12091\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/psychmonkey.gif\" alt=\"spinning monkey\" width=\"155\" height=\"279\" \/><\/p>\n<h2>Animation<\/h2>\n<p>Scene Kit is designed to work well with Core Animation. You can create both implicit or explicit animations. When creating an implicit animation, Scene Kit provides its own transition class, <strong>SCNTransaction<\/strong>.<\/p>\n<p>Here&#8217;s a example that rotates the sphere:<\/p>\n<pre class=\"lang:csharp decode:true\">\nSCNTransaction.Begin ();\nSCNTransaction.AnimationDuration = 2.0;\nsphereNode.Rotation = new SCNVector4 (0, 1, 0, (float)Math.PI * 4);\nSCNTransaction.Commit ();\n<\/pre>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12087\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/rotation.png\" alt=\"rotation\" width=\"536\" height=\"542\" \/><\/p>\n<p>You can animate much more than rotation though. Many properties of Scene Kit are animatable. For example, the following code animates the material&#8217;s <strong>Shininess<\/strong> to increase the specular reflection.<\/p>\n<pre class=\"lang:csharp decode:true\">\nSCNTransaction.Begin ();\nSCNTransaction.AnimationDuration = 2.0;\nmaterial.Shininess = 0.1f;\nSCNTransaction.Commit ();\n<\/pre>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-12088\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/shininess.png\" alt=\"shininess\" width=\"536\" height=\"542\" \/><\/p>\n<p>As you can see, Scene Kit is incredibly easy to use. This post just scratches the surface though. There are a wealth of additional features including constraints, physics, declarative actions, 3D text, depth of field support, Sprite Kit integration and Core Image integration to name just a few. It&#8217;s exciting to see this API come to iOS 8.<\/p>\n<p>The source code from this post is available <a href=\"https:\/\/gist.github.com\/mikebluestein\/8d8486c200dd6d0f8d06\" title=\"Hello Scene Kit\" target=\"_blank\">here<\/a>.<\/p>\n<p><a href=\"http:\/\/forums.xamarin.com\/discussion\/19229\" title=\"Discuss in Forums\" target=\"_blank\"><em>Discuss this blog post in the Xamarin Forums<\/em><\/a><\/p>\n<p>&nbsp;\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Scene Kit is a powerful 3D graphics API that makes working with 3D a snap. It was first introduced in OS X 10.8, and has now come to iOS 8. With Scene Kit, creating immersive 3D visualizations and casual 3D games no longer requires expertise in OpenGL. Building on common scene graph concepts, Scene Kit [&hellip;]<\/p>\n","protected":false},"author":1932,"featured_media":39167,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[6,4],"class_list":["post-12064","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-ios","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>Scene Kit is a powerful 3D graphics API that makes working with 3D a snap. It was first introduced in OS X 10.8, and has now come to iOS 8. With Scene Kit, creating immersive 3D visualizations and casual 3D games no longer requires expertise in OpenGL. Building on common scene graph concepts, Scene Kit [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/12064","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/1932"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=12064"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/12064\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=12064"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=12064"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=12064"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}