O introducere în SceneKit Fundamentele

Ce veți crea

În acest tutorial, veți învăța cum să creați o scenă 3D de bază în SceneKit fără complexitatea OpenGL. Aceasta include geometria de bază, camerele, lumina, materialele și umbrele.

Introducere

Cadrul SceneKit a fost lansat pentru prima dată de către Apple alături de OS X 10.8 Mountain Lion și a fost ulterior pus la dispoziție pe iOS cu lansarea iOS 8. Scopul acestui cadru este de a permite dezvoltatorilor să integreze cu ușurință grafica 3D în jocuri și aplicații fără complexitatea grafică API, cum ar fi OpenGL și Metal.

SceneKit vă permite să furnizați pur și simplu o descriere a activelor pe care le doriți în scenă, cu cadrul însuși manipulând tot codul de redare OpenGL pentru dvs. În acest prim tutorial, vă voi învăța câteva dintre fundamentele de lucru cu active 3D și elementele de bază ale cadrului SceneKit.

Acest tutorial cere să rulați la Xcode 6 sau o versiune superioară. În timp ce nu este necesar, vă recomandăm să utilizați un dispozitiv fizic care rulează iOS 8 pentru a vă testa codul SceneKit. Puteți folosi simulatorul iOS, dar performanța nu este excelentă dacă scena dvs. devine mai complexă. Rețineți că testarea pe un dispozitiv fizic iOS necesită un cont de dezvoltator iOS înregistrat.

1. Fundamentele

Primul lucru pe care trebuie să știți despre SceneKit este că activele, reprezentate de noduri, sunt aranjate într-un arbore ierarhic numit graficul scenei. Dacă sunteți familiarizat cu dezvoltarea iOS, acest arbore funcționează mult ca un obișnuit vizualiza ierarhiaîn UIKit. Fiecare scenă pe care o creați are un singur nod rădăcină în care adăugați noduri ulterioare și care oferă, de asemenea, o bază pentru sistemul de coordonate 3D al acelei scene.

Când adăugați un nod la o scenă, poziția sa este specificată de un set de trei numere, un vector cu trei componente reprezentat de SCNVector3 structură în codul dvs. Fiecare dintre aceste trei componente definește poziția nodului pe axele x, y și z, după cum se arată în imaginea de mai jos.

Credit de imagine: Apple SceneKit Cadru de referință

Poziția nodului tău rădăcină este definită ca (0, 0, 0). În imaginea de mai sus, aceasta este poziția în care se intersectează cele trei axe. Camera inclusă în imagine reprezintă direcția implicită pe care un aparat de fotografiat o aduce în scenă.

Acum că știți câteva dintre elementele de bază despre modul în care obiectele sunt reprezentate de SceneKit, sunteți gata să începeți să scrieți un cod.

2. Configurarea proiectului

Deschideți Xcode și creați un nou Aplicația iOS bazat pe Vizualizare individuală șablon. În timp ce puteți crea cu ușurință o aplicație de la Joc șablon folosind SceneKit, pentru acest tutorial vă voi arăta cum să începeți să lucrați cu SceneKit de la zero.

Introduceți a numele produsului, a stabilit Limba la Rapid, și Dispozitive la universal. Clic Următor → a continua.

După crearea proiectului, navigați la ViewController.swift și adăugați următoarea declarație de import în partea de sus pentru a importa cadrul SceneKit:

import SceneKit

Apoi, adăugați următoarea implementare a viewDidLoad metodă în ViewController clasă:

override func vizualizareDidLoad () super.viewDidLoad () permite sceneView = SCNView (cadru: self.view.frame) self.view.addSubview (sceneView)

În viewDidLoad metoda, vom crea o SCNView obiect, trecând în cadrul vizualizării controlerului de vizualizare. Noi atribuim SCNView exemplu la o constantă, sceneView, și adăugați-o ca o subiectivă a vizualizării controlerului de vizualizare.

 SCNView clasa este o subclasă de UIView și oferă o priză pentru conținutul dvs. SceneKit. Pe lângă faptul că are funcționalitatea unei viziuni obișnuite, o SCNView are de asemenea mai multe proprietăți și metode referitoare la conținutul SceneKit.

