Dans ce didacticiel, vous apprendrez à créer une scène 3D de base dans SceneKit sans la complexité d’OpenGL. Cela comprend la géométrie de base, les caméras, les lumières, les matériaux et les ombres.
Le framework SceneKit a été lancé initialement par Apple aux côtés de OS X 10.8 Mountain Lion, puis rendu disponible sur iOS avec la sortie d'iOS 8. L'objectif de ce cadre est de permettre aux développeurs d'intégrer facilement des graphiques 3D à des jeux et à des applications sans la complexité API graphiques, telles que OpenGL et Metal.
SceneKit vous permet simplement de fournir une description des éléments que vous souhaitez dans votre scène, le cadre lui-même gérant tout le code de rendu OpenGL pour vous. Dans ce premier tutoriel, je vais vous enseigner les principes de base du travail avec des éléments 3D et les bases du cadre SceneKit..
Ce tutoriel nécessite que vous exécutiez Xcode 6 ou supérieur. Bien que cela ne soit pas nécessaire, je vous recommande d’utiliser un périphérique physique sous iOS 8 pour tester votre code SceneKit. Vous pouvez utiliser le simulateur iOS, mais les performances ne sont pas excellentes si votre scène devient plus complexe. Notez que pour tester sur un périphérique iOS physique, vous devez disposer d'un compte de développeur iOS enregistré..
La première chose à savoir sur SceneKit est que les éléments, représentés par des noeuds, sont organisés dans un arbre hiérarchique appelé graphique de scène. Si vous êtes familier avec le développement iOS, cet arbre fonctionne un peu comme un logiciel ordinaire. voir la hiérarchiedans UIKit. Chaque scène que vous créez a un seul nœud racine auquel vous ajoutez des nœuds ultérieurs et qui fournit également une base pour le système de coordonnées 3D de cette scène..
Lorsque vous ajoutez un nœud à une scène, sa position est spécifiée par un ensemble de trois chiffres, un vecteur à trois composantes représenté par le symbole. SCNVector3
structure dans votre code. Chacune de ces trois composantes définit la position du nœud sur les axes x, y et z, comme indiqué dans l'image ci-dessous..
La position du noeud racine de votre scène est définie comme suit: (0, 0, 0). Dans l'image ci-dessus, il s'agit de la position où les trois axes se coupent. La caméra incluse dans l'image représente la direction par défaut de la caméra lorsqu'elle est ajoutée à votre scène..
Maintenant que vous connaissez les bases de la représentation des objets par SceneKit, vous êtes prêt à commencer à écrire du code..
Ouvrez Xcode et créez un nouveau Application iOS basé sur Application à vue unique modèle. Bien que vous puissiez facilement créer une application à partir du Jeu modèle à l'aide de SceneKit, pour ce tutoriel, je vais vous montrer comment commencer à travailler avec SceneKit à partir de zéro.
Entrez un Nom du produit, ensemble La langue à Rapide, et Dispositifs à Universel. Cliquez sur Suivant continuer.
Après avoir créé votre projet, accédez à ViewController.swift et ajoutez l'instruction d'importation suivante en haut pour importer le framework SceneKit:
importer SceneKit
Ensuite, ajoutez la mise en œuvre suivante du viewDidLoad
méthode dans le ViewController
classe:
remplacer func viewDidLoad () super.viewDidLoad () let sceneView = SCNView (cadre: self.view.frame) self.view.addSubview (sceneView)
dans le viewDidLoad
méthode, nous créons un SCNView
objet, en passant dans le cadre de la vue du contrôleur de vue. Nous assignons le SCNView
par exemple à une constante, sceneView
, et l'ajouter en tant que sous-vue de la vue du contrôleur de vue.
le SCNView
classe est une sous-classe de UIView
et fournit un point de vente pour votre contenu SceneKit. En plus d’avoir la fonctionnalité d’une vue normale, un SCNView
possède également plusieurs propriétés et méthodes relatives au contenu de SceneKit.
Pour vérifier que tout fonctionne correctement, construisez et exécutez votre application. Vous verrez que vous avez juste une vue blanche vierge.
Pour rendre le contenu dans un SCNView
, vous devez d'abord créer un SCNScene
et l'assigner à la vue. Dans cette scène, vous devez ensuite ajouter un caméra et au moins une lumière. Pour cet exemple, vous allez également ajouter un cube à rendre par SceneKit. Ajoutez le code suivant au viewDidLoad
méthode:
remplacer func viewDidLoad () super.viewDidLoad () let sceneView = SCNView (frame: self.view.frame) self.view.addSubview (sceneView) let scene = SCNScene () sceneView.scene = scène let camera = SCNCamera () let cameraNode = SCNNode () cameraNode.camera = caméra cameraNode.position = SCNVector3 (x: 0.0, y: 0.0, z: 3.0) let light = SCNLight () light.type = SCNLightTypeOmni let lightNode = SCNNode () lightNode.light = light lightNode.position = SCNVector3 (x: 1.5, y: 1.5, z: 1.5) let cubeGeometry = SCNBox (largeur: 1.0, hauteur: 1.0, longueur: 1.0, chamferRadius: 0.0) let cubeNode = SCNNode (géométrie: cubeGeometry). rootNode.addChildNode (lightNode) scene.rootNode.addChildNode (cameraNode) scene.rootNode.addChildNode (cubeNode)
Passons à travers le viewDidLoad
méthode étape par étape:
init
méthode. Sauf si vous chargez une scène préparée à partir d'un fichier externe, c'est l'initialiseur que vous utiliserez toujours.SCNCamera
objet et un SCNNode
exemple pour la caméra. Vous attribuez ensuite le SCNCamera
objecter à la caméra
propriété de cameraNode
et déplacez ce noeud le long de l'axe z pour voir le cube que vous allez créer un peu plus tard.SCNLight
objet et un SCNNode
nommé lightNode
. le SCNLight
instance est attribuée à la lumière
propriété du noeud léger. le type
propriété du SCNLight
est réglé sur SCNLightTypeOmni
. Ce type de lumière distribue la lumière uniformément dans toutes les directions à partir d'un point de l'espace 3D. Vous pouvez considérer ce type de lumière comme une ampoule ordinaire.SCNBox
classe, en faisant la largeur, la hauteur et la longueur de la même taille. le SCNBox
classe est une sous-classe de SCNGéométrie
et est l'une des formes primitives que vous pouvez créer. Les autres formes comprennent des sphères, des pyramides et des tores. Vous créez également un nœud en passant dans le cube pour le géométrie
paramètre.SCNScene
objet détecte automatiquement quand un nœud contient une caméra ou un objet lumineux, rendant la scène en conséquence.Construisez et exécutez votre application, et vous verrez que vous avez maintenant un cube noir éclairé par la lumière du coin supérieur droit..
Malheureusement, le cube n'a pas l'air en trois dimensions pour le moment. En effet, la caméra est positionnée directement devant elle. Ce que vous allez faire maintenant, c’est changer la position de la caméra pour qu’elle ait une meilleure vue du cube..
Pour que la caméra soit dirigée directement vers le cube, vous allez également ajouter un SCNLookAtConstraint
à la caméra. Commencez par mettre à jour la position de la caméra comme indiqué ci-dessous.
cameraNode.position = SCNVector3 (x: -3.0, y: 3.0, z: 3.0)
Ensuite, ajoutez l'extrait de code suivant à la méthode viewDidLoad, après l'instanciation du noeud pour le cube:
let constraint = SCNLookAtConstraint (target: cubeNode) constraint.gimbalLockEnabled = true cameraNode.constraints = [contrainte]
Le changement de position déplace la caméra vers la gauche et vers le haut. En ajoutant une contrainte, avec le cube comme cible et gimbalLockEnabled
mis à vrai
, vous vous assurez que la caméra restera parallèle à l'horizon et à la fenêtre d'affichage, l'écran de votre appareil dans ce cas. Pour ce faire, désactivez la rotation le long de l’axe de rouleau, l’axe pointant de la caméra à la cible de la contrainte..
Générez et exécutez votre application à nouveau, et vous verrez votre cube dans toute sa gloire 3D.
Il est temps d'ajouter plus de réalisme à la scène avec des matériaux et des ombres. Vous allez d’abord avoir besoin d’un autre objet sur lequel jetter une ombre. Utilisez l'extrait de code suivant pour créer un plan, un rectangle plat, puis positionnez-le sous le cube. N'oubliez pas d'ajouter le nouveau nœud en tant que nœud enfant au nœud racine de la scène..
override func viewDidLoad () … let cubeGeometry = SCNBox (largeur: 1.0, hauteur: 1.0, longueur: 1.0, chamferRadius: 0.0) let cubeNode = SCNNode (géométrie: cubeGeometry) let planeGeometry = SCNPlane (largeur: 50.0, hauteur: 50.0) let planeNode = SCNNode (géométrie: planeGeometry) planeNode.eulerAngles = SCNVector3 (x: GLKMathDegreesToRadians (-90), y: 0, z: 0) planeNode.position = SCNVector3 (x: 0, y: -0,5, z: 0) … Scene.rootNode.addChildNode (lightNode) scene.rootNode.addChildNode (cameraNode) scene.rootNode.addChildNode (cubeNode) scene.rootNode.addChildNode (planeNode)
En changeant le noeud du plan eulerAngles
propriété, vous faites pivoter le plan en arrière de 90 degrés le long de l’axe des x. Nous devons faire cela, car les plans sont créés verticalement par défaut. Dans SceneKit, les angles de rotation sont calculés en radians plutôt qu'en degrés, mais ces valeurs peuvent être facilement converties à l'aide de l'option GLKMathDegreesToRadians (_ :)
et GLKMathsRadiansToDegrees (_ :)
les fonctions. GLK signifie GLKit, le framework OpenGL d’Apple.
Ensuite, ajoutez un matériau au cube et au plan. Pour cet exemple, vous allez donner au cube et au plan une couleur unie, respectivement rouge et verte. Ajoutez les lignes suivantes au viewDidLoad
méthode pour créer ces matériaux.
override func viewDidLoad () … planeNode.position = SCNVector3 (x: 0, y: -0,5, z: 0) laissez redMaterial = SCNMaterial () redMaterial.diffuse.contents = UIColor.redColor () cubeGeometry.materials = [redMaterial] let greenMaterial = SCNMaterial () greenMaterial.diffuse.contents = UIColor.greenColor () planeGeometry.materials = [greenMaterial] let constraint = SCNLookAtConstraint (target: cubeNode)…
Pour chaque SCNMatériel
objet, vous attribuez à son contenu diffus une UIColor
valeur. La propriété diffuse d'un matériau détermine son apparence lorsqu'elle est exposée à la lumière directe. Notez que la valeur attribuée ne doit pas nécessairement être un UIColor
objet. Il existe de nombreux autres types d'objets acceptables à affecter à cette propriété, tels que UIImage
, CALayer
, et même une texture SpriteKit (SKTexture
).
Générez et exécutez à nouveau votre application pour non seulement voir l'avion pour la première fois, mais aussi les matériaux que vous avez créés..
Il est maintenant temps d'ajouter des ombres à votre scène. Parmi les quatre types de lumière disponibles dans SceneKit, seuls les projecteurs peuvent créer des ombres. Pour cet exemple, vous allez transformer votre lumière omni existante en un projecteur ciblant le cube. Ajoutez le code suivant au viewDidLoad
méthode:
override func viewDidLoad () … let light = SCNLight () light.type = SCNLightTypeSpot light.spotInnerAngle = 30.0 light.spotOuterAngle = 80.0 light.castsShadow = true laissez lightNode = SCNNode () lightNode.light = lightNode.position = SCNNode.light = lumière x: 1.5, y: 1.5, z: 1.5)… let constraint = SCNLookAtConstraint (target: cubeNode) constraint.gimbalLockEnabled = true cameraNode.constraints = [contrainte] lightNode.constraints = [contrainte]…
Pour créer le spot, vous devez d’abord définir le type de lumière sur SCNLightTypeSpot
. Vous spécifiez ensuite les angles intérieur et extérieur du projecteur en degrés. Les valeurs par défaut sont 0 et 45 respectivement. L'angle interne détermine la surface couverte par la lumière directe, tandis que l'angle externe détermine la surface partiellement éclairée. La différence entre ces angles deviendra claire une fois que vous verrez la scène résultante. Vous dites ensuite explicitement à la lumière de projeter des ombres et d'ajouter le même SCNLookAtConstraint
que vous avez créé pour votre appareil photo plus tôt.
Générez et exécutez votre application pour voir la scène résultante. L'angle interne que vous avez spécifié dans votre code est indiqué lorsque le plan est un vert continu, directement sous le cube. L'angle extérieur est indiqué par le gradient de lumière qui passe au noir à mesure qu'il s'éloigne de la cible de la lumière..
Vous verrez que votre cube projette correctement une ombre. Le spot, cependant, n’éclaire qu’une partie de l’avion. C'est parce qu'il n'y a pas de lumière ambiante dans votre scène.
Une lumière ambiante est une source de lumière qui éclaire tout avec une répartition égale de la lumière. Étant donné qu'une lumière ambiante illumine toute la scène, sa position importe peu et vous pouvez l'ajouter à n'importe quel nœud, même le même que votre caméra. Utilisez l'extrait de code suivant pour créer une lumière ambiante pour votre scène..
override func viewDidLoad () … let camera = SCNCamera () let cameraNode = SCNNode () cameraNode.camera = camera cameraNode.position = SCNVector3 (x: -3,0, y: 3.0, z: 3.0) laisse ambientLight = SCNLight () ambientLight .type = SCNLightTypeAmbient ambientLight.color = UIColor (rouge: 0,2, vert: 0,2, bleu: 0,2, alpha: 1,0) cameraNode.light = ambientLight…
L'extrait de code crée un SCNLight
, comme vous l'avez fait auparavant. La principale différence est la lumière type
propriété, qui est définie sur SCNLightTypeAmbient
. Vous définissez également sa couleur sur un gris foncé pour ne pas dominer votre scène. La couleur par défaut d'une lumière est le blanc pur (valeur RVB de 1, 1, 1) et si cette couleur est appliquée à la lumière ambiante, la scène entière sera entièrement éclairée, comme indiqué dans la capture d'écran ci-dessous..
Générez et exécutez votre application une dernière fois pour voir le résultat final.
Si vous en êtes à la fin de ce didacticiel, vous devriez maintenant être à l'aise avec les sujets suivants:
SCNView
avec un SCNScene
Dans le prochain didacticiel de cette série, vous découvrirez des concepts plus avancés du framework SceneKit, notamment l'animation, l'interaction utilisateur, les systèmes de particules et la simulation physique..