---
title: "WebGL Showcase"
date: 2018-01-03
cover: ./images/Bildschirmfoto-2018-01-03-um-13.09.42-2.png
comments: true
---

import Image from "@components/Image.astro";
import YouTube from "@components/YouTube.astro";

import Screenshot1 from "./images/Bildschirmfoto-2018-01-03-um-13.18.45-2.png";
import Screenshot2 from "./images/Bildschirmfoto-2018-01-03-um-13.18.27-2.png";
import Screenshot3 from "./images/Bildschirmfoto-2018-01-03-um-13.17.57-2.png";
import Screenshot4 from "./images/Bildschirmfoto-2018-01-03-um-13.09.42-2.png";
import WHarG from "./images/wHarG.jpg";
import ImageGallery from "@components/ImageGallery.svelte"

<ImageGallery client:load/>

Vorerst etwas Story:

Ich habe mich in letzter Zeit sehr viel mit dem Programmieren von Webanwendungen beschäftigt, angefangen über statisches HTML und CSS, dann bin ich zu Javascript übergegangen und jetzt schließlich Node.js. Im

Grunde hat mich programmieren schon vor sehr langer Zeit gepackt, und zwar als ich mit meinem besten Freund für ein Schulpraktikum vier Wochen auf einer Farm in Kanada verbracht hab. Ich wollte diese Erfahrung irgendwie festhalten nicht nur in Bildern und Videos sondern auch interaktiv, der Plan war eine Reihe von Bildern von der Farm zu machen und auf einer Website eine Art Suchbild/Weg durch die Farm zu erstellen. Der User sollte dann auf bestimme parts in dem Foto klicken können, eventuell Infos dazu bekommen und sich so durch die Farm bewegen. Ich weiß noch dass ich es geschafft habe dass erste Bild einzubinden und vollflächig darzustellen. Dann habe ich die anderen zerschnipselt und versucht über dass erste zu legen und meine Fresse war die Scheiße frustrierend, an alle die schonmal versucht habe Dinge mit CSS zu positionieren ohne überhaupt zu wissen was der Unterschied zwischen "absolute" und "relative" ist, ich denke ihr wisst wie es ausgegangen ist, an alle anderen stellt es euch vor als würdet ihr versuchen nen 20. seitige Broschüre in Word gestalten.  Diese Website verstaubt ihm Moment auf ner alten Festplatte von mir, naja vielleicht grab ich sie eines Tages noch aus.

Dann bin ich im Zuge meiner Arbeit irgendwie auf WebGL, dass ist eine Technologie die auf einer anderen Technologie (OpenGL) beruht, die wiederum so gut wie alle Live 3D Anwendung ermöglicht, WebGL also macht es möglich 3D im Internet zu haben, echtes, interaktives 3D. Ich war ziemlich begeistert. Ich denke im Nachhinein war es der perfekte Einstieg für mich, ich kannte schon die ganzen Fremdwörter aus dem 3D Bereich, deswegen war es nicht so schwierig für mich. Des Weiteren hat mir eine grandiose Javascript Library namens three.js geholfen, eine Library ist im Grunde eine kleine extra Programmiersprache, der man dann nur einfache Dinge sagen muss, wie zum Beispiel "new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );" und die dann die ganzen komplizierten Sachen für einen macht.

Meine erste 3D Anwendung ist bist jetzt auch meine komplizierteste da ich immer weiter daran arbeite. Eine Visualisierung von einem von mir erstellten Raum:

[Link](/modern/?scene=modern)

Bis jetzt habe ich zwei Szenen erstellt einmal "modern" und einmal "dwfb", beide kann man erreichen in dem man in der URL hinter "szene=" den Szenennamen schreibt. Da in "dwfb" diverse 4k Texturen sind, sind die Ladezeiten alles andere als schön.

# Sachen die ich beim Programmieren von dieser Website gelernt habe:

OOP:

OOP steht für Object Oriented Programming, dass heißt der Code ist in Objekte aufgeteilt die untereinander kommunizieren, dass macht es einfacher Fehler zu finden, und den Code zu erweitern.

