AR VR in der Grundschule

Aus Wikiversity

Die folgende Lernressource befasst sich mit der Entwicklung von VR/AR-Anwendungen und deren möglichen Integration in Lernumgebungen[1]. Der wesentliche Teil der Lernressource ist ein Einführungstutorial für die 3D-Modellierung mit A-Frame. Die Standardkonzepte wurden in einfacher Sprache erläutert und mit Minimalbeispielen belegt. Als nicht-triviales Beispiel wurde die Sonne-Erde-Mond-Bewegung detailliert besprochen und implementiert.

Lernziel[Bearbeiten]

Rotierendes Planetensystem auf Hiro-Marker

Nach Bearbeitung dieser Lernressource werden Sie in der Lage sein, selbst 3D-Objekt auf Markern zu konstruieren und diese digitale Objekte auch auf Markern zu animieren. Die Abbildung zeigt das Ergebnis der Lerneinheit. Die Lernumgebung selbst basiert auf dem Open Community Approach, bei dem Open-Source-Software und Open Educational Resources (OER) den freien Zugang zu den Bildungsressourcen ermöglichen und diese unter einer freien Licence für Lernpersonen und für Lernende anpassbar sind und wieder frei zur Verfügung dem Bildungssystem zur Verfügung gestellt werden können.

Vorbereitung[Bearbeiten]

(Seite mit Markern) Drucken Sie dazu eine Seite mit Markern aus und zerschneiden Sie die Marker so, dass noch ein weißen Rand bleibt. Kleben Sie dann die Marker so auf eine Pappe, dass der Hiro-Marker auf der einen Seite und der Kanji-Marker auf der anderen Seite zu sehen ist. Diese Pappe ist dann für beliebige 3D-Modelle auf einem Hiro- oder Kanji-Marker verwendbar, da das Modell nicht im dem Marker kodiert ist, sondern nur die Erkennung der Position der 3D-Modells im Kamerabild verwendet wird. Kleben Sie die quadratischen Marker so auf eine rechteckige Pappe, deren Größe ausreichend ist, um die Pappe noch mit der Hand festzuhalten, ohne den Marker selbst mit der Hand zu verdecken.

Endprodukte[Bearbeiten]

Hiro-Marker

Wenn Sie einen ersten Eindruck von dem animierten Endprodukt haben möchten, dann wäre es sinnvoll zunächst einen Hiro-Marker auszudrucken und auf Pappe zu kleben.

Erste Schritte[Bearbeiten]

Formal wird A-Frame als Framework zur Darstellung von 3D-Objekten und VR-Inhalten im Web-Browser bezeichnet. A-Frame ist auf WebVR und WebGL Javascript Bibliotheken aufgebaut, jedoch basiert die Interaktion auf HTML-ähnlicher Sprache. Damit ist gemeint, dass A-Frame als eine Erweiterung von HTML gesehen werden kann, die eine zusätzliche Funktionalität besitzt. Sie kann 3D-Objekte erschaffen und sie im Browser erscheinen lassen. Die A-Frame-Anwendungen sind also im Grunde nichts anderes als Webseiten, auf die man per Web-Browser zugreifen kann. Der Inhalt kann auf allen möglichen Geräten per Web-Browser abgerufen werden, z. B. auf Handys, Tablets und Laptops. Zudem unterstützt A-Frame auch viele VR-Brillen wie HTC Vive, Oculus Rift, Windows Mixed Reality. Im Gegensatz zu WebVR- und WebGL-Anwendungen benötigt man für A-Frame keine Vorkenntnisse von Javascript. Daher ist A-Frame eine willkommene Lösung für Menschen, die sich nicht mit Programmierung auskennen. Das Framework ist ein Open-Source-Projekt und ist daher nicht kostenpflichtig. Beim Verfassen dieser Lernressource war die Version 1.1.0 die Aktuellste. Das muss beachten werden, da A-Frame nicht durchgängig abwärtskompatibel ist und daher einige Befehle aus diversen Tutorials nicht mehr benutzt werden können.

Es gibt verschiedene Möglichkeiten, mit A-Frame zu arbeiten. Der einfachste und schnellste Weg ist Glitch. Glitch bietet eine Online-Plattform mit integriertem Code-Editor und vorinstallierten Paketen für die sofortige Entwicklung und das Hosting von A-Frame-basierten Webseiten. Mit Hosting ist das Platzieren der Webseiten (A-Frame-Anwendungen) auf einem externen Server gemeint. Ebenso liefert Glitch eine Menge Beispiele (Projekte) mit einem offenen und modifizierbaren Quellcode, die man sofort abrufen kann. Hiermit bietet Glitch einen sehr einfachen Start in die Entwicklung mit A-Frame.

Elementare Konzepte der A-Frame Modellierung[Bearbeiten]

A-Frame basiert auf HTML-Sprache, daher sollte die Datei mit <!DOCTYPE html> Deklaration beginnen. In die typische Struktur einer HTML-Datei gehören <head>...</head> und <body>...</body>-Sektionen, auch Tag genannt. Die erste dient dabei als Container der Konfigurationsdaten; da steht beispielsweise der Titel, Style usw. Ebenso werden dort die dazu benötigten Skripte, unter anderem A-Frame, mithilfe von <script>...</script>-Tag angeknüpft. Die zweite Sektion ist ein Container der Daten, die später im Browser angezeigt werden. Der A-Frame-Inhalt wird innerhalb des <a-scene>...</a-scene>-Tags eingeführt. Das Beispielprogramm 1 zeigt die typische Struktur einer A-Frame-Datei. In dem Beispiel wird ein Würfel mithilfe eines <a-box>...</a-box>-Befehls gezeichnet.