Pentru a verifica dacă totul funcționează corect, construiți și executați aplicația. Veți vedea că aveți doar o vizualizare alb albă.

3. Setarea scenelor

Pentru a reda conținut într-un SCNView, trebuie mai întâi să creați un SCNScene și alocați-l opiniei. În această scenă, trebuie să adăugați a camera foto și cel puțin o lumină. Pentru acest exemplu, veți adăuga, de asemenea, un cub pentru SceneKit pentru a face. Adăugați următorul cod la viewDidLoad metodă:

override funcția viewDidLoad () super.viewDidLoad () let sceneView = SCNView (cadru: self.view.frame) auto.view.addSubview (sceneView) let scene = SCNScene () sceneView.scene = scena let camera = SCNCamera cameraNode = camera SCNNode () cameraNode.camera = cameraName.position = SCNVector3 (x: 0.0, y: 0.0, z: 3.0) (n = 1, lm: 1.5, z: 1.5) permite cubeGeometry = SCNBox (lățime: 1,0, înălțimea: 1,0, lungimea: 1,0, chamferRadius: 0,0). rootNode.addChildNode (lightNode) scena.rootNode.addChildNode (cameraNode) scene.rootNode.addChildNode (cubeNode)

Să trecem prin viewDidLoad metoda pas cu pas:

  • Mai întâi creați scenă pentru vizualizarea dvs. invocând init metodă. Dacă nu încărcați o scenă pregătită dintr-un fișier extern, acesta este inițializatorul pe care îl veți folosi întotdeauna.
  • Apoi, creați un SCNCamera obiect și an SCNNode exemplu pentru camera foto. Apoi, atribuiți SCNCamera obiecte față de aparat foto proprietatea cameraNode și mutați acest nod de-a lungul axei z pentru a vedea cubul pe care îl veți crea un pic mai târziu.
  • În pasul următor, creați un SCNLight obiect și a SCNNode numit lightNode. SCNLight este atribuită instanței ușoară proprietatea nodului luminos. tip proprietate a SCNLight este setat sa SCNLightTypeOmni. Acest tip de lumină distribuie lumină în mod egal în toate direcțiile dintr-un punct din spațiul 3D. Vă puteți gândi la acest tip de lumină ca la un bec obișnuit.
  • În cele din urmă, creați un cub utilizând SCNBox clasa, făcând lățimea, înălțimea și lungimea cu aceeași dimensiune. SCNBox clasa este o subclasă de SCNGeometry și este una dintre formele primitive pe care le puteți crea. Alte forme includ sfere, piramide și torusi. De asemenea, creați un nod care trece în cub pentru geometrie parametru.
  • Pentru a seta scena în sus, adăugați cele trei noduri (cameră, lumină și cub) la graficul de scenă al scenei. Setarea suplimentară nu este necesară ca atare SCNScene Obiectul detectează automat când un nod conține o cameră sau un obiect luminoas, făcând scena în consecință.

Construiți și rulați aplicația dvs. și veți vedea că aveți acum un cub negru care este iluminat de lumina dvs. din colțul din dreapta sus.

Din păcate, cubul nu arată în acest moment tridimensional. Acest lucru se datorează faptului că aparatul foto este poziționat direct în fața acestuia. Ceea ce aveți de gând să faceți acum este să schimbați poziția aparatului foto astfel încât acesta să aibă o vedere mai bună asupra cubului.

Pentru a păstra aparatul foto îndreptat direct spre cub, cu toate acestea, veți adăuga, de asemenea, un SCNLookAtConstraint la camera foto. Începeți prin actualizarea poziției camerei, după cum se arată mai jos.