Nerdstuff:

jaja ich weiß OOP, dass ist ja mal so was von 2015
Functional Programming ist das Neue Ding und so, ey ich habe
quasi gerade erst angefangen zu Programmieren mir reicht OOP
für jetzt erstmal. Also

JSON:

JSON steht for JavaScript Object Notation, ich brauchte für das Projekt einen besseren Weg meine Objekte in die Szene zu laden als den Standardweg, deswegen habe ich ein Loader Objekt programmiert, was zuerst aus einer .json Datei den Grundaufbau der Szene lädt, d.h. welche Objekte an welcher Position stehen, welche Materialien diese Objekte haben usw, danach lädt es diese Objekte, erstellt die Materialien unternimmt diverse Optimierung an der Szene, und lädt dann zum Schluss die Szene.

---

Nerdstuff:

Sobald der Loader initalisiert wird erstellt er eine Szene.
Dann kann man über Loader.load("Pfad/Zur/Json/Datei") dein Ladevorgang starten.
Die JSON Datei wird per XMLHttpRequest geladen, dann geparst.
Die Datei enthält den Namen der Szene, einen Array für alle HDRI's, einen Array für alle Objekte,
und einen für alle Materialen. Der Aufbau ist darauf ausgelegt möglich
wenige requests zu machen, und wegen der Redundanz der einzelnen Objekte,
eine HDRIS wird von vielen Materialien verwendet, eine Textur eher selten deswegen sind
die Texturen in den Materialien Array eingebettet.
Zur Optimierung der FPS kann man den Objekten eine "statische"
Eigenschaft geben, alle statischen Objekte werden in Buffergeometry
umgewandelt, dass heißt die Koordinaten der einzelnen Vertices liegen nicht im Format
\{xyz\}\{xyz\}\{xyz\}\{xyz\} vor sondern so: \{xyzxyzxyzxyz\}. Dies verringert die Kommunikation
zwischen CPU und GPU. Außerdem werden alle statischen Objekte zu einem Mesh
zusammengefügt was wiederum denselben Effekt hat.

Hier der Link zur JSON Datei:
[LINK](/modern/3D/modern/modern.json) Und hier der Link zum Loader Modul:
[LINK](/modern/js/loader.js)

ArchVizControls:

Architecture Visualizations Controls, es gibt schon diverse fertig programmierte Objekte die den User die Kamera kontrollieren lassen. Diese hatten allerdings diverse Limitationen die ich nicht umgehen konnte deshalb habe ich meine eigenen Controls programmiert. Diese haben den Vorteil das sie sehr einfach einen 3D Cursor unterstützen, genauere Begrenzung der Kamera Rotation, und der Auto Rotation der Kamera und bessere Drag Controls.

---

Nerdstuff:

Die Komplikation bei den OrbitControls.js die ich vorher benutzt habe
war dass der Author die kompletten Rotation auf der Y-Achse von -PI bis
+PI moduliert hat, das Problem ist hier etwas verdeutlicht:

<Image src={WHarG} alt="WHarG" />

Nachdem ich dazu eine Frage auf Stackoverflow gestellt habe,
wurde ich darauf hingewiesen dass ich relativ leicht meine
eigenen Controls programmieren kann. Einfach ein Empty Objekt,
an welches die Kamera geparented ist. Dann muss man nur noch aus
der MouseDown Position und der aktuellen Mouse Position einen
Vektor erstellen und diesen als Rotation auf das Empty Objekt anwenden.
Dazu dann noch ein Raycaster, welcher die Interaktion mit dem 3D Cursor
und klickbaren Objekten ermöglicht, und eine Animationsmodul zum
animieren der Kamera wenn man auf etwas klickt uuuuuund
fettich.

Screenshots:

Modern:
<Image src={Screenshot1} alt="Screenshot 1" />
<Image src={Screenshot2} alt="Screenshot 2" />

DWFB:
<Image src={Screenshot3} alt="Screenshot 3" />
<Image src={Screenshot4} alt="Screenshot 4" />