Beispielprogramm 1
<!DOCTYPE html>
<html>
  <head>
    <script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
  </head>
  <body>
    <a-scene>
      <a-box> </a-box>
    </a-scene>
  </body>
</html>

Das Gute an A-Frame ist, dass Befehle wie <a-box> vorhanden sind, womit man ganz einfach verschiedene geometrische Figuren darstellen kann, ohne Programmierkenntnisse von Javascript oder Ähnlichem zu benötigen. Im Späteren wird der Code nicht komplett angegeben, sondern nur die A-Frame-relevanten Abschnitte im <a-scene>...</a-scene> – um Platz zu sparen und den Fokus des Lesers auf das Wesentliche lenken zu können. Die nächsten Abschnitte behandeln die Modellierung von geometrischen Figuren, dabei wird auf Texturen, Animation und Hintergründe eingegangen.

Einfache geometrische Figuren[Bearbeiten]

In A-Frame gibt es grundlegende Figuren, die man für die Ausarbeitung ganz einfach benutzen kann. Man unterscheidet zwischen 13 vorprogrammierten 2D- und 3D-Figuren. Bei 3D-Objekten hat man die Wahl zwischen Würfeln, Kegeln, Zylindern, Dodekaedern, Oktaedern, Tetraedern, Kugeln, Tori und Torusknoten. Für die 2D-Geometrie sind folgende Objekte vorprogrammiert: Ebenen, Kreise, Ringe und Dreiecke. Jedes dieser geometrischen Objekte besitzt interne Parameter, die die Geometrie des Objektes definieren, z. B. ist eine Kugel festgelegt durch den Radius und beim Zylinder wird zusätzlich die Höhe benötigt. Zusätzlich haben alle geometrischen Objekte globale geometrieunabhängige Eigenschaften wie Position, Rotation usw.

A-Frame benutzt das typische kartesische Koordinatensystem. Die Kamera ist positioniert in mit Blick in die negative -Richtung. Die Größen sind alle in Meter angegeben, sodass die Höhe der Kamera beträgt und somit ungefähr auf Augenhöhe eines Menschen liegen soll. Beispielprogramm 2 zeigt eine grüne Kugel und einen roten Würfel, die in und positioniert sind. Die -Koordinate der Objekte ist gleich der Höhe der Kamera, und entspricht Distanz von der Kamera in -Richtung. Wie man aus dem Code erkennt, wurde eine Kugel vom Radius erstellt und bei dem Würfel wurden die Dimensionen nicht angegeben, daher wurde ein Würfel mit Standardgrößen erzeugt.

A-Frame bietet eine Menge der Transformationen wie z. B. Rotation oder Skalierung. Wie man im Beispielprogramm 3 sieht, wurde die Kugel durch leichte Modifikation in die -Richtung gestreckt und der Würfel um um die eigene -Achse gedreht. Hierbei ist es wichtig zu bemerken, dass bei einer Rotation die eigene lokale -Achse durch den Mittelpunkt des Quadrats und nicht das globale Koordinatensystem benutzt wurde.

Beispielprogramm 2
<a-scene>
  <a-box position = "1 1.6 -2"  
         color="red"> 
  </a-box>
  <a-sphere radius="0.5"
            position="-1 1.6 -2" 
            color="green"> 
  </a-sphere>
</a-scene>

Grüne Kugel und roter Würfel

Beispielprogramm 3
<a-scene>
  <a-box position="1 1.6 -2"
         color="red" 
         rotation="0 45 0"> 
  </a-box>
  <a-sphere radius="0.5" 
            position="-1 1.6 -2" 
            color="green" 
            scale="1 2 1"> 
  </a-sphere>
</a-scene>

Skalierte Kugel und gedrehter Würfel 

Das ist einer der wesentlichen Punkte in der Entwicklung mit A-Frame – man muss immer den Überblick behalten, welche Figuren bezüglich welcher Koordinatensysteme definiert sind. Um dies zu verdeutlichen, wird das Beispielprogramm 4 betrachtet. Dieses produziert beim ersten Hinschauen genau dasselbe Bild wie Beispielprogramm 2, allerdings ist hierbei die Kugel innerhalb des Würfels definiert, d. h. innerhalb des <a-box>...</a-box>-Tags. Somit ist die Kugel als Teil der Würfelgeometrie zu verstehen. Dieses Phänomen ist als Vererbung bekannt. Die Kugel vererbt unter anderem das Koordinatensystem des Würfels: Der -Punkt der Kugel ist mit dem Zentrum des Würfels bestimmt. Wie in Zeile 5 zu sehen ist, muss die Kugel um in die -Richtung verschoben werden, damit man dieselbe Geometrie bekommt, wie im Beispielprogramm 2. Die Kugel ist ein Teil der Würfelgeometrie, die Drehung des Würfels impliziert die Drehung der Kugel um die -Achse des Würfels, wie im Beispielprogramm 5 zu sehen ist.

Beispielprogramm 4
<a-scene>
  <a-box position="1 1.6 -2" 
         color="red">
         <a-sphere radius="0.5" 
                   position="-2 0 0" 
                   color="green"> 
         </a-sphere>
 </a-box>   
</a-scene>

Kugel ist ein Teil des Würfelgeometrie 


Beispielprogramm 5
<a-scene>
  <a-box position="1 1.6 -2"
         color="red"  
         rotation="0 -45 0">
         <a-sphere radius="0.5" 
                   position="-2 0 0" 
                   color="green"> 
         </a-sphere>
  </a-box>   
</a-scene>

Rotation der Kugel als Teil der Würfelgeometrie

