Demo ARKit: tworzenie filmów w rozszerzonej rzeczywistości

Opublikowany: 2022-03-11

AR i VR stają się głównym nurtem, a wszystkie czołowe duże firmy high-tech podążają za nimi: Apple ma ARKit, Google ma ARCore, a Microsoft ma własne HoloLens (i oczywiście jest też Unity). A ponieważ kilka aplikacji cieszy się dużym zainteresowaniem opinii publicznej, tworzenie aplikacji rzeczywistości rozszerzonej staje się bardzo pożądaną umiejętnością dla programistów mobilnych.

W tym artykule chciałbym zademonstrować prostą, ale znaczącą, małą aplikację, która będzie miała więcej niż tylko obracający się sześcian. Kto i tak potrzebuje obrotowych kostek? Zróbmy Matrix.

Wprowadzenie do ARKit

ARKit to platforma Apple do tworzenia aplikacji AR na urządzenia z systemem iOS. Można z nim korzystać z kilku rendererów: SpriteKit dla obiektów 2D, SceneKit dla 3D i Metal, jeśli chcemy zaimplementować niestandardowy renderer.

W tym demo użyjemy SceneKit do renderowania i umieszczania w pełni renderowanych obiektów 3D (noże).

obraz: rozróżnienie między rendererami

Od ARKit v2, ARKit obsługuje pięć typów konfiguracji:

AROrientationTrackingConfiguration — gdy chcesz śledzić tylko orientację urządzenia (np. w przypadku aplikacji konstelacji gwiazd). W tej konfiguracji ruchy fizyczne, takie jak boczny krok, nie są śledzone i nie wpływają na położenie ani kierunek obiektów na scenie.

ARWorldTrackingConfiguration – jest to prawdopodobnie najczęściej używana konfiguracja AR, ponieważ obsługuje to, co większość ludzi uważa za rozszerzoną rzeczywistość. Przykłady obejmują aplikacje do polowania na wirtualne zwierzaki lub pokemony.

ARFaceTrackingConfiguration — ta konfiguracja jest obecnie obsługiwana tylko przez iPhone X, ponieważ wymaga aparatu TrueDepth (takiego jak Face ID). Ta konfiguracja śledzi cechy twarzy i ich względne przesunięcie w stosunku do neutralnego wyrazu twarzy (np. aplikacja, w której użytkownicy mogą wypróbować modne okulary przeciwsłoneczne, zanim je zamówią).

ARImageTrackingConfiguration – Jeśli masz zestaw znaczników i chcesz pokazać zwierzęta wyskakujące ze znacznika, ta konfiguracja jest właśnie dla Ciebie. Nie muszą to być znaczniki przypominające karty, ale dowolny obraz 2D. Mógłbyś skierować swój aparat na Mona Lisę, a ona odwróciłaby głowę i coś ci powiedziała. Wadą jest to, że musisz z góry powiedzieć, jaki jest fizyczny rozmiar znacznika obrazu.

ARObjectScanningConfiguration — ta konfiguracja jest wersją 3D ARImageTrackingConfiguration.

W tym demo będziemy dodawać noże i pociski do sceny i chcielibyśmy mieć sześć stopni swobody, więc odpowiednim narzędziem jest ARWorldTrackingConfiguration.

Koncepcja aplikacji

Każdy, kto widział Matrix, może sobie przypomnieć, jak Neo (Keanu Reeves) unikał kul i zatrzymywał je w powietrzu. Nasza aplikacja pomoże nam odtworzyć tę scenę z kamery na żywo. W ten sposób możemy tworzyć niestandardowe filmy demonstrujące moce Neo.

