I denne opplæringen lærer du hvordan du lager en grunnleggende 3D-scene i SceneKit uten kompleksiteten til OpenGL. Dette inkluderer grunnleggende geometri, kameraer, lys, materialer og skygger.
SceneKit-rammen ble først lansert av Apple sammen med OS X 10.8 Mountain Lion og ble senere gjort tilgjengelig på iOS med utgivelsen av iOS 8. Formålet med dette rammeprogrammet er å tillate utviklere å enkelt integrere 3D-grafikk i spill og applikasjoner uten kompleksiteten av grafikk-APIer, for eksempel OpenGL og Metal.
SceneKit lar deg bare gi en beskrivelse av eiendelene du vil ha i din scene, med selve rammen som håndterer alle OpenGL-gjengivelsenskoder for deg. I denne første opplæringen vil jeg lære deg noen av grunnleggende for å jobbe med 3D-eiendeler og grunnleggende i SceneKit-rammen.
Denne opplæringen krever at du kjører på Xcode 6 eller høyere. Selv om det ikke er nødvendig, anbefaler jeg at du bruker en fysisk enhet som kjører iOS 8 for å teste din SceneKit-kode på. Du kan bruke iOS-simulatoren, men ytelsen er ikke bra hvis scenen din blir mer kompleks. Vær oppmerksom på at testing på en fysisk iOS-enhet krever at du har en registrert iOS-utviklerkonto.
Det første du trenger å vite om SceneKit er at eiendeler, representert av noder, er arrangert i et hierarkisk tre som kalles en scene graf. Hvis du er kjent med iOS-utviklingen, fungerer dette treet som en vanlig se hierarkieti UIKit. Hver scene du lager, har en enkelt rotnode som du legger til påfølgende nodene, og som også gir grunnlag for 3D-koordinatsystemet for den scenen.
Når du legger til en node på en scene, er posisjonen angitt av et sett med tre tall, en tre-komponentvektor representert av SCNVector3
struktur i koden din. Hver av disse tre komponentene definerer nodens posisjon på x-, y- og z-aksene som vist i bildet nedenfor.
Din scenes rotknuteposisjon er definert som (0, 0, 0). I bildet ovenfor er dette stedet hvor de tre aksene skjærer. Det medfølgende kameraet i bildet representerer standardretningen et kamera peker på når det legges til din scene.
Nå som du vet noen av grunnleggende om hvordan objekter er representert av SceneKit, er du klar til å begynne å skrive noen kode.
Åpne Xcode og opprett en ny iOS-applikasjon basert på Enkeltvisningsprogram mal. Mens du enkelt kan lage et program fra Spill mal ved hjelp av SceneKit, for denne opplæringen skal jeg vise deg hvordan du begynner å jobbe med SceneKit fra bunnen av.
Skriv inn en Produktnavn, sett Språk til Fort, og enheter til Universell. Klikk neste å fortsette.
Etter å ha opprettet prosjektet, naviger til ViewController.swift og legg til følgende importoppgave øverst for å importere SceneKit-rammeverket:
importere SceneKit
Deretter legger du til følgende implementering av viewDidLoad
metode i ViewController
klasse:
overstyr func viewDidLoad () super.viewDidLoad () la sceneView = SCNView (ramme: self.view.frame) self.view.addSubview (sceneView)
I viewDidLoad
Metode, vi lager en SCNView
objekt, passerer i rammen av visningskontrollørens visning. Vi tildeler SCNView
forekommer til en konstant, sceneView
, og legg det til som et undervisning av visningskontrollens visning.
De SCNView
klassen er en underklasse av UIView
og gir et uttak for ditt SceneKit-innhold. Bortsett fra å ha funksjonaliteten til en vanlig visning, an SCNView
har også flere egenskaper og metoder knyttet til SceneKit-innholdet.
For å kontrollere at alt fungerer som det skal, bygg og kjør appen din. Du vil se at du bare har en blank, hvit visning.
For å gjengi innhold i en SCNView
, du må først opprette en SCNScene
og tilordne den til visningen. I denne scenen må du legge til en kamera og minst ett lys. For dette eksempelet skal du også legge til en kube for SceneKit å gjengi. Legg til følgende kode i viewDidLoad
metode:
overstyr func viewDidLoad () super.viewDidLoad () la sceneView = SCNView (ramme: self.view.frame) self.view.addSubview (sceneView) la scene = SCNScene () sceneView.scene = scene la kamera = SCNCamera cameraNode = SCNNode () cameraNode.camera = kamera kameraNode.position = SCNVector3 (x: 0.0, y: 0.0, z: 3.0) la lys = SCNLight () light.type = SCNLightTypeOmni la lightNode = SCNNode () lightNode.light = light lightNode.position = SCNVector3 (x: 1,5, y: 1,5, z: 1,5) la cubeGeometry = SCNBox (bredde: 1,0, høyde: 1,0, lengde: 1,0, chamferRadius: 0,0) la cubeNode = SCNNode (geometri: cubeGeometry) scene. rootNode.addChildNode (lightNode) scene.rootNode.addChildNode (cameraNode) scene.rootNode.addChildNode (cubeNode)
La oss gå gjennom viewDidLoad
metode trinn for trinn:
i det
metode. Med mindre du laster inn en forberedt scene fra en ekstern fil, er dette initialisereren du alltid vil bruke.SCNCamera
objekt og en SCNNode
eksempel for kameraet. Du tilordner deretter SCNCamera
protestere mot kamera
tilhører cameraNode
og flytt denne noden langs z-aksen for å se kuben du vil lage litt senere.SCNLight
objekt og a SCNNode
oppkalt lightNode
. De SCNLight
forekomst er tildelt til lys
egenskapen til lysnoden. De type
eiendom av SCNLight
er satt til SCNLightTypeOmni
. Denne lystypen fordeler lys jevnt i alle retninger fra et punkt i 3D-plass. Du kan tenke på denne lys typen som en vanlig lyspære.SCNBox
klasse, noe som gjør bredden, høyden og lengden av samme størrelse. De SCNBox
klassen er en underklasse av SCNGeometry
og er en av de primitive figurene du kan lage. Andre former inkluderer sfærer, pyramider og toruser. Du lager også en node som passerer i terningen for geometri
parameter.SCNScene
objekt oppdager automatisk når en knute inneholder et kamera eller lysobjekt, som gjør scenen tilsvarende.Bygg og kjør appen din, og du vil se at du nå har en svart terning som lyser opp av lyset ditt fra øverste høyre hjørne.
Dessverre ser kuben ikke tredimensjonal ut i øyeblikket. Dette skyldes at kameraet er plassert rett foran den. Hva du skal gjøre nå, er å endre posisjonen til kameraet slik at det gir et bedre bilde av kuben.
For å holde kameraet spiss direkte på terningen, vil du også legge til en SCNLookAtConstraint
til kameraet. Start med å oppdatere posisjonen til kameraet som vist nedenfor.
cameraNode.position = SCNVector3 (x: -3.0, y: 3.0, z: 3.0)
Deretter legger du til følgende kodestykke i ViewDidLoad-metoden, etter at du har installert noden for terningen:
la begrensning = SCNLookAtConstraint (mål: cubeNode) constraint.gimbalLockEnabled = true cameraNode.constraints = [begrensning]
Posisjonsendringen beveger kameraet til venstre og oppover. Ved å legge til en begrensning, med terningen som mål og gimbalLockEnabled
satt til ekte
, Du sikrer at kameraet forblir parallelt med horisonten og visningsporten, enhetens skjerm i dette tilfellet. Dette gjøres ved å deaktivere rotasjon langs rulleaksen, idet aksen peker fra kameraet til begrensningens mål.
Bygg og kjør appen din på nytt, og du vil se kuben i alle sine 3D-ære.
Det er på tide å legge til mer realisme på scenen med materialer og skygger. Du kommer først til å trenge et annet objekt for å kaste en skygge på. Bruk følgende kodestykke for å lage et plan, et flatt rektangel, og plasser det under kuben. Ikke glem å legge til den nye noden som en barnekode til scenens rotknutepunkt.
overstyr func viewDidLoad () ... la cubeGeometry = SCNBox (bredde: 1.0, høyde: 1.0, lengde: 1.0, chamferRadius: 0.0) la cubeNode = SCNNode (geometri: cubeGeometry) la planeGeometry = SCNPlane (bredde: 50,0, høyde: 50,0) la planetNode = SCNNode (geometri: planetGeometry) planetNode.eulerAngles = SCNVector3 (x: GLKMathDegreesToRadians (-90), y: 0, z: 0) planetNode.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)
Ved å endre flyknutens Tait-Bryan rotasjoner
eiendom, roterer du flyet bakover 90 grader langs x-aksen. Vi må gjøre dette, fordi flyene er opprettet vertikalt som standard. I SceneKit beregnes rotasjonsvinkler i radianer i stedet for grader, men disse verdiene kan enkelt konverteres ved hjelp av GLKMathDegreesToRadians (_ :)
og GLKMathsRadiansToDegrees (_ :)
funksjoner. GLK står for GLKit, Apples OpenGL-rammeverk.
Deretter legger du til et materiale på terningen og flyet. For dette eksempelet skal du gi terningen og flyet en solid farge, rød og grønn henholdsvis. Legg til følgende linjer i viewDidLoad
metode for å lage disse materialene.
overstyr func viewDidLoad () ... planNode.position = SCNVector3 (x: 0, y: -0,5, z: 0) la redMaterial = SCNMaterial () redMaterial.diffuse.contents = UIColor.redColor () cubeGeometry.materials = [redMaterial] la greenMaterial = SCNMaterial () greenMaterial.diffuse.contents = UIColor.greenColor () planeGeometry.materials = [greenMaterial] la begrensning = SCNLookAtConstraint (mål: cubeNode) ...
For hver SCNMaterial
objekt, tilordner du dets diffuse innhold a UIColor
verdi. Den diffuse egenskapen til et materiale bestemmer hvordan det vises når det er direkte lys. Legg merke til at verdien som er tildelt, ikke må være a UIColor
gjenstand. Det er mange andre akseptable objekttyper som kan tilordnes denne egenskapen, for eksempel UIImage
, CALayer
, og til og med en SpriteKit tekstur (SKTexture
).
Bygg og kjør appen din igjen for ikke bare å se flyet for første gang, men også materialene du opprettet.
Nå er det på tide å legge til noen skygger på scenen din. Av de fire lysene som er tilgjengelige i SceneKit, kan bare spotlys skape skygger. For dette eksempelet skal du omdanne ditt eksisterende omni-lys til et spotlys, rettet mot kassen. Legg til følgende kode i viewDidLoad
metode:
overstyr func viewDidLoad () ... la lys = SCNLight () light.type = SCNLightTypeSpot light.spotInnerAngle = 30.0 light.spotOuterAngle = 80.0 light.castsShadow = sant la lightNode = SCNNode () lightNode.light = light lightNode.position = SCNVector3 x: 1,5, y: 1,5, z: 1,5) ... la begrensning = SCNLookAtConstraint (mål: cubeNode) constraint.gimbalLockEnabled = true cameraNode.constraints = [begrensning] lightNode.constraints = [begrensning] ...
For å lage spotlyset, setter du først lysets type til SCNLightTypeSpot
. Du angir deretter spotlysets indre og ytre vinkel i grader. Standardverdiene er 0 og 45 henholdsvis. Den indre vinkelen bestemmer hvor mye område lyset dekker i direkte lys mens ytre vinkel bestemmer hvor mye område er delvis opplyst. Forskjellen mellom disse vinklene blir klar når du ser den resulterende scenen. Du forklarer da eksplisitt lyset for å kaste skygger og også legge til det samme SCNLookAtConstraint
som du opprettet for kameraet ditt tidligere.
Bygg og kjør appen din for å se den resulterende scenen. Den indre vinkelen du spesifiserte i koden din, vises hvor flyet er en solid grønn, rett under kuben. Ytre vinkelen er vist ved lysets gradient som fades til svart når den beveger seg bort fra lysets mål.
Du ser at du nå har kuben som støtter en skygge riktig. Spotlyset lyser imidlertid bare en del av flyet. Dette skyldes at det ikke er omgivende lys i scenen din.
Et omgivende lys er en lyskilde som belyser alt med en like lysfordeling. Fordi et omgivelseslys lyser opp hele scenen, spiller ingen rolle det, og du kan legge det til en node du vil ha, til og med samme node som kameraet ditt. Bruk følgende kodestykke for å lage et omgivende lys for scenen din.
overstyr func viewDidLoad () ... la kamera = SCNCamera () la kameraNode = SCNNode () kameraNode.camera = kamera kameraNode.position = SCNVector3 (x: -3,0, y: 3,0, z: 3,0) la ambientLight = SCNLight () ambientLight .type = SCNLightTypeAmbient ambientLight.color = UIColor (rød: 0.2, grønn: 0.2, blå: 0.2, alfa: 1.0) cameraNode.light = ambientLight ...
Kodestykket oppretter en SCNLight
, akkurat som du gjorde før. Hovedforskjellen er lysets type
eiendom, som er satt til SCNLightTypeAmbient
. Du stiller også fargen til mørkegrå, slik at den ikke overstyrer scenen din. Standardfarge for lys er ren hvit (RGB-verdi på 1, 1, 1) og med denne fargen på et omgivende lys får hele scenen til å bli fullt opplyst som vist på skjermbildet under.
Bygg og kjør appen din en gang for å se det endelige resultatet.
Hvis du har gjort det til slutten av denne opplæringen, bør du nå være komfortabel med følgende emner:
SCNView
med en SCNScene
I neste veiledning i denne serien lærer du om noen mer avanserte konsepter i SceneKit-rammen, inkludert animasjon, brukerinteraksjon, partikkelsystemer og simulerende fysikk.