Hiermit wird deutlich, wie man ein Objekt an die Achse eines anderen Objektes binden kann. Dies ist besonders wichtig, wenn man die Bewegungen des einen Objektes in Bezug auf das andere implementieren möchte. Allerdings ist noch zu klären, wie man ein Objekt bezüglich der Achse des anderen rotieren lässt, ohne dass das Andere selbst rotiert. Eine Möglichkeit, so etwas zu implementieren, ist die Zuhilfenahme von <a-entity>. Die Idee dahinter besteht darin, einen Platzhalter für ein Objekt zu kreieren, und analog zu Beispielprogramm 5 ein anderes Objekt um den Platzhalter rotieren zu lassen. Das statische Objekt wird einfach über dem Platzhalter positioniert. Beispielprogramm 6 zeigt eine Kugel, die bezüglich der -Achse des Würfels gedreht ist, der Würfel jedoch nicht.

Beispielprogramm 6
<a-scene>
  <a-entity position="1 1.6 -2" 
            rotation="0 -45 0">
            <a-sphere radius="0.5" 
                      position="-2 0 0" 
                      color="green"> 
            </a-sphere>
  </a-entity>   
  <a-box position="1 1.6 -2" 
         color="red"> 
  </a-box>   
</a-scene>

Benutzen des Entity-Konzeptes 

So ein <a-entity>-Platzhalter kann ebenfalls nützlich sein beim Importieren der 3D-Objekte. Das Beispielprogramm 7 illustriert, wie man ein Objekt im gltf-Format in A-Frame importieren und richtig positionieren kann. Das Baum-Modell wurde von Don McCurdy heruntergeladen.

Beispielprogramm 7
<a-scene>
  <a-entity position="0 1.6 -5"
            gltf-model="tree.gltf">
  </a-entity>
</a-scene>

Import der gltf-Objekte 

Der <a-entity>...</a-entity>-Tag ist ein Teil des sogenannten Entity-Component-System-Konzeptes (ECS). Das Konzept wird größtenteils für die Entwicklung von Computerspielen verwendet und trägt dieselbe Philosophie wie die objektorientierte Programmierung: Vererbung und Hierarchie. Es hat sich herausgestellt, dass die Aufbauart des Codes in vielen Aspekten sehr hilfreich sein kann. Wie man bereits gesehen hat, ist einer der wichtigsten Aspekte, dass die Objekte innerhalb der Entity ein lokales Koordinatensystem bekommen, und daher der Code unabhängig vom globalem Koordinatensystem ist. Wenn man an großen Projekten arbeitet, möchte man nicht alle geometrischen Objekte notwendigerweise im selben Ort bezüglich desselben Koordinatensystems deklarieren, sondern man möchte die Szene in mehrere solcher Entities teilen und getrennt bearbeiten.

Texturen[Bearbeiten]

Der Zweck der 3D-Modellierung ist oft die Visualisierung der realistischen 3D-Objekte. Um diese so realistisch wie möglich gestalten zu können, werden gerne Texturen verwendet. Unter einer Textur versteht man ein Bild, das auf die Oberfläche der jeweiligen Figur projiziert wird, um physischen Stoff oder Material zu reproduzieren. Typische Beispiele sind Holz, Metall, Gestein, usw. Im Beispielprogramm 8 sieht man einen Würfel, der aussieht, als wäre er aus Backsteinen. Das Einfügen von Texturen wird mithilfe einer src-Option ausgeführt, wie es in Zeile 5 zu sehen ist.

Beispielprogramm 8
<a-scene>
  <a-box position="0 1.6 -1.3" 
         rotation="0 30 0"
         color="white"
         src="bricks.jpg">
  </a-box>    
</a-scene>

Backsteintextur auf einem Würfel

Beispielprogramm 9
<a-scene>
  <a-box position="0 1.6 -1.3" 
         rotation="0 30 0"
         color="white"
         src="bricks.jpg"
         normal-map="bricks_nm.jpg">
  </a-box>    
</a-scene>

Backsteintextur mit "normal map" auf einem Würfel

Allerdings sieht die Backsteinoberfläche, wie man auf dem Bild sehen kann, ziemlich flach und somit künstlich aus. Um den visuellen 3D-Effekt zu erzielen, benutzt man sogenannte ”normal maps”. Mit ”normal mapping” bezeichnet man den Trick, der die Reflexion des Lichtes modifiziert, und somit der Oberfläche einen erhabenen Eindruck verpasst. Das Benutzen von normal maps ist im Beispielprogramm 9 dargestellt; dies passiert mit der normal-map-Option, siehe Zeile 6. Man kann beobachten, dass die Oberfläche viel realistischer aussieht. Die dazu benötigte Textur und normal map wurde von [1] heruntergeladen.

Es gibt viele weitere Optionen, die visuelle Erscheinung der Materialien zu verbessern. Dazu gibt es gute Tutorials in Pasquariello, wie die Dokumentation auf der A-Frame-Webseite [2] . Allerdings muss man noch eine Sache anmerken: Die Textur (das Bild) wird auf die komplette Fläche aufgeklebt und somit muss die Skalierung extra angepasst werden. Wenn der Würfel groß genug ist, sehen die Backsteine ebenfalls gigantisch und unrealistisch aus. Die Skalierung der Textur kann mit repeat implementiert werden, wie es im Beispielprogramm 10 gezeigt wird. Mit zwei Zahlen ist die Skalierung in die - und -Richtungen gemeint. Indem man in die eine Richtung mehr skaliert, können die Backsteine dicker bzw. dünner gemacht werden. In Beispielprogramm 10 wurde eine zweifache Skalierung in beide Richtungen vorgenommen. Hier muss man noch betonen, dass man die dazugehörige normal map entsprechend anpassen muss.