cameraNode.position = SCNVector3 (x: -3.0, y: 3.0, z: 3.0)

Apoi, adăugați următorul fragment de cod în metoda viewDidLoad, după instanțializarea nodului pentru cub:

constraint = SCNLookAtConstraint (țintă: cubeNode) constraint.gimbalLockEnabled = true cameraNode.constraints = [constraint]

Schimbarea poziției mută camera la stânga și în sus. Prin adăugarea unei constrângeri, cu cubul ca țintă și gimbalLockEnabled setat la Adevărat, vă asigurați că în acest caz camera va rămâne paralelă cu orizontul și cu fereastra de vizualizare, ecranul dispozitivului dvs. Aceasta se face prin dezactivarea rotației de-a lungul axei rolei, axa care indică de la aparatul de fotografiat la ținta constrângerii.

Construiți și rulați aplicația din nou și veți vedea cubul în toată gloria 3D.

4. Materiale și umbre

Este timpul să adăugați mai multă realism scena cu materiale și umbre. În primul rând veți avea nevoie de un alt obiect pentru a arunca o umbră. Utilizați următorul fragment de cod pentru a crea un plan, un dreptunghi plat și poziționați-l sub cub. Nu uitați să adăugați noul nod ca nod copil la nodul rădăcină al scenei.

override functie viewDidLoad () ... lasa cubeGeometry = SCNBox (lățime: 1.0, înălțime: 1.0, lungime: 1.0, chamferRadius: 0.0) permite cubeNode = SCNNode (geometrie: cubeGeometrie) (x: 0, y: -0.5, z: 0) planNode.position = SCNNode (geometrie: planeGeometrie) planeNode.eulerAngles = SCNVector3 (x: GLKMathDegreesToRadians ... scene.rootNode.addChildNode (lightNode) scene.rootNode.addChildNode (cameraNode) scene.rootNode.addChildNode (cubeNode) scene.rootNode.addChildNode (planeNode)

Prin schimbarea nodului plan Unghiurile lui Euler proprietate, rotiți planul înapoi cu 90 de grade de-a lungul axei x. Trebuie să facem acest lucru, deoarece avioanele sunt create vertical în mod implicit. În SceneKit, unghiurile de rotație sunt calculate mai degrabă în radiani decât în ​​grade, dar aceste valori pot fi ușor convertite utilizând GLKMathDegreesToRadians (_ :) și GLKMathsRadiansToDegrees (_ :) funcții. GLK reprezintă GLKit, cadrul OpenGL al Apple.

Apoi, adăugați un material la cub și avion. Pentru acest exemplu, veți da cubului și avionului o culoare solidă, respectiv roșu și verde. Adăugați următoarele linii la viewDidLoad pentru a crea aceste materiale.

override functie viewDidLoad () ... planeNode.position = SCNVector3 (x: 0, y: -0.5, z: 0) redMaterial = SCNMaterial () redMaterial.diffuse.contents = UIColor.redColor () cubeGeometry.materials = [redMaterial] permiteți greenMaterial = SCNMaterial () greenMaterial.diffuse.contents = UIColor.greenColor () planeGeometry.materials = [greenMaterial] permite constraint = SCNLookAtConstraint (target: cubeNode) ...

Pentru fiecare SCNMaterial obiect, îi atribuiți conținuturile sale difuze a UIColor valoare. Proprietatea difuză a unui material determină cum apare atunci când se află în lumină directă. Rețineți că valoarea atribuită nu trebuie să fie a UIColor obiect. Există multe alte tipuri de obiecte acceptabile pentru a le atribui acestei proprietăți, cum ar fi UIImageCALayer, și chiar și o textură SpriteKit (SKTexture).

Construiți și rulați din nou aplicația dvs. pentru a nu vedea doar avionul pentru prima dată, ci și materialele pe care le-ați creat.

Acum este timpul să adăugați niște umbre la scenă. Dintre cele patru tipuri de lumină disponibile în SceneKit, numai luminile spot pot crea umbre. Pentru acest exemplu, veți transforma lumina omni existente într-o lumină spot, orientată spre cub. Adăugați următorul cod la viewDidLoad metodă:

override functie viewDidLoad () ... permite lumina = SCNLight () light.type = SCNLightTypeSpot lumina.spotInnerAngle = 30.0 light.spotOuterAngle = 80.0 light.castsShadow = true da lightNode = SCNNode () lightNode.light = lumina luminiiNode.position = SCNVector3 x: 1.5, y: 1.5, z: 1.5) ... constraint = constraint = constraint = constraint = constraint = constraint = constraint constraint.gmpalLockEnabled = true cameraNode.constraints =

