WebGL: Ein Anfängerleitfaden für 3D-Grafiken im Browser

Hallo da draußen, zukünftige 3D-Grafik-Zauberer! Ich freue mich sehr, Ihr Guide auf dieser aufregenden Reise in die Welt von WebGL zu sein. Als jemand, der seit Jahren Computergrafik unterrichtet, kann ich Ihnen sagen, dass WebGL wie eine magische Zauberstab für Ihren Webbrowser ist. Es ermöglicht Ihnen, atemberaubende 3D-Grafiken und Animationen direkt in Ihren Webseiten zu erstellen. Ist das nicht toll? Lassen Sie uns eintauchen!

WebGL - Home

Was ist WebGL?

WebGL, kurz für Web Graphics Library, ist eine JavaScript-API, die es ermöglicht, interaktive 2D- und 3D-Grafiken in jedem kompatiblen Webbrowser ohne die Notwendigkeit von Plugins zu rendern. Es ist so, als würde man Ihrem Webbrowser Superkräfte verleihen, um erstaunliche visuelle Erlebnisse zu schaffen!

Eine kurze Geschichte

WebGL wurde erstmals 2011 vorgestellt und hat seitdem die Art und Weise revolutioniert, wie wir über Grafiken im Web nachdenken. Bevor WebGL kam, musste man Plugins wie Flash oder Java-Applets verwenden, um 3D-Grafiken im Browser zu erstellen. Jetzt können wir all das nativ im Browser erledigen. Es ist, als hätten wir von einem Fahrrad auf ein Sportauto aufgerüstet!

Voraussetzungen

Bevor wir unsere WebGL-Abenteuer starten, stellen wir sicher, dass wir die richtigen Werkzeuge in unserem Rucksack haben:

  1. Ein moderner Webbrowser (Chrome, Firefox, Safari oder Edge)
  2. Ein Texteditor (ich empfehle Visual Studio Code, aber jeder tut es)
  3. Grundkenntnisse in HTML und JavaScript (machen Sie sich keine Sorgen, wenn Sierostig sind, wir werden im Laufe der Zeit复习)

Einstieg in WebGL

Lassen Sie uns unser erstes WebGL-Programm erstellen! Wir beginnen mit einem einfachen "Hallo, WebGL!"-Beispiel, das ein farbiges Dreieck auf dem Bildschirm anzeigt.

Schritt 1: Einrichten der HTML

Zuerst müssen wir eine HTML-Datei mit einem Canvas-Element erstellen. Dieses Canvas ist der Ort, an dem unsere WebGL-Zauberei stattfinden wird.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Hello, WebGL!</title>
<style>
canvas { border: 1px solid black; }
</style>
</head>
<body>
<canvas id="glCanvas" width="640" height="480"></canvas>
<script src="webgl-demo.js"></script>
</body>
</html>

In dieser HTML haben wir ein Canvas-Element mit der ID "glCanvas" erstellt und seine Abmessungen auf 640x480 Pixel gesetzt. Wir haben auch auf eine JavaScript-Datei namens "webgl-demo.js" verlinkt, in der wir unseren WebGL-Code schreiben werden.

Schritt 2: Initialisieren von WebGL

Nun erstellen wir unsere "webgl-demo.js"-Datei und fangen an, einige JavaScript-Code zu schreiben, um WebGL zu initialisieren:

function main() {
const canvas = document.getElementById("glCanvas");
const gl = canvas.getContext("webgl");

if (!gl) {
alert("Unable to initialize WebGL. Your browser or machine may not support it.");
return;
}

// Set clear color to black, fully opaque
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// Clear the color buffer with specified clear color
gl.clear(gl.COLOR_BUFFER_BIT);
}

window.onload = main;

Lassen Sie uns das herunterbrechen:

  1. Wir holen eine Referenz zu unserem Canvas-Element.
  2. Wir versuchen, einen WebGL-Kontext vom Canvas zu erhalten. Wenn dies fehlschlägt, bedeutet dies, dass WebGL nicht unterstützt wird, und wir zeigen eine Fehlermeldung an.
  3. Wenn erfolgreich, setzen wir die Clear-Farbe (die Hintergrundfarbe) auf schwarz und löschen den Canvas.

Schritt 3: Erstellen von Shadern