Beispielprogramm 10
<a-scene>
  <a-box position="0 1.6 -1.3" 
         rotation="0 30 0" 
         color="white" 
         src="bricks.jpg" 
         repeat="2 2"
         normal-map="bricks_nm.jpg"
         normal-texture-repeat="2 2">
  </a-box>    
</a-scene>

Skalierung der Texturen

Beispielprogramm 11
<a-scene>
  <a-assets>
    <img id="bricks" src="bricks.jpg">
    <img id="bricks_nm" src="bricks_nm.jpg">
  </a-assets>
  <a-box position="0 1.6 -1.3" 
         rotation="0 30 0"  
         material="color:white;         
                   src:#bricks;
                   repeat:2 2;
                   normal-map:#bricks_nm;    
                   normal-texture-repeat:2 2">
  </a-box>    
</a-scene>

Alternative Schreibweise

Oft werden die ganzen Materialerscheinungsoptionen in material definiert und die Bilder in <a-assets> eingeführt, siehe Beispielprogramm 11. Die Beispielprogramm 10 und Beispielprogramm 11 haben exakt den selben Effekt, allerdings wird beim zweiten mehr Struktur hervorgehoben, was den Code lesbarer macht. Ebenso ist die zweite Version kanonischer, wenn man dieselben Texturen mehrfach verwendet. Insbesondere die Vordefinition der Texturbilder als sogenannte Assets (Verwendete Dateien wie z. B. Bilder, Videos, Musik) sind für das Speichermanagement von Vorteil.

Einfache Dynamik[Bearbeiten]

A-Frame funktioniert nicht nur gut bei der Erstellung der 3D-Objekte, sondern erlaubt auch gewisse Animationen. Die als Standard vorprogrammierten Animationen in A-Frame kann man in zwei Kategorien unterteilen: Bewegung und Erscheinung [3]. A-Frame erlaubt ebenfalls gewisse Interaktionen mit dem Nutzer; z. B. kann die Maus als Auslöser einer oder mehrerer Animationen dienen. Das wird hier aber nicht betrachtet.

Im Folgenden werden die vier Arten der Animation erklärt, die am wichtigsten sind: Rotation, Gradlinige Bewegung, Farb- und Formänderungen. Hierbei ist zu beachten, dass die Notation mit <a-animation>-Tag, wie sie in Pasquariello, benutzt wird, ab Version 0.9.0 nicht mehr möglich ist.

Beispielprogramm 12
<a-scene>
  <a-box color="red"
         position="0 0.6 -3"
         animation="property:rotation;
                    to:0 360 0;
                    easing:linear;
                    loop:true;
                    dur:5000">
  </a-box>    
  <a-sphere color="green"
            radius="0.5"
            position="-1 2.6 -3"
            animation="property:position;
                       to:1 2.6 -3;
                       easing:easeInOutSine;
                       dir:alternate;
                       loop:true;
                       dur:2500">
  </a-sphere>
</a-scene>

Im Beispielprogramm 12 sind zwei Animationsvorgänge dargestellt: Der Würfel rotiert um die eigene -Achse und die Kugel bewegt sich von links nach rechts und zurück. Das Einführen der Animationen ist mit dem Stichwort <animation> umgesetzt, siehe Zeilen 4 und 13. Die Art der Bewegung wird mit <property> definiert; im Beispiel werden die Rotation und geradlinige Bewegungen betrachtet, die mit den Stichworten <rotation> und <position> gekennzeichnet sind. Das Stichwort <to> bezeichnet den Endzustand der Animation; beim Würfel wäre der Endzustand eine Rotation um um die -Achse und bei der Kugel die Koordinate des Endpunktes. Das Stichwort <dur> gibt in Millisekunden an, wie lange die Animation dauern soll. In diesem Fall sind es bei dem Würfel und bei der Kugel. Mit <loop> kann man angeben, wie oft die Animation ablaufen soll. Wenn man den Wert auf <indefinite> setzt, wiederholt sich die Animation unendlich oft. Mit <easing> kann man die Geschwindigkeitsänderung der Simulation kontrollieren, z. B. mit linear bleibt die Geschwindigkeit konstant über den ganzen Simulationsvorgang, und mit <easeInOutSine> ändert sich die Geschwindigkeit sinusförmig, d. h. die Geschwindigkeit am Anfang und zum Schluss ist langsamer als in der Mitte. Die Bewegung der Kugel ist definiert von links nach rechts, d. h. nach einer Iteration springt die Kugel in den Anfangszustand. Damit das nicht passiert und die Kugel sich ”rückgängig” mit der selben Geschwindigkeit zum Anfangszustand bewegt, kann das Stichwort <dir:alternate> verwendet werden. Daher wurde die Simulationszeit der Kugel auf gesetzt, denn sie braucht genau so lange auch zurück. In , in denen der Würfel eine ganze Umdrehung macht, schafft es die Kugel also einmal hin und zurück.

Beispielprogramm 13
<a-scene>
  <a-box color="red"
         position="1 1.6 -2"
         animation="property:scale;
                    to:0.5 1 2;
                    easing:linear;
                    dir:alternate;
                    loop:true;
                    dur:5000">
  </a-box>    
  <a-sphere color="green"
            radius="0.5"
            position="-1 1.6 -2"
            animation="property:components.material.material.color;
                       type:color;
                       to:blue;
                       easing:linear;
                       dir:alternate;
                       loop:true;
                       dur:5000">
  </a-sphere>
</a-scene>

