WebGL - Farben: Ein Anfängerleitfaden zum Leben in Ihren 3D-Grafiken hinzufügen
Hallo da drüben, angehende WebGL-Enthusiasten! Ich freue mich sehr, Ihr Guide auf dieser bunten Reise durch die Welt von WebGL zu sein. Als jemand, der seit über einem Jahrzehnt Computergrafik unterrichtet, kann ich Ihnen sagen, dass das Hinzufügen von Farben zu Ihren 3D-Szenen wie das Leben in ein Schwarzweiß-Foto zu bringen ist. Es ist magisch, und heute werden wir diese Magie gemeinsam entdecken!
Farben in WebGL verstehen
Bevor wir uns den Details des Anwendens von Farben widmen, lassen Sie uns einen Moment innehalten, um zu verstehen, was Farben im Kontext von WebGL bedeuten. In dieser digitalen Welt werden Farben mit dem RGB-(Rot, Grün, Blau)-Farbmodell dargestellt. Jede Farbe ist eine Kombination dieser drei Primärfarben, mit Werten zwischen 0.0 und 1.0.
Zum Beispiel:
- Rot: (1.0, 0.0, 0.0)
- Grün: (0.0, 1.0, 0.0)
- Blau: (0.0, 0.0, 1.0)
- Weiß: (1.0, 1.0, 1.0)
- Schwarz: (0.0, 0.0, 0.0)
Denken Sie daran wie das Mischen von Farben, aber mit Licht anstelle von Pigmenten. Es ist ein bisschen so, als wäre man ein digitaler Künstler mit einer unendlichen Palette an Ihren Fingertippen!
Farben in WebGL anwenden
Nun, da wir die Grundlagen verstehen, lassen Sie uns die Hände schmutzig (oder sollte ich sagen, bunt?) machen und Farben in WebGL anwenden.
Schritte zum Anwenden von Farben
- Definieren Sie Farbattribute in Ihrem Vertex-Shader
- Übertragen Sie Farbdaten aus Ihrem JavaScript-Code
- Verwenden Sie die Farbe in Ihrem Fragment-Shader
Lassen Sie uns diese Schritte mit einigen Codebeispielen durchgehen.
Schritt 1: Farbattribute im Vertex-Shader definieren
Zuerst müssen wir unserem Vertex-Shader mitteilen, dass wir mit Farben arbeiten werden. So machen wir das:
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
gl_Position = a_Position;
v_Color = a_Color;
}
In diesem Code definieren wir ein Attribut a_Color
, um Farbdaten zu empfangen, und eine veränderliche Variable v_Color
, um die Farbe an den Fragment-Shader zu übermitteln. Es ist, als würden wir eine Farbleitung von unserem JavaScript-Code bis zu unseren Pixeln einrichten!
Schritt 2: Farbdaten aus JavaScript übertragen
Nun müssen wir die Farbdaten aus unserem JavaScript-Code an den Shader übermitteln. Hier ist ein Beispiel, wie wir das tun könnten:
// Definieren von Eckpunkten und Farben
var vertices = new Float32Array([
0.0, 0.5, 1.0, 0.0, 0.0, // Vertex 1: x, y, r, g, b
-0.5,-0.5, 0.0, 1.0, 0.0, // Vertex 2: x, y, r, g, b
0.5,-0.5, 0.0, 0.0, 1.0 // Vertex 3: x, y, r, g, b
]);
// Erstellen eines Puffers und Übermitteln der Daten an ihn
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
//.tell WebGL, wie der Puffer gelesen werden soll
var FSIZE = vertices.BYTES_PER_ELEMENT;
var a_Position = gl.getAttribLocation(program, 'a_Position');
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 5, 0);
gl.enableVertexAttribArray(a_Position);
var a_Color = gl.getAttribLocation(program, 'a_Color');
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2);
gl.enableVertexAttribArray(a_Color);
Dieser Code mag initially einschüchternd erscheinen, aber lassen Sie uns ihn aufschlüsseln:
- Wir definieren unsere Eckpunkte und Farben in einer einzigen Array. Jeder Eckpunkt hat 5 Werte: x, y, r, g, b.
- Wir erstellen einen Puffer und übermitteln unsere Daten an ihn.
- Wir告诉WebGL, wie dieser Puffer für Position (erste 2 Werte) und Farbe (letzte 3 Werte) gelesen werden soll.
Es ist, als würde man einen Koffer mit Kleidung und Toilettenartikeln packen und dann seinem Freund genau sagen, wie er ihn auspacken soll!
Schritt 3: Farbe im Fragment-Shader verwenden
Schließlich verwenden wir die Farbe in unserem Fragment-Shader:
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
Dieser einfache Shader nimmt die Farbe, die wir vom Vertex-Shader übermittelt haben, und wendet sie auf unseren Fragment (Pixel) an. Es ist der letzte Schritt in unserer Farbreise, wo die Farbe schließlich auf dem Bildschirm erstrahlt!
Beispiel – Farbe anwenden
Lassen Sie uns alles zusammenbringen mit einem vollständigen Beispiel. Wir erstellen ein buntes Dreieck mit dem Code, den wir besprochen haben.
<!DOCTYPE html>
<html>
<head>
<title>Buntes WebGL-Dreieck</title>
</head>
<body>
<canvas id="glCanvas" width="640" height="480"></canvas>
<script>
// Vertex-Shader-Programm
const vsSource = `
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
gl_Position = a_Position;
v_Color = a_Color;
}
`;
// Fragment-Shader-Programm
const fsSource = `
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
`;
function main() {
const canvas = document.querySelector("#glCanvas");
const gl = canvas.getContext("webgl");
if (!gl) {
alert("Unable to initialize WebGL. Your browser or machine may not support it.");
return;
}
// Initialisieren eines Shader-Programms
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
// Abrufen der Attributionsorte
const programInfo = {
program: shaderProgram,
attribLocations: {
vertexPosition: gl.getAttribLocation(shaderProgram, 'a_Position'),
vertexColor: gl.getAttribLocation(shaderProgram, 'a_Color'),
},
};
// Erstellen des Puffers
const buffers = initBuffers(gl);
// Zeichnen der Szene
drawScene(gl, programInfo, buffers);
}
function initBuffers(gl) {
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
0.0, 0.5, 1.0, 0.0, 0.0,
-0.5, -0.5, 0.0, 1.0, 0.0,
0.5, -0.5, 0.0, 0.0, 1.0,
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
return {
position: positionBuffer,
};
}
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);
{
const numComponents = 2; // 2 Werte pro Iteration abrufen
const type = gl.FLOAT; // Die Daten im Puffer sind 32-Bit-Floater
const normalize = false; // nicht normalisieren
const stride = 20; // Wie viele Bytes von einem Wertensatz zum nächsten
const offset = 0; // Wie viele Bytes im Puffer, um zu beginnen
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);
gl.vertexAttribPointer(
programInfo.attribLocations.vertexPosition,
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(
programInfo.attribLocations.vertexPosition);
}
{
const numComponents = 3;
const type = gl.FLOAT;
const normalize = false;
const stride = 20;
const offset = 8;
gl.vertexAttribPointer(
programInfo.attribLocations.vertexColor,
numComponents,
type,
normalize,
stride,
offset);
gl.enableVertexAttribArray(
programInfo.attribLocations.vertexColor);
}
gl.drawArrays(gl.TRIANGLES, 0, 3);
}
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;
}
window.onload = main;
</script>
</body>
</html>
Wenn Sie diesen Code ausführen, werden Sie ein schönes Dreieck mit roten, grünen und blauen Eckpunkten sehen. Es ist, als würde ein Regenbogen auf Ihrem Bildschirm zum Leben erweckt werden!
Schlussfolgerung
Und da haben Sie es, Leute! Wir haben die farbenfrohe Welt von WebGL durchquert, von der Darstellung von Farben bis hin zu deren Anwendung in unseren 3D-Grafiken. Denken Sie daran, das ist erst der Anfang. Mit diesen Grundlagen sind Sie gut auf dem Weg, um atemberaubende, lebendige 3D-Grafiken zu erstellen.
Als wir uns verabschieden, erinnere ich mich an einen Schüler, der mir einmal sagte, dass das Lernen von WebGL-Farben wie das Malen mit Licht ist. Und Sie wissen was? Er hatte完全权利. Also, meine lieben Schüler, gehen Sie hinaus und malen Sie Ihre digitalen Leinwände mit allen Farben des Windes (ja, das ist ein Disney-Verweis, und nein, ich bin nicht schamhaft darum).
Frohes Coden und möge Ihre WebGL-Abenteuer immer farbenfroh sein!
Credits: Image by storyset