WebGL - Drehender Würfel
Hallo da draußen, zukünftige WebGL-Zauberer! Heute machen wir uns auf eine aufregende Reise in die Welt der 3D-Grafik. Bis zum Ende dieses Tutorials wirst du in der Lage sein, einen drehenden Würfel mit WebGL zu erstellen. Ist das nicht toll? Lass uns eintauchen!
Grundlagen verstehen
Bevor wir anfangen, Würfel wie ein DJ zu drehen, lassen wir uns einige grundlegende Konzepte zu Gemüte führen.
Was ist WebGL?
WebGL (Web Graphics Library) ist eine JavaScript-API, die es uns ermöglicht, 3D-Grafik in einem Webbrowser zu rendern. Es ist so, als würde man seinem Browser ein Paar 3D-Brillen geben!
Warum ein Würfel?
Du fragst dich vielleicht, "Warum fangen wir mit einem Würfel an?" Na, mein liebes Studium, ein Würfel ist wie das "Hallo Welt" der 3D-Grafik. Er ist einfach genug, um ihn zu verstehen, aber komplex genug, um uns wichtige Konzepte beizubringen. Und wer liebt nicht einen guten Würfel?
Unsere WebGL-Umgebung einrichten
Das HTML-Canvas
Zuerst brauchen wir eine Bühne für unseren Würfel, auf der er auftreten kann. In WebGL nennt man diese Bühne canvas. Lassen wir uns das einrichten:
<canvas id="glcanvas" width="640" height="480">
Dein Browser unterstützt kein HTML5-Canvas
</canvas>
Dies erstellt ein 640x480 Pixel großes Canvas. Wenn du es nicht siehst, keine Sorge - es ist wie ein unsichtbarer Tanzboden momentan.
WebGL initialisieren
Jetzt bereiten wir WebGL auf die Party vor:
var canvas = document.getElementById('glcanvas');
var gl = canvas.getContext('webgl');
if (!gl) {
console.log('WebGL wird nicht unterstützt, zurückgreifen auf experimental-webgl');
gl = canvas.getContext('experimental-webgl');
}
if (!gl) {
alert('Dein Browser unterstützt kein WebGL');
}
Dieser Code holt unseren WebGL-Kontext. Wenn dein Browser kein WebGL unterstützt, ist es wie versucht, eine DVD auf einem VHS-Player abzuspielen - es funktioniert einfach nicht!
Unseren 3D-Würfel erstellen
Vertices definieren
Ein Würfel hat 8 Ecken (Vertices). Wir müssen WebGL mitteilen, wo diese Ecken sind:
var vertices = [
// Vorderseite
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Rückseite
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Oberseite
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Unterseite
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Rechtes Gesicht
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Linkes Gesicht
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
];
Jede Gruppe von drei Zahlen represents eine Ecke unseres Würfels im 3D-Raum. Es ist, als würde man WebGL eine Karte unseres Würfels geben!
Buffer erstellen
Jetzt müssen wir diese Daten an die GPU senden:
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
Das ist so, als würde man seinen Würfel in einen Koffer (Buffer) packen und ihn zur GPU schicken.
Shader - Die Magier von WebGL
Vertex-Shader
Der Vertex-Shader positioniert unsere Vertices:
var vertexShaderSource = `
attribute vec3 aVertexPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);
}
`;
Dieser Shader nimmt jeden Vertex und wendet unsere Transformationsmatrizen an. Es ist, als würde ein Magier die Ecken unseres Würfels bewegen!
Fragment-Shader
Der Fragment-Shader färbt unseren Würfel:
var fragmentShaderSource = `
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
`;
Dieser einfache Shader färbt alles weiß. Es ist, als würde man unseren Würfel anmalen!
Shader kompilieren und verknüpfen
Jetzt müssen wir unsere Shader kompilieren und sie in ein Programm verknüpfen:
function getShader(gl, source, type) {
var shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert('Beim Kompilieren der Shader ist ein Fehler aufgetreten: ' + gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var vertexShader = getShader(gl, vertexShaderSource, gl.VERTEX_SHADER);
var fragmentShader = getShader(gl, fragmentShaderSource, gl.FRAGMENT_SHADER);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert('Das Shader-Programm konnte nicht initialisiert werden: ' + gl.getProgramInfoLog(shaderProgram));
}
gl.useProgram(shaderProgram);
Das ist so, als würde man seinen Magiern (Shaders) ihre Tricks beibringen und sie dann auf die Bühne schicken!
Unseren Würfel drehen
Rotation einrichten
Um unseren Würfel zu drehen, müssen wir seinen Drehwinkel im Laufe der Zeit aktualisieren:
var cubeRotation = 0.0;
var then = 0;
function render(now) {
now *= 0.001; // in Sekunden umwandeln
const deltaTime = now - then;
then = now;
cubeRotation += deltaTime;
drawScene();
requestAnimationFrame(render);
}
Diese Funktion wird wiederholt aufgerufen und aktualisiert die Drehung unseres Würfels jedes Mal.
Szene zeichnen
Jetzt setzen wir alles zusammen und zeichnen unseren drehenden Würfel:
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, 45 * Math.PI / 180, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.1, 100.0);
const modelViewMatrix = mat4.create();
mat4.translate(modelViewMatrix, modelViewMatrix, [-0.0, 0.0, -6.0]);
mat4.rotate(modelViewMatrix, modelViewMatrix, cubeRotation, [0, 1, 1]);
gl.uniformMatrix4fv(gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'), false, projectionMatrix);
gl.uniformMatrix4fv(gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'), false, modelViewMatrix);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 36);
}
Diese Funktion löscht die Leinwand, stellt unsere Perspektive ein, wendet unsere Rotation an und zeichnet schließlich unseren Würfel.
Fazit
Und da hast du es, Leute! Wir haben einen drehenden 3D-Würfel mit WebGL erstellt. Denke daran, das Beherrschen von WebGL ist wie das Jonglieren lernen - es erfordert Übung, aber wenn du es einmal kannst, kannst du erstaunliche Dinge vollbringen!
Hier ist eine Tabelle, die die Hauptmethoden zusammenfasst, die wir verwendet haben:
Methode | Beschreibung |
---|---|
gl.createBuffer() |
Erstellt ein neues Buffer-Objekt |
gl.bindBuffer() |
Bindet ein Buffer-Objekt an ein Ziel |
gl.bufferData() |
Erstellt und initialisiert den Daten Speicher eines Buffer-Objekts |
gl.createShader() |
Erstellt ein Shader-Objekt |
gl.shaderSource() |
Setzt den Quellcode eines Shader-Objekts |
gl.compileShader() |
Kompiliert ein Shader-Objekt |
gl.createProgram() |
Erstellt ein Programm-Objekt |
gl.attachShader() |
Hängt ein Shader-Objekt an ein Programm-Objekt an |
gl.linkProgram() |
Verknüpft ein Programm-Objekt |
gl.useProgram() |
Setzt das angegebene Programm als Teil des aktuellen Render-Zustands |
gl.clear() |
Löscht Puffer zu voreingestellten Werten |
gl.uniformMatrix4fv() |
Gibt den Wert einer uniformen Variablen für das aktuelle Programm-Objekt an |
gl.drawArrays() |
Render Primitive aus Array-Daten |
Weiter üben, weiter coden, und bald wirst du erstaunliche 3D-Grafik in deinem Browser erstellen. Viel Spaß beim Coden!
Credits: Image by storyset