In Beispielprogramm 13 werden zwei Arten von Erscheinungsanimationen dargestellt: Die Änderung der Farbe der Kugel und die Änderung der geometrischen Form des Würfels. Dies funktioniert relativ analog zu Beispielprogramm 12. Die Skalierungsanimation des Würfels wird mit dem Stichwort scale aktiviert. Als Endzustand wurde to:0.5 1 2 gewählt, das heißt, dass der Würfel in die -Richtung halbiert und in die -Richtung verdoppelt wird, die -Dimension bleibt dabei unverändert. Für die Farbänderung muss man <components.material.material.color; setzen. Dabei ist es wichtig, <type:color; dazu zu schreiben, wie es in der Dokumentation steht.

Modellierung der Umgebung[Bearbeiten]

A-Frame ermöglicht es, sehr realistische 3D-Modelle zu konstruieren. Dabei ist es im Kontext von realitätsnahen VR wichtig, den passenden Hintergrund dazu zu erschaffen. Im Folgenden wird die Methode erläutert, wie man den Boden und Himmel typischerweise modelliert, siehe Beispielprogramm 14. Der einfachste Weg der Bodendarstellung ist die Zuhilfenahme einer Ebene. Das Kreieren der Ebene funktioniert mit dem A-Frame-Kommando <a-plane>. Dabei ist zu beachten, dass die Ebene normalerweise in --Richtung erstellt wird. Daher muss man sie rotieren, wie es in Zeile 9 gemacht wird. Die Parameter height und width beschreiben die Größe der Ebene. Um es realistisch darzustellen, kann man eine Textur mit ggf. normal map drauf legen; hier wurde das passende Gras zum Baum gefunden .

Beispielprogramm 14
<a-scene>
  <a-entity position="0 3 -10"
            gltf-model="tree.gltf">
  </a-entity>
  <a-plane src="gras.jpg"
           normal-map="gras_nm.jpg"
           height="100"
           width="100"
           rotation="-90 0 0"
           repeat="100 100"
           normal-textured-repeat="100 100">
  </a-plane>           
  <a-sky src="lake.jpg"
         radius="50"
         position="0 0 0">
  </a-sky> 
</a-scene>

Himmel und Boden

Zur Darstellung des Himmels wird üblicherweise der <a-sky>-Tag verwendet, siehe Zeile 13. Dabei ist es nichts Anderes als eine große Sphäre mit einem Radius, der groß genug ist. In diesem Beispiel wurde eine solche Textur verwendet – in Form eines -Bildes (siehe Aframe Sky).

Augmented Reality with AR.js[Bearbeiten]

Es ist zu hoffen, dass es den Leser bereits davon überzeugte, dass A-Frame ein sehr vielseitiges und dennoch relativ einfach zu handhabendes Instrument ist, um VR-Szenen zu erschaffen. Dabei wurde nur die Spitze des Eisbergs betrachtet. Die Funktionalität von A-Frame bietet noch viel mehr. Insbesondere kann man mit minimalen Modifikationen den AR-Inhalt kreieren. Wie bereits erwähnt wurde, versteht man unter AR die erweiterte Realität, d. h. man erweitert die Realität mit virtuellen Komponenten.

Eine der Möglichkeiten ist das Bild der Kamera als Hintergrund der Szene zu benutzen. Jedoch ist die vorgeschlagene Lösung relativ komplex und für Personen ohne gute Vorkenntnisse in Webprogrammierung nicht gut nachvollziehbar. Ebenso ist das Resultat ziemlich verzerrt, denn Standard-Kameras produzieren ein normales flaches Bild, das auf die Sphäre projiziert wird. Im Beispielprogramm 14 wurde ein spezielles verzerrtes -Bild genau aus dem Grund verwendet.

Eine kanonische Vorgehensweise in der A-Frame-Community ist AR.js-Bibliothek. Diese bietet ein einfaches A-Frame-ähnliches Interface zur Erschaffung von AR-Inhalten und beinhaltet unter anderem auch Marker-Tracking-Features. Die Marker dienen dazu, die Position und Größe des VR-Objektes zu definieren. Der Marker wird erkannt und die Position des VR-Objektes wird an die Position des Markers gebunden; die Bewegungen und Rotationen des Markers werden dann auf das Objekt übertragen. Insbesondere wird der Marker benutzt, um die Transformation in -Richtung zu erkennen - wird der Marker kleiner, entfernt sich das Objekt weiter. Marker dienen also als Anker für das Objekt im 3D-Raum.

Theoretisch kann man 3D-Informationen aus 2D-Bildern ohne Marker rekonstruieren; es gibt ausreichend viele Forschungsmaterialien in dieser Richtung. Ebenso wurden schon markerlose AR im AR.js erzielt Jerome Etienne, jedoch ist diese Technologie noch relativ neu und wird noch nicht offiziell unterstützt. Die Tutorials sind relativ komplex und unverständlich. Aus diesen Gründen wird der Fokus nur auf die markerbasierte Modellierung gelegt.

Integration von AR.js in A-Frame[Bearbeiten]

Das Benutzen von AR.js in A-Frame ist relativ einfach, dazu gibt es mehrere Tutorials, z. B. Jerome Etienne ,Documentation. Anhand von Etienne, wurde ein Minimalbeispiel im Beispielprogramm 15 zusammengestellt. Das Beispiel zeichnet einen Würfel, sobald man den "Hiro"-Marker in die Kamera zeigt, siehe Abbildung Beispielprogramm 15.

