WebGL Grundlagen 12 – Point Lighting.

Willkommen zu unserem elften Teil unserer Serie von WebGL Grundlagen. In diesem Beitrag werden wir das Point Lighting thematisieren. Der Inhalt ist leicht zu verstehen und sehr wichtig. Wir werden damit später interessante Dinge machen können. Das Point Lighting ist eine Beleuchtungsart, die von einem bestimmten Punkt innerhalb einer Szene kommt – im Gegensatz zu des bisher verwendeten directional Lighting, bei der das Licht von einem Punkt außerhalb der Szene kommt.

Ein wichtiger Hinweis: Dieser Teil richtet sich an Personen mit fortgeschrittenen Programmierkenntnissen, aber ohne wirkliche Erfahrung mit 3D-Grafiken. Sie werden ein gutes Verständnis für den Code mitbringen und es zum Laufen bringen, so dass Sie so schnell wie möglich mit der Erstellung einer eigenen Website in 3D beginnen können.

Es existieren zwei verschiedene Möglichkeiten, den Code für dieses Beispiel zu erhalten. In den Browsereinstellungen mit „View Source“, während Sie sich die Live-Version ansehen oder wenn Sie GitHub verwenden, können Sie es aus dem Repository kopieren. Unabhängig davon für welchen Weg Sie sich entscheiden, sollten Sie ihren bevorzugten Texteditor herunterladen und sich den Code genau ansehen.

Wir werden zunächst einmal genau beschreiben, was wir mit dem Point Lighting vorhaben. Der Unterschied zwischen Point und directional Lighting besteht darin, dass das Licht von einem Punkt innerhalb der Szene kommt. Der Gedanke eines Augenblicks sollte deutlich machen, dass dies bedeutet, dass der Blickwinkel aus dem das Licht kommt an jedem Punkt der Szene unterschiedlich ist. Der naheliegende Weg für die Modellierung besteht also darin, die Richtung zur Position des Lichts für jeden Scheitelpunkt zu berechnen und dann genau die gleichen Berechnungen durchzuführen, welche wir für das directional Lighting gemacht haben. Und genau das werden wir jetzt umsetzen.

Man könnte an dieser Stelle denken, dass es vielleicht sogar noch besser wäre die Richtung zum Licht nicht nur für jeden Scheitelpunkt, sondern auch für die Punkte zwischen den Scheitelpunkten zu berechnen. Und Sie haben völlig Recht, wenn Sie das denken. Eine derartige Beleuchtung bedeutet für eine Grafikkarte deutlich mehr Arbeit, aber sieht im Endergebnis deutlich besser aus. Und genau das werden wir in unserer nächsten Übung machen.

Nun haben wir uns entschieden, was wir tun wollen. Es lohnt sich also, noch einmal auf das Videobeispiel zu schauen und noch eine Sache zu beachten. Es existiert kein Objekt in der Szene an dem Punkt, von dem das Licht kommt.Wenn Sie ein Objekt haben möchten, das Licht zu werfen scheint, dann müssen Sie die Lichtquelle und das Objekt getrennt definieren. Das Objekt umzusetzen sollte ziemlich einfach sein, also werden wir hier nur erklären, wie die Quelle des Point Lighting funktioniert. Wie Sie es vielleicht von der obigen Beschreibung her erwarten können, ist es eigentlich ganz einfach.

Wie üblich beginnen wir am unteren Rand der HTML-Quelldatei und arbeiten uns durch die Unterschiede zwischen dieser Datei und dem elften Teil nach oben. Die ersten Änderungen sind im HTML-Body zu sehen, wo sich die Felder in denen Sie eine Lichtrichtung eingeben können, geändert haben, um die Position des Lichts zu bestimmen. Das ist so einfach, dass jegliche Veranschaulichungen hier keinen Sinn machen, also gehen wir direkt zu webGLStart über. Noch einmal, die Änderungen sind einfach – diese Übung hat keine mausbasierten Steuerelemente, also haben wir keinen Mouse-Handling-Code. Was früher als initTexture bekannt war, wird nun als initTextures bezeichnet, weil Sie davon davon laden wird.