Shaders sind spezielle Programme, die auf der GPU ausgeführt werden. Sie werden in einer Sprache namens GLSL (OpenGL Shading Language) geschrieben. Wir benötigen zwei Arten von Shadern: Vertex-Shaders und Fragment-Shaders.

// Vertex shader program
const vsSource = `
attribute vec4 aVertexPosition;

void main() {
gl_Position = aVertexPosition;
}
`;

// Fragment shader program
const fsSource = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

Der Vertex-Shader positioniert unsere Vertices, während der Fragment-Shader unsere Pixel einfärbt (in diesem Fall rot).

Schritt 4: Initialisieren eines Shader-Programms

Nun müssen wir diese Shaders kompilieren und zu einem Shader-Programm verknüpfen:

function initShaderProgram(gl, vsSource, fsSource) {
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);

const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));
return null;
}

return shaderProgram;
}

function loadShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);

if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}

return shader;
}

Dieser Code kompiliert unsere Shaders, verknüpft sie zu einem Programm und überprüft auf Fehler.

Schritt 5: Erstellen des Dreiecks

Nun erstellen wir die Daten für unser Dreieck:

function initBuffers(gl) {
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

const positions = [
-1.0,  1.0,
1.0,  1.0,
-1.0, -1.0,
];

gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

return {
position: positionBuffer,
};
}

Dies erstellt ein Buffer und füllt es mit den Positionen unserer Dreiecksvertices.

Schritt 6: Zeichnen der Szene

Schließlich setzen wir alles zusammen und zeichnen unser Dreieck:

function drawScene(gl, programInfo, buffers) {
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

gl.useProgram(programInfo.program);

gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexPosition,
2,        // 2 components per iteration
gl.FLOAT, // the data is 32bit floats
false,    // don't normalize
0,        // stride (0 = auto)
0         // offset into the buffer
);

gl.drawArrays(gl.TRIANGLES, 0, 3);
}

Diese Funktion löscht den Canvas, stellt unser Shader-Programm ein, verbindet unsere Buffer-Daten und zeichnet schließlich unser Dreieck.

Alles zusammenfügen

Nun aktualisieren wir unsere main-Funktion, um all diese Teile zu verwenden:

function main() {
const canvas = document.getElementById("glCanvas");
const gl = canvas.getContext("webgl");

if (!gl) {
alert("Unable to initialize WebGL. Your browser or machine may not support it.");
return;
}

const shaderProgram = initShaderProgram(gl, vsSource, fsSource);

const programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
},
};

const buffers = initBuffers(gl);

drawScene(gl, programInfo, buffers);
}

window.onload = main;

Und das ist es! Dein erstes WebGL-Programm. Wenn du deine HTML-Datei in einem Browser öffnest, solltest du ein rotes Dreieck auf einem schwarzen Hintergrund sehen. Gratulation!

Häufige WebGL-Methoden

Hier ist eine Tabelle einiger häufiger verwendeter WebGL-Methoden, die wir verwendet haben und deren Zweck:

Methode Zweck
gl.createBuffer() Erstellt ein neues Buffer-Objekt
gl.bindBuffer() Bindet ein Buffer-Objekt an ein Ziel
gl.bufferData() Initialisiert und erstellt den Daten Speicher des 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.getAttribLocation() Gibt die Lage einer Attributvariablen zurück
gl.enableVertexAttribArray() Aktiviert eine Vertex-Attribut-Array
gl.vertexAttribPointer() Spezifiziert die Anordnung der Vertex-Attribut-Daten
gl.drawArrays() Render Primitive aus Array-Daten

Schlussfolgerung

Wow, wir haben heute viel Boden gewonnen! Wir haben erfahren, was WebGL ist, unsere Entwicklungsumgebung eingerichtet und unser erstes WebGL-Programm erstellt. Denken Sie daran, das Lernen von WebGL ist wie das Fahrradfahren zu lernen - es mag am Anfang wacklig erscheinen, aber mit Übung werden Sie很快 zoomen können!

In zukünftigen Lektionen werden wir komplexere Formen erkunden, Interaktivität hinzufügen und sogar in die 3D-Grafik eintauchen. Die Welt von WebGL ist riesig und spannend, und ich kann es kaum erwarten, mehr davon mit Ihnen zu erkunden. Bis下次, fröhliches Coden!

Credits: Image by storyset