Es ist zu erkennen, dass der Unterschied von AR (Beispielprogramm 15) zu VR (Beispielprogramm 1) ein 4-Zeilen-Code ist. Erstens wird hier die AR.js-Bibliothek in Zeile 5 angeknüpft, und mit Option <embedded arjs> in Zeile 9 eingeschaltet. Zweitens muss man der Kamera den Befehl geben, nach einem <"hiro"> Marker zu suchen; dies passiert in Zeile 11. Ebenso soll man die Kamera in Position stellen, damit es so aussieht, als wäre das Objekt über dem Marker, wie es in Zeile 13 passiert. Hiro wird klassischerweise als Beispiel benutzt, allerdings kann man beliebige Muster zu Markern machen. Dies wird genauer im nächsten Unterkapitel erläutert.

Beispielprogramm 15
<<!DOCTYPE html>
<html>
  <head>
    <script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
    <script src="https://jeromeetienne.github.io/AR.js/aframe/build/aframe-ar.js">
    </script>
  </head>
  <body>
    <a-scene embedded arjs>
      <a-marker preset="hiro">
          <a-box> </a-box>
      </a-marker>
      <a-camera position="0 0 0"> </a-camera>
    </a-scene>
  </body>
</html>>

Erstellen eigener Marker[Bearbeiten]

Die Hiro und Kanji-Marker sind vordefiniert und werden durch die folgende Zeilen jeweils für die Darstellung der 3D-Objekte benutzt.

  • <a-marker preset="hiro">
  • <a-marker preset="kanji">

Jedoch können sie durch andere Marker ersetzt werden, die ggf. besser erkennbar machen, welche 3D-Modelle auf dem jeweiligen Marker dargestellt werden.

Die zwei unterstützten Arten, selbst erstellte Marker einzusetzen sind:

  • Patterns und
  • Barcodes.

Pattern - Muster[Bearbeiten]

Die Patterns als quadratische Bildmuster sollten folgenden Anforderungen erfüllen:

  • (Schwarzer Rand) Als Marker qualifiziert sich jedes Bild, solange es eine schwarze Umrandung besitzt Etienne.
  • (Keine Symmetrie bzgl. Drehung) Eine Marker sollte keine Symmetrie bzgl. Drehung um 80,180 oder 360 Grad besitzen, denn ansonsten kann auf dem Markermuster das 3D-Modell nicht in eindeutiger Weise dargestellt werden, damit das 3D-Objekt im Kamerabild in eindeutiger Weise auf dem Marker dargestellt werden kann.
  • (Musterdetails) Ein 3D-Objekt sollte in unterschiedlicher Entfernung auf dem Marker im Kamerabild dargestellt werden können. Wenn die Detail auf dem Marker zu fein sind, kann eine Webcam mit der gegebenen Auflösung ggf. die Markerorientierung im Raum bei größerer Distanz zur Kamera ggf. nicht mehr auflösen.
  • (Kontraste) In einem Kamerabild sind durch Beleuchtung und Lichteinfall verschiedene Graustufen selbst auf einem weißen Papier erkennbar (z.B. Schatten). Wenn die Kontraste zwischen den verwendeten Farben groß sind, erhöht sich die Erkennungsgenauigkeit. Daher bietet sich bei schlechteren Lichtverhältnissen die Verwendung von groben, nicht drehsymmetrischen Schwarz-Weiß-Mustern an.

Anleitungen zur eigenen Markererstellung[Bearbeiten]

Das AR.js-Entwicklungsteam publizierte Jerome Etienne eine ausführliche Anleitung zur Entwicklung der Marker, an der man sich größtenteils orientieren kann.

Es wurden drei verschiedene Pattern-Marker mithilfe vom Markergenerator Jerome Etienne erzeugt und getestet. Das Benutzen des Generators Jerome Etienne ist sehr einfach: Man lädt ein beliebiges Bild hoch, und erhält eine *.patt- und *.png-Datei des Markers zurück. Von den drei Markern hat der Irina-Marker am besten abgeschlossen: Er wurde am schnellsten erkannt, und es gab kaum Verzögerungen bei Bewegungen.

Erkennungsgenauigkeit[Bearbeiten]

Jedoch hat keiner der erstellten Marker so gut funktioniert, wie der Standard Hiro- und Kanji-Marker. Der Grund dafür ist, dass der Farbkontrast relativ stark sein muss. Hellere Farben werden von der Kamera schlechter erkannt. Ferner ist es wesentlich, dass der Marker bzgl. der Symmetrie des inneren Markerbildes eindeutig festlegen muss, welche Seite "VORNE", "LINKS", "RECHTS", "HINTEN" definiert. Der erste Marker in den folgenden Abbildungen ist in dieser Hinsicht nicht eindeutig.

Beispiel-Marker mit unterschiedlichen Eigenschaften[Bearbeiten]

3D-Objekte auf Markern platzieren[Bearbeiten]

Nach der Markererzeugung muss man dem AR.js und A-Frame mitteilen, dass das erzeugte Muster ein Marker ist. Dies ist sehr einfach realisierbar durch die Ersetzung von

<a-marker preset="hiro"> in Zeile 11 von Beispielprogramm 15.

durch die folgende Zeile möglich:

<a-marker type="pattern" url="marker.patt">


Mit <type="pattern"> sagt man aus, dass der Marker vom Pattern-Typ ist und mit der <url="marker.patt"> gibt man die Adresse an, in der die erzeugte *.patt-Datei sich befindet.

