Zengin bir deneyim yaşatan artırılmış gerçeklik, günümüzün en popüler konusu. Metaverse ile daha da ilginç hale gelen bu konu eğitimden sağlığa birçok alanda kullanılıyor. Apple tarafında ise bu uygulamalar ARKit aracılığıyla oluşturuluyor. Bu framework ile kullandığınız 2 veya 3 boyutlu cisimler gerçek dünyaya entegre oluyor. Bu sayede hem sanal hem fiziksel ortam birleşiyor. Peki ama bu nasıl yapılıyor? Gelin buna bir uygulamayla yakından bakalım.
Projeyi Oluşturalım
Bunun için önce Xcode‘u açalım. Ardından “Yeni bir Xcode Projesi Oluştur” seçeneğine tıklayalım. Bir sonraki adımda “Augmented Reality App” seçtiğimizden emin olalım.
Ardından açılan ekranda projemize bir isim verelim. İsim verdikten sonra “İçerik Teknolojisi (Content Technology)” kısmının “SceneKit” seçili olduğuna dikkat edelim. Daha sonra “İleri” butonuna tıklayalım ve projemiz artık hazır.
Uygulama için Gereklilikler
Öncelikle ARKit ile ilgili yapacağımız bütün testleri gerçek bir iPhone üzerinde yapmak zorundayız. Cihaz kamerasına erişeceğimiz için maalesef simülatörde yapamıyoruz. Bunun dışında iPhone 6S ve üzeri cihazlar bu uygulamalar için destekleniyor. Bunun nedeni ise yapılan işlemler için belirli bir işlem gücü ve çip jenerasyonu gerekliliği. Eğer iPhone 6S ve üzeri bir iPhone’a sahipseniz,bu adımda telefonunuzu MacBook cihazınıza bağlayabilirsiniz.
Uygulama için Materyal Edinmek
Yapacağımız uygulama bir güneş sistemi simülasyonu olacak. Bunun için birkaç küre oluşturup bu küreleri belirli “Texture” yapıları yani görseller ile kaplayacağız. Bunun için “Solar System Scope” sitesinden faydalanacağız. Sitede de göreceğiniz gibi birçok “Texture” mevcut. Bizim uygulamamız için aldıklarımız ise şu şekilde;
Verdiğimiz linklere tıkladıkça bulabileceğiniz görselleri sıra sıra bilgisayarınıza kaydedin. Ardından sıra geldi bunu Xcode içerisine aktarmaya. Bu işlemde aslında oldukça kolay. İnen görselleri “Art” klasörü altına sürüklemek yeterli olacaktır.
Küre Oluşturmak
Yukarıda da bahsettiğimiz gibi uygulamamız bir güneş sistemi uygulaması olacak. Bu yüzden öncelikle ViewDidLoad altındaki şu satırları temizleyelim.
sceneView.showsStatistics = true
let scene = SCNScene(named: "art.scnassets/ship.scn")!
sceneView.scene = scene
Bildiğiniz gibi 6 adet Texture kullancağız. Fakat bunun öncesinde bir küre nasıl oluşturuluyor ona bakalım. Bir önceki yazımızda SpriteKit ile nasıl oyun oluşturulur ondan bahsetmiştik. Orada da değindiğimiz “node” yapısı aslında burada da devam ediyor. Yani biz oluşturacağımız nesnenin fiziksel görünümünü belirleyip ona bir de Texture vereceğiz. Ardından “node” ile ekranda göstereceğiz. Küre oluşturmak için SCNSphere sınıfından yararlanıyoruz. Bu bizden bir radius yani yarıçap değeri istiyor. Burada yazılan değerler metre cinsinden olacağı için dikkat etmekte fayda var. Biz burada 0.1 değerini kullanacağız.
let mysphere = SCNSphere(radius: 0.1)
Ardından sıra geldi oluşturduğumuz kürenin içinde neler olacağını belirtmeye. Bunun için materials metodunu kullanacağız. Bu oluşturulan geometrinin ortaya çıkması için bizden SCNMaterial dizisi istiyor. Bu yüzden gelin bir material oluşturup metoda bir dizi içerisinde verelim. Material olarak bir Texture vereceğiz. Bunun için oluşturduğumuz material değişkeninin diffuse metodu ile içeriğinde değişiklik yapacağımızı söylüyoruz. Ardından contents metodunu kullanarak Texture veriyoruz. Burada Texture verirken önce klasörü göstermeyi unutmamalıyız.
let mysphere = SCNSphere(radius: 0.1)
let sphereMaterial = SCNMaterial()
sphereMaterial.diffuse.contents = UIImage(named: "art.scnassets/world.jpeg")
mysphere.materials = [sphereMaterial]
Sıra geldi node oluşturmaya. Bunun için SCNNode() sınıfından yararlanacağız. Oluşturduktan sonra bir position değeri vereceğiz. Fakat bu değeri SCNVector3 olacak şekilde vereceğiz. Bizden istediği x, y ve z değerlerini verdikten sonra sıra geldi oluşturduğumuz küreyi node’a vermeye. Bunun için geometry metodunu kullanıyoruz. Bu sayede küremiz node olarak tanımlanmış oldu. Son adım ise küreyi ekranda göstermek. Bunun için sceneView.scene.rootNode.addChildNode diyerek ekrana ekliyoruz.
let mysphere = SCNSphere(radius: 0.1)
let sphereMaterial = SCNMaterial()
sphereMaterial.diffuse.contents = UIImage(named: "art.scnassets/world")
mysphere.materials = [sphereMaterial]
let sphereNode = SCNNode()
sphereNode.position = SCNVector3(0, 0.1, -0.5)
sphereNode.geometry = mysphere
sceneView.scene.rootNode.addChildNode(sphereNode)
Güneş Sistemini Oluşturmak
Küre oluşturmayı öğrendik. Artık sıra geldi asıl yapmak istediğimiz uygulamaya. Bunun için 6 adet küre oluşturmalıyız. Fakat bu işlem uzayacağı için bunu bir fonksiyon içerisinde yapmak daha mantıklı olacaktır. Bu yüzden yarıçap, içerik ve vektör bilgilerini kullanıcıdan alacağımız bir fonksiyon yazalım.
func createSphere (radius : CGFloat, content : String, vector : SCNVector3) {
let mysphere = SCNSphere(radius: radius)
let sphereMaterial = SCNMaterial()
sphereMaterial.diffuse.contents = UIImage(named: "art.scnassets/\(content)")
mysphere.materials = [sphereMaterial]
let sphereNode = SCNNode()
sphereNode.position = vector
sphereNode.geometry = mysphere
sceneView.scene.rootNode.addChildNode(sphereNode)
}
Şimdi ise ViewDidLoad altında gezegenlerimizi oluşturalım.
createSphere(radius: 0.1, content: "sun.jpeg", vector: SCNVector3(0, 0.2, -0.5))
createSphere(radius: 0.1, content: "world.jpeg", vector: SCNVector3(-0.5, 0.2, -0.5))
createSphere(radius: 0.1, content: "moon.jpeg", vector: SCNVector3(-1, 0.2, -0.5))
createSphere(radius: 0.1, content: "jupiter.jpeg", vector: SCNVector3(-1.5, 0.2, -0.5))
createSphere(radius: 0.1, content: "mars.jpeg", vector: SCNVector3(-2, 0.2, -0.5))
createSphere(radius: 0.1, content: "neptune.jpeg", vector: SCNVector3(-2.5, 0.2, -0.5))
Son olarak eğer çıkan kürelerin ışıklandırmasının biraz daha iyi olmasına ihtiyacınız varsa sceneView’un automaticallyUpdatesLighting metodunu true olarak işaretleyebilirsiniz. Bu sayede ışıklar ve gölgeler biraz daha optimize olacaktır.
sceneView.automaticallyUpdatesLighting = true
Final
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
override func viewDidLoad() {
super.viewDidLoad()
sceneView.delegate = self
createSphere(radius: 0.1, content: "sun.jpeg", vector: SCNVector3(0, 0.2, -0.5))
createSphere(radius: 0.1, content: "world.jpeg", vector: SCNVector3(-0.5, 0.2, -0.5))
createSphere(radius: 0.1, content: "moon.jpeg", vector: SCNVector3(-1, 0.2, -0.5))
createSphere(radius: 0.1, content: "jupiter.jpeg", vector: SCNVector3(-1.5, 0.2, -0.5))
createSphere(radius: 0.1, content: "mars.jpeg", vector: SCNVector3(-2, 0.2, -0.5))
createSphere(radius: 0.1, content: "neptune.jpeg", vector: SCNVector3(-2.5, 0.2, -0.5))
sceneView.automaticallyUpdatesLighting = true
}
func createSphere (radius : CGFloat, content : String, vector : SCNVector3) {
let mysphere = SCNSphere(radius: radius)
let sphereMaterial = SCNMaterial()
sphereMaterial.diffuse.contents = UIImage(named: "art.scnassets/\(content)")
mysphere.materials = [sphereMaterial]
let sphereNode = SCNNode()
sphereNode.position = vector
sphereNode.geometry = mysphere
sceneView.scene.rootNode.addChildNode(sphereNode)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let configuration = ARWorldTrackingConfiguration()
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
sceneView.session.pause()
}
func session(_ session: ARSession, didFailWithError error: Error) {}
func sessionWasInterrupted(_ session: ARSession) {}
func sessionInterruptionEnded(_ session: ARSession) {}
}
Göründüğü gibi oldukça kolay kullanılan ARKit ile sizlerde gittikçe önem kazanan artırılmış gerçeklik alanına yönelik yep yeni uygulamalar geliştirebilir, bunu insanlarla paylaşabilirsiniz. Eğer ARKit hakkında daha fazla bilgiye ulaşmak isterseniz Apple tarafından hazırlanan dökümantasyonu inceleyebilirsiniz.