WebGL - Grafik-Pipeline
Hallo那里,有抱负的程序开发者们!今天,我们将踏上一段令人兴奋的旅程,探索 WebGL Grafik-Pipeline。如果你是编程新手,不用担心——我会成为你友好的向导,我们会一步一步地进行。在本教程结束时,你将有一个扎实的理解,了解 WebGL 如何将你的代码转换成屏幕上的惊人视觉效果。
JavaScript: Der Ausgangspunkt
Bevor wir uns in die Tiefen von WebGL stürzen, beginnen wir mit etwas Vertrautem – JavaScript. WebGL wird über JavaScript angesprochen, was es zum perfekten Einstiegspunkt für unser Abenteuer macht.
Dein Erstes WebGL-Programm
Lassen wir mit einem einfachen Beispiel beginnen:
// Hole das Canvas-Element
const canvas = document.getElementById('myCanvas');
// Hole den WebGL-Kontext
const gl = canvas.getContext('webgl');
// Setze die Clear-Farbe (Hintergrundfarbe)
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// Bereinige das Canvas
gl.clear(gl.COLOR_BUFFER_BIT);
In diesem Code-Snippet machen wir einige Dinge:
- Wir holen eine Referenz zu unserem HTML Canvas-Element.
- Wir erhalten den WebGL-Render-Kontext.
- Wir setzen die Clear-Farbe (in diesem Fall schwarz).
- Wir bereinigen das Canvas mit unserer angegebenen Farbe.
Das mag nicht viel erscheinen, aber Gratulation! Du hast dein erstes WebGL-Programm erstellt. Es ist, als ob du ein leeres Canvas für ein Meisterwerk vorbereitet hast.
Vertex Shader: Gestaltung Deiner Welt
Nun, da wir unser Canvas bereit haben, sprechen wir über Vertex-Shaders. Stell dir Vertex-Shaders als Bildhauer deiner 3D-Welt vor. Sie arbeiten mit den rohen Daten deiner Objekte – den Vertexen.
Ein Einfacher Vertex Shader
Hier ist ein Beispiel eines grundlegenden Vertex-Shaders:
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
Dieser Shader macht etwas Einfaches, aber Kritisches – er nimmt die Position jedes Vertex und weist sie gl_Position
zu. Es ist, als würde man jedem Punkt deines 3D-Objekts sagen: "Du gehst hier hin!"
Primitive Assembly: Verbinde Die Punkte
Nachdem der Vertex Shader seine Arbeit erledigt hat, bewegt sich WebGL zur Primitive Assembly. Diese Stufe ist wie "Verbinde die Punkte" – sie nimmt die einzelnen Vertexen und.figureiert heraus, wie sie miteinander verbunden werden sollten, um Formen zu bilden.
Zum Beispiel, wenn du ein Dreieck zeichnest, würde die Primitive Assembly drei Vertexen nehmen und verstehen, dass sie ein einzelnes Dreieck bilden.
Rasterisierung: Pixel Überall
Nun kommt die Magie der Rasterisierung. Diese Stufe verwandelt unsere 3D-Formen in die 2D-Pixel, die du auf deinem Bildschirm siehst. Es ist, als ob man eine 3D-Skulptur nimmt und ein detailliertes Foto davon erstellt.
Fragment Shader: Male Deine Welt
Der Fragment Shader ist, wo die wahre Kunstfertigkeit stattfindet. Während der Vertex Shader sich um die Struktur deiner Objekte gekümmert hat, färbt der Fragment Shader sie ein.
Ein Einfacher Fragment Shader
Hier ist ein grundlegender Fragment Shader, der alles rot färbt:
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Dieser Shader setzt gl_FragColor
auf einen Vektor, der die Farbe Rot darstellt (volle Rot, keine Grün, keine Blau, volle Deckkraft). Es ist, als ob man seine ganze 3D-Welt in rote Farbe taucht!
Fragment Operationen: Die Letzten Touches
Nach dem Fragment Shader führt WebGL verschiedene Operationen auf den Fragmenten durch. Dies umfasst Tiefentests (bestimmt, welche Objekte vor anderen sind), Mischung (wie transparente Objekte interagieren) und mehr.
Frame Buffer: Das Gross Finale
Schliesslich erreichen wir den Frame Buffer. Dies ist, wo dein gerendertes Bild gespeichert wird, bevor es auf dem Bildschirm angezeigt wird. Es ist wie der Backstage-Bereich, wo die letzten Touches vor dem Vorhangaufgang angewendet werden.
Alles Zusammenfügen
Nun, da wir durch jede Stufe gegangen sind, sehen wir, wie sie alle in einem vollständigen WebGL-Programm zusammenarbeiten:
// Vertex Shader Quellcode
const vsSource = `
attribute vec4 aVertexPosition;
void main() {
gl_Position = aVertexPosition;
}
`;
// Fragment Shader Quellcode
const fsSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
// Initialisiere Shaders
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);
// Erstelle Shader-Programm
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
// Verwende das Programm
gl.useProgram(shaderProgram);
// Erstelle Buffer und übermittle Daten
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
1.0, 1.0,
-1.0, 1.0,
1.0, -1.0,
-1.0, -1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
// Sage WebGL, wie er die Positionen aus dem Position Buffer in das VertexPosition Attribut zieht
const numComponents = 2;
const type = gl.FLOAT;
const normalize = false;
const stride = 0;
const offset = 0;
gl.vertexAttribPointer(
gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(gl.getAttribLocation(shaderProgram, 'aVertexPosition'));
// Zeichne die Szene
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
Dieses Programm erstellt ein einfaches rotes Quadrat auf einem schwarzen Hintergrund. Lassen Sie es aufschlüsseln:
- Wir definieren unsere Vertex- und Fragment-Shaders.
- Wir kompilieren diese Shaders und verknüpfen sie in ein Programm.
- Wir erstellen einen Buffer mit den Positionen der Vertexen unseres Quadrats.
- Wir sagen WebGL, wie er diese Buffer-Daten interpretieren soll.
- Schliesslich bereinigen wir den Bildschirm und zeichnen unser Quadrat.
Jeder Schritt entspricht einer Stufe in der Grafik-Pipeline, die wir besprochen haben. Es ist, als ob man einer Produktionslinie zuschaut, wo Rohstoffe (Vertex-Daten) in ein fertiges Produkt (Pixel auf deinem Bildschirm) verwandelt werden.
Methoden Tabelle
Hier ist eine Tabelle der wichtigsten WebGL-Methoden, die wir verwendet haben:
Methode | Beschreibung |
---|---|
gl.createShader() |
Erstellt ein Shader-Objekt |
gl.shaderSource() |
Setzt den Quellcode eines Shaders |
gl.compileShader() |
Kompiliert einen Shader |
gl.createProgram() |
Erstellt ein Programm-Objekt |
gl.attachShader() |
Hängt einen Shader an ein Programm an |
gl.linkProgram() |
Verknüpft ein Programm-Objekt |
gl.useProgram() |
Setzt das angegebene Programm als Teil des aktuellen Render-Zustands |
gl.createBuffer() |
Erstellt ein Buffer-Objekt |
gl.bindBuffer() |
Bindet ein Buffer-Objekt an ein Ziel |
gl.bufferData() |
Erstellt und initialisiert den Daten Speicher eines Buffer-Objekts |
gl.vertexAttribPointer() |
Specifiziert die Anordnung der Vertex-Daten |
gl.enableVertexAttribArray() |
Aktiviert eine Vertex-Attribut-Anzeige |
gl.clearColor() |
Specifiziert die Farbe, die verwendet wird, um Farb-Buffer zu bereinigen |
gl.clear() |
Bereinigt Buffer zu voreingestellten Werten |
gl.drawArrays() |
Render_primitive aus Array-Daten |
Und das ist es! Wir sind durch die WebGL Grafik-Pipeline gereist, von JavaScript bis zum finalen Frame Buffer. Denke daran, dass das Beherrschen von WebGL wie jede andere Fähigkeit Übung erfordert. Aber mit jeder Zeile Code, die du schreibst, kommst du näher, um erstaunliche 3D-Grafiken in deinem Web-Browser zu erstellen. Weiter experimentieren, weiter lernen und vor allem: Spass haben!
Credits: Image by storyset