Ein Nachteil bei Pattern besteht darin, dass die Muster durch komplexe Bilder dargestellt werden. Wenn die Marker sich nicht so stark unterscheiden, ist es oft schwer, sie von einander zu differenzieren. Im Prinzip ist ein Bild nichts anderes als eine hoch-dimensionierte Matrix, deren Rekonstruktion bzw. Approximation auf komplizierten Algorithmen beruht, und meistens nicht mal gemacht wird. Die Unterscheidung von Bildern wird anhand gewisser Merkmale gemacht, sodass zwei verschiedene Bilder mit den selben charakteristischen Merkmalen gar nicht unterschieden werden können. Bei einem einfachen klein-dimensionierten Bild (z. B. Pixeln) hingegen ist das Muster viel einfacher zu erkennen.

Solche Bilder, deren Muster eindeutig erkennbar sind, nennt man Barcodes. Es gibt verschiedene Barcode-Arten. Heute unterscheidet man 1D-Barcodes (klassische Barcodes die z. B. in Geschäften benutzt werden, um Produkte zu identifizieren), 2D-Barcodes (z. B. DataMatrix oder QR), und 3D-Barcodes (z. B. farbige 2D-Barcodes).

In AR.js werden schachmusterartige Marker unterstützt. Diese werden sogar empfohlen in Szenen mit mehreren Markern Etienne aus den oben genannten Gründen. Hierbei muss beachtet werden, dass solche Muster klassischerweise mit einer Zahl in Verbindung gebracht werden. Z. B. kann man mithilfe von -schachbrettartigen Barcodes die Zahlen 0-63 kodieren. Daher sieht die Zeile 11 im Programm Beispielprogramm 15 für Barcodes beispielsweise wie folgt aus:

<a-marker type="barcode" value="5">

Die Zeile bedeutet, dass die Kamera nach dem Barcode suchen wird, der einer <"5"> entspricht. Ebenso muss man bei Barcodes die genauere Spezifikation des Markers in Zeile 9 angeben:

<a-scene embedded arjs="detectionMode:mono_and_matrix; matrixCodeType:3x3;">>

Hier steht ebenfalls, dass der Marker schwarzweiß ist und eine -Struktur besitzt, d. h. ein Schachbrett mit 9 Feldern. Die Marker mit den Zahlen 0-63 sind in [4] zu finden.

Ebenso kann man -, - oder -Muster verwenden, wenn man mehr als 64, 8192, oder 4194304 verschiedene Marker braucht. Der Barcode Generator [5] generiert verschiedene Barcodes in verschiedenen Formen. In den Abbildungen sind verschiedene Barcode-Marker-Beispiele dargestellt, die mithilfe des Barcode-Generators erzeugt wurden.

Beispiel: Sonne-Erde-Mond-Dynamik[Bearbeiten]

In diesem Kapitel wird ein Sonnen-Erde-Mond-Modell betrachtet: Die Erde rotiert um die Sonne und der Mond rotiert um die Erde. In der Wissenschaftsliteratur ist dieses Modell bekannt als Dreikörperproblem. Ebenso rotieren die Objekte um die eigene Achse. Diese Simulation eignet sich gut für Grundschüler der vierten Klasse, die die Grundlagen der Planetenbewegung erlernen sollen. Das Beispiel lässt sich mit wenig Aufwand auf das komplette Sonnensystem erweitern. Bevor die Implementierung erläutert wird, wird zuerst das betrachtete Modell genauer beschrieben.

Modellbeschreibung[Bearbeiten]

Animation einer Hypozykloide mit sich überlagernden Kreisbewegungen

Die genaue Dynamik dieser Bewegungen hängt mit dem geometrischen Themengebiet der Zykloide zusammen (siehe Animation). Zur Vereinfachung wird Folgendes angenommen:

  1. Alle drei Objekte sind kugelförmig.
  2. Die Bewegung aller drei Körper findet in der -Ebene statt.
  3. Die Bahnen der Planeten sind kreisförmig und die Bewegungsgeschwindigkeit konstant.
  4. Alle Rotationen sind um die Achse parallel zur -Achse; d. h. die Neigung der Achsen werden vernachlässigt.

Um das Problem besser veranschaulichen zu können, wurde die Skizze angefertigt.

Mit , und bezeichnet man die Radien der Objekte. Die Distanzen und bezeichnen die Abstände von der Erde zur Sonne und von der Erde zum Mond. Mit wird die Zeit bezeichnet, in der die Erde eine volle Umdrehung um die Sonne macht. Mit bezeichnet man die Zeit, die benötigt wird für eine volle Umkreisung des Mondes um die Erde. Der Mond rotiert nicht um die eigene Achse. Es ist bekannt, dass der Mensch nur ein und die selbe Seite des Mondes zu sehen bekommt. Jedoch rotiert die Erde um ihre eigene Achse. Deren Rotationsgeschwindigkeit wird mit der Periodenzeit bezeichnet. Ebenso werden die Maße nicht maßstabsgetreu skaliert, um eine bessere Veranschaulichung zu schaffen. Die Größe der Erde ist im Vergleich zur Sonnengröße vernachlässigbar; die maßstabstreue Skalierung würde dazu führen, dass man die Erde und den Mond nicht erkennen kann. Alle verwendeten Größen sind gewählt wie in der Tabelle angegeben.

Implementierungsvorgehen[Bearbeiten]

Um das Problem in A-Frame veranschaulichen zu können, werden drei Platzhalter für Sonne, Erde und Mond benötigt; im Folgendem als Entity 1, Entity 2 und Entity 3 bezeichnet. Entity 1 dient dazu, die Bewegung um die Sonne zu beschreiben. Innerhalb von Entity 1 wird Entity 2 platziert, verschoben um . Somit rotiert Entity 2 um die Achse im Zentrum von Entity 1. Innerhalb von Entity 2 wird ebenfalls eine Rotation definiert und Entity 3, verschoben um , platziert.