Nasza aplikacja będzie zawierała modele 3D pocisków i noży. Od użytkownika zależy, ile pocisków lub noży chce umieścić w swoim filmie. Jeśli chcesz poświęcić trochę czasu i dodać inne modele, kod aplikacji jest typu open source i jest dostępny na GitHub (https://github.com/altaibayar/toptal_ar_video_maker). Chociaż nie jest to pełny samouczek AR, wersja demonstracyjna i źródło powinny być cennym źródłem, jeśli próbujesz zająć się tworzeniem aplikacji AR na iOS.

Zamierzony scenariusz przypadku użycia jest następujący:

  1. mieć przyjaciela przebranego za Neo (niekonieczne do działania aplikacji, ale równie dobrze może wyglądać dobrze, gdy to robimy).
  2. Poproś „Neo”, aby stanął około 10 metrów od ciebie.
  3. Uruchom aplikację i zeskanuj płaszczyznę uziemienia.
  4. Dodaj kule i noże lecące w „Neo”.
  5. Przytrzymaj przycisk nagrywania, aby nagrać wideo, podczas gdy „Neo” wykonuje fajne ruchy, unikając lub zatrzymując pociski
  6. zwolnij przycisk nagrywania i zapisz wideo w swojej bibliotece.

Budowanie aplikacji

Jak wspomniano wcześniej, chcemy mieć możliwość swobodnego poruszania się podczas nagrywania wszystkich 360 stopni sceny i odpowiedniego śledzenia ruchu kamery przez pociski i noże.

Do celów demonstracyjnych będziemy mieli tylko dwa rodzaje wirtualnych obiektów: noże i pociski do strzelby.

Noże to szczegółowe przedmioty i będę używał darmowego modelu z https://poly.google.com/view/3TnnfzKfHrq (Dzięki Andrew).

Jednak pociski do strzelb są prostymi kulistymi obiektami i możemy je po prostu zakodować. Dla urozmaicenia zrobimy je metaliczne i rozpalone do czerwoności. Ponieważ emulujemy strzelbę, wygenerujemy je również jako zgrupowane klastry. Aby grupowanie miało sens bez większych kłopotów, możemy użyć generatora liczb losowych Gaussa z GamplayKit.

GameplayKit to przydatne narzędzie, które przydaje się, gdy potrzebujesz losowego generowania szumów, automatu stanu, sztucznej inteligencji lub podejmowania decyzji opartych na prawdopodobieństwie.

 override init() { super.init(); // generate 50 gaussian distributed position around [0, 0, 0] let positions = Randomness.gaussian(center: SCNVector3Zero, count: 50); for pos in positions { let node = SCNNode(geometry: sphereGeometry()); node.position = pos; self.addChildNode(node); } } private func sphereGeometry() -> SCNGeometry { // radius of one projectile sphere is 5mm/0.2inch let sphere = SCNSphere(radius: 0.005); // sphere is reddish sphere.firstMaterial?.diffuse.contents = UIColor.red; // reflection on light is gray/silver sphere.firstMaterial?.reflective.contents = UIColor.gray; // metalness is 0.3 sphere.firstMaterial?.metalness.contents = 0.3; // shading should be realistic sphere.firstMaterial?.lightingModel = .physicallyBased; return sphere; }

Podobną logikę losowego przesunięcia można zastosować dla noży, ale ponieważ nie zachowują się one jak klastry, można zastosować prosty losowy rozkład.

Architektura aplikacji

Zagłębienie się w dyskusje na temat tego, który paradygmat architektury jest najlepszy, wykracza poza zakres tego demo. Istnieje wiele artykułów, które zagłębiają się w ten temat.

Zamiast tego przedstawię strukturę projektu jako wskazówkę, jak znaleźć drogę do połączonego projektu GitHub: jakie są główne komponenty, jak są połączone i dlaczego zostały wybrane.

Aplikacja ma tylko trzy ekrany:

PermissionViewController – Ekran, na którym prosimy użytkownika o przyznanie aplikacji dostępu do wymaganych funkcji mobilnych.

  • Aparat – oczywiście
  • Galeria – Aby zapisać nagrane wideo i wejście mikrofonowe
  • Mikrofon – Uprawnienie jest wymagane przez bibliotekę, której używam do tworzenia wideo (domyślnie dźwięk z mikrofonu byłby używany jako źródło ścieżki audio).

ExportViewController — ten ekran pokazuje nagrane wideo i oferuje opcje udostępniania lub zapisywania wideo.

MainViewController — Cała magia dzieje się tutaj.

Z mojego doświadczenia najlepiej jest otoczyć wszystkie niezbędne klasy ARKit, takie jak ARSession, ARConfiguration i wszystkie unikalne typy SCNNode. W ten sposób kod nie wymaga wyjaśnień.

ARSession jest dziedziczony w ToptalARSession, a nowa klasa sesji ma tylko trzy metody: konstruktor klasy, w którym konfigurujemy wszystko, co jest wymagane, oraz metody resetTracking i pauseTracking.

Aplikacja rozpoznaje cztery unikalne typy SCNNodes:

  • KnifeNode — reprezentuje obiekt 3D noża i automatycznie ładuje nóż 3D jako jego geometrię.
  • BulletsNode – Ten węzeł reprezentuje zestaw pocisków do strzelby. Losowy szum Gaussa, kolory i tryb oświetlenia fizycznego są konfigurowane automatycznie.

    W klasach korzystających z KnifeNode lub BulletsNode nie jest wymagana żadna specjalna ani dodatkowa praca i mogą one być używane jako szablony do dostosowywania aplikacji do dodawania większej liczby rodzajów obiektów 3D.

  • ReticleNode – Zawija model 3D, który pojawia się w scenie nad podłogą, aby pokazać, gdzie zostaną dodane noże lub pociski.
  • DirectionalLightNode — jest to węzeł reprezentujący pionowe światło skierowane w dół.

Referencje i kredyty

Model noża: https://poly.google.com/view/3TnnfzKfHrq

Nagranie z SCNScene: https://github.com/svtek/SceneKitVideoRecorder

Ikony przycisków, aplikacja demonstracyjna ARKit: https://developer.apple.com/documentation/arkit/handling_3d_interaction_and_ui_controls_in_augmented_reality