Pentru a crea lumina spot, setați mai întâi tipul luminii SCNLightTypeSpot. Apoi specificați unghiurile interioare și exterioare ale luminilor spot în grade. Valorile implicite sunt 0 și 45 respectiv. Unghiul interior determină suprafața pe care lumina o acoperă în lumină directă, în timp ce unghiul exterior determină cât spațiu este parțial luminat. Diferența dintre aceste unghiuri va deveni clară odată ce veți vedea scena rezultată. Apoi, spuneți în mod explicit lumina să arunce umbre și, de asemenea, adăugați la fel SCNLookAtConstraint pe care l-ați creat mai devreme pentru camera dvs. foto.

Construiți și rulați aplicația pentru a vedea scena rezultată. Unghiul interior specificat în codul dvs. este afișat în cazul în care planul este un verde solid, direct sub cub. Unghiul exterior este arătat de gradientul de lumină care se estompează la negru pe măsură ce se îndepărtează de ținta luminii.

Veți vedea că acum ați luat cubul dvs. aruncând o umbră corect. Lumina spotului, totuși, luminează doar o parte a avionului. Acest lucru se datorează faptului că nu există lumină ambientală în scenă. 

O lumină ambientală este o sursă de lumină care luminează totul cu o distribuție egală a luminii. Deoarece o lumină ambientală luminează întreaga scenă, poziția sa nu contează și o puteți adăuga la orice nod pe care îl doriți, chiar la același nod ca și camera dvs. foto. Utilizați următorul fragment de cod pentru a crea o lumină ambientală pentru scenă.

override functie viewDidLoad () ... permite camera = SCNCamera () lasa cameraNode = SCNNode () cameraNode.camera = CameraName.position = SCNVector3 (x: -3.0, y: 3.0, z: 3.0) .type = SCNLightTypeAmbient ambientLight.color = UICcolor (roșu: 0,2, verde: 0,2, albastru: 0,2, alfa: 1,0) cameraNode.light = ambientLight ...

Fragmentul de cod creează un SCNLight, la fel cum ați făcut înainte. Diferența principală este cea a luminii tip proprietate, care este setat la SCNLightTypeAmbient. De asemenea, setați culoarea la un gri închis, astfel încât să nu depășească scena. Culoarea implicită pentru o lumină este albă pură (valoarea RGB de 1, 1, 1) și având această culoare pe o lumină ambientală determină ca întreaga scenă să fie complet iluminată așa cum se arată în imaginea de mai jos.

Construiți și rulați aplicația ultima oară pentru a vedea rezultatul final.

Concluzie

Dacă ați reușit până la sfârșitul acestui tutorial, acum ar trebui să vă simțiți confortabil cu următoarele subiecte:

  • sistemul de coordonate 3D și graficul scenelor folosite de SceneKit
  • înființarea unui SCNView cu un SCNScene
  • adăugând camere, lumini și noduri la o scenă
  • atribuirea de materiale geometriei
  • lucrul cu lumini pentru a ilumina o scenă și umbre aruncate

În următorul tutorial al acestei serii, veți afla despre câteva concepte mai avansate ale cadrului SceneKit, inclusiv animația, interacțiunea cu utilizatorul, sistemele de particule și simularea fizicii.

Cod