Dieses Beispiel lässt sich vermutlich auch ohne das Entity-Konzept genau so realisieren, wie es im Beispielprogramm 12 gemacht wurde, jedoch liefern die Entities bewegliche lokale Koordinatensysteme, sodass die Objekte nur noch richtig platziert werden müssen.

Um die Idee besser veranschaulichen zu können, wurde folgender Algorithmus als Pseudocode gefertigt.

Algorithmus 1 Pseudocode zu Sonne-Erde-Mond-Bewegungen

Anfang Entity1
Setze Position =
Rotation =
Sonne
Anfang Entity2
Setze Position =
Setze Rotation =
Erde
Anfang Entity3
Setze Position =
Mond
Ende Entity3
Ende Entity2
Ende Entity1

Hierbei ist zu beachten, dass die Objekte durch das Rotieren der Platzhalter ebenso mitrotieren. Wenn die Sonne beipielsweise innerhalb von Entity 1 platziert wird, wie im Algorithmus 1 dargestellt ist, rotiert die Sonne mit. Dies kann man umgehen, indem man innerhalb der Sonnensphäre eine interne Gegenrotation einfügt, oder man platziert die Sonne außerhalb der Entity 1, wie es im Beispielprogramm 6 gemacht wurde. Diese Technik wird auch hier verwendet. Ebenso würde der obige Psedocode dazu führen, dass die Rotationsgeschwindigkeit des Mondes um die Erde gleich der Rotationsgeschwindigkeit der Erde um die eigene Achse wäre. Das heißt, dass der Mond immer nur von einer Seite der Erde gesehen wird. Deshalb lässt man die Rotation innerhalb von Entity 2 der Geschwindigkeit entsprechen, mit der der Mond um die Erde kreist. Die Rotation der Erde um die eigene Achse passt man mit der internen zusätzlichen Rotation (innerhalb der Sphärenumgebung) entsprechend an.

Der Programmcode ist im Beispielprogramm 16 dargestellt.

Beispielprogramm 16
<a-scene>
  <a-sphere radius="0.5"
            src="sonne.jpg">
  </a-sphere>
  <a-entity animation="property:rotation; 
                       to:0 360 0; 
                       dur:100000; 
                       loop:true; 
                       easing:linear">
    <a-entity position="1 0 0"
              animation="property:rotation; 
                         to:0 360 0; 
                         dur:10000; 
                         loop:true; 
                         easing:linear">
      <a-sphere radius="0.125"
                src="erde.jpg"
                animation="property:rotation; 
                           to:0 360 0; 
                           dur:1000; 
                           loop:true; 
                           easing:linear">
      </a-sphere>
      <a-entity position="0.3 0 0">
        <a-sphere radius="0.0525"
                  src="mond.jpg">
        </a-sphere> 
      </a-entity>
    </a-entity>
  </a-entity>
  <a-sky radius="50"
         src="sternhimmel.jpg"
         repeat="20 20">
  </a-sky>
</a-scene>

Hierbei kann man anmerken, dass die Entity 3 nicht notwendigerweise gebraucht wird. Man kann genauso den Mond in Position platzieren. Allerdings liefert uns Entity 3 eine gewisse Freiheit: Man kann damit beispielsweise die Rotation des Mondes um die eigene Achse verwirklichen. Um es so realistisch wie möglich zu gestalten, wurden Texturen für Planeten und ein Sternbild für den Himmel verwendet, die man in Textur-Universum finden kann. Hier wurde auf normal-maps verzichtet, da der Effekt kaum zu sehen ist.

Markerbasierte Realisierung[Bearbeiten]

Das Modell lässt sich auch auf Marker übertragen. Beispielprogramm 17 auf dem Hiro-Marker[2] zeigt, wie das entwickelte Sonne-Erde-Mond-Modell auf Hiro-Marker projiziert werden kann. Die dazu benötigten Schritte sind genau wie im Kapitel "Augmented Reality with AR.js" beschrieben, und werden daher nicht wiederholt. Das Verwenden des Hintergrundes ist in AR überflüssig, sodass <a-sky> wegfällt.

<a-scene> embedded arjs>
 <a-marker preset="hiro">
   <a-sphere radius="0.5"
             src="sonne.jpg">
   </a-sphere>
   <a-entity animation="property:rotation; 
                        to:0 360 0; 
                        dur:100000; 
                        loop:true; 
                        easing:linear">
     <a-entity position="1 0 0"
               animation="property:rotation; 
                          to:0 360 0; 
                          dur:10000; 
                          loop:true; 
                          easing:linear">
       <a-sphere radius="0.125"
                 src="erde.jpg"
                 animation="property:rotation; 
                            to:0 360 0; 
                            dur:1000; 
                            loop:true; 
                            easing:linear">
        </a-sphere>
        <a-entity position="0.3 0 0">
          <a-sphere radius="0.0525"
                    src="mond.jpg">
          </a-sphere> 
        </a-entity>
      </a-entity>
    </a-entity>
  </a-marker>
  <a-camera position="0 0 0"> </a-camera>
</a-scene>

Siehe auch[Bearbeiten]

Quellennachweis[Bearbeiten]

  1. Chen, P., Liu, X., Cheng, W., & Huang, R. (2017). A review of using Augmented Reality in Education from 2011 to 2016. Innovations in smart learning, 13-18.
  2. Hiro-Kanji-Marker Druckvorlage (2017) PDF-Dokument - Zum Ausdrucken und Aufkleben auf Pappstreifen - Download: https://niebert.github.io/JSON3D4Aframe/pdf/marker_hiro_kanji_printout.pdf JSON3D4Aframe