Ein wenig weiter oben hat die Tick-Funktion einen neuen Aufruf erhalten, um zu animieren, so dass sich unsere Szene im Laufe der Zeit aktualisiert.

Copy to Clipboard

Darüber hinaus ist die Animationsfunktion selbst zu sehen, die einfach zwei globale Variablen aktualisiert, welche beschreiben, wie weit der Mond und der Würfel um ihre Umlaufbahn herum entfernt sind, dass Sie sich bei 50°/Sekunde umkreisen:

Copy to Clipboard

Die nächste Funktion ist drawScene, welche ein paar interessante Änderungen enthält. Es beginnt mit dem normalen Textbaustein-Code, um das Canvas zu leeren und unsere Perspektive einzurichten. Daraus ergibt sich ein Code, der mit dem Code aus dem elften Grundlagenteil identisch ist, um zu überprüfen, ob das Kontrollkästchen für die Beleuchtung aktiviert ist und um die Umgebungslichtfarbe an die Grafikkarte zu senden:

Copy to Clipboard

Anschließend schieben wir die Position unseres Punktlichst in einer Uniform zur Grafikkarte. Dies entspricht dem Code, welcher die Lichtrichtung in unserer elften Übung nach oben schob. Der große Unterschied liegt darin, dass hier etwas weggenommen wurde, anstatt etwas hinzuzufügen. Als wir die Beleuchtungsrichtung an die Grafikkarte schickten, mussten wir Sie in einen Einheitsvektor umwandeln und ihre Richtung umkehren. So etwas benötigen wir hier nicht. Wir schieben einfach die Koordinaten des Lichts direkt nach oben:

Copy to Clipboard

Als nächstes machen wir das Gleiche für die Farbe des Punktlichts und wir sind fertig mit dem Lichtcode in drawScene:

Copy to Clipboard

Anschließend zeichnen wir tatsächlich die Kugel und den Würfel in den entsprechenden Positionen:

Copy to Clipboard

Also, das ist drawScene. Wenn Sie den Code weiter nach oben schieben, werden Sie sehen, dass initBuffers unseren Standard-Code zur Erzeugung von Puffern für einen Würfel sowie den Code für eine Kugel erhalten hat und dass initTextures nun zwei Texturen statt einer lädt.

Die nächste Änderung ist die Wichtigste. Wenn du nach oben scrollst, wo sich der VertexShader befindet, wirst du sehen, dass er ein paar kleine Änderungen hat und es sind diese, die den Unterschied für diese Übung ausmachen. Die Veränderungen wurden wieder rot markiert:

Copy to Clipboard

Hier wurde unser alter Code in zwei Teile geteilt. In allen unseren bisherigen Vertex-Shadern haben wir die Model-View-Matrix und die Projektionsmatrix in einem Rutsch auf die Vertex-Position angewendet:

Copy to Clipboard

Nun wird der Zwischenwert für die aktuelle Position des Scheitelpunktes mit der aktuellen Model-View-Matrix gespeichert, bevor dieser perspektivisch angepasst wurde. Dies wird im nächsten Bit verwendet:

Copy to Clipboard

Die Position des Lichts und die Scheitelposition, die mit der Model-View-Matrix multipliziert wurde, richten Sie nach den Weltkoordinaten. Wir müssen die Richtung des Punktlichts von unserem aktuellen Scheitelpunkt in Bezug auf diese Koordinaten und die Richtung von einem Punkt zum anderen berechnen, indem wir Sie substrahieren. Wenn das erledigt ist, müssen wir den Richtunsgvektor normalisieren, so dass dieser genau wie unser alter Lichtrichtungsvektor eine Länge von eins hat.

Sobald das erledigt ist, sind alle Teile an Ort und Stelle, um eine Berechnung durchzuführen, welche identisch mit derjenigen ist, die wir für das directional Lighting gemacht haben, wobei nur einige wenige Variablennamen geändert wurden:

Copy to Clipboard

Und das war`s. Sie wissen jetzt, wie man Shader schreibt, um Point Lighting zu erzeugen.

Nächstes Mal werden wir uns mit dem Thema der Beleuchtung näher beschäftigen und den Realismus unserer Szene verbessern, indem wir die Beleuchtung fragmentarisch statt per-vertex arbeiten lassen.