WebGL - Rotazione del Cubo
Ciao a tutti, futuri maghi di WebGL! Oggi ci imbarchiamo in un viaggio emozionante nel mondo della grafica 3D. Alla fine di questo tutorial, sarete in grado di creare un cubo rotante utilizzando WebGL. Non è fantastico? Tuffiamoci dentro!
Comprensione delle Basi
Prima di iniziare a far girare i cubi come un DJ, cerchiamo di capire alcuni concetti fondamentali.
Cos'è WebGL?
WebGL (Web Graphics Library) è una API JavaScript che ci permette di rendere grafica 3D in un browser web. È come dare al tuo browser un paio di occhiali 3D!
Perché un Cubo?
Potresti chiederti, "Perché stiamo iniziando con un cubo?" Bene, miei cari studenti, un cubo è come il "Hello World" della grafica 3D. È semplice abbastanza da comprendere ma complesso abbastanza per insegnarci concetti importanti. E chi non adora un buon cubo?
Configurazione del Nostro Ambiente WebGL
Il Canvas HTML
Prima di tutto, abbiamo bisogno di un palco per il nostro cubo per esibirsi. In WebGL, questo palco si chiama canvas. Impostiamolo:
<canvas id="glcanvas" width="640" height="480">
Il tuo browser non supporta HTML5 canvas
</canvas>
Questo crea un canvas di 640x480 pixel. Se non lo vedi, non preoccuparti - è come un'inedibile pista da ballo in questo momento.
Inizializzazione di WebGL
Ora, prepariamo WebGL per la festa:
var canvas = document.getElementById('glcanvas');
var gl = canvas.getContext('webgl');
if (!gl) {
console.log('WebGL non supportato, ripiego su experimental-webgl');
gl = canvas.getContext('experimental-webgl');
}
if (!gl) {
alert('Il tuo browser non supporta WebGL');
}
Questo codice ottiene il nostro contesto WebGL. Se il tuo browser non supporta WebGL, è come cercare di giocare un DVD su un lettore VHS - semplicemente non funzionerà!
Creazione del Nostro Cubo 3D
Definizione dei Vertici
Un cubo ha 8 angoli (vertici). Dobbiamo dire a WebGL dove questi angoli sono:
var vertices = [
// Facce frontale
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// Facce posteriore
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// Facce superiore
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
1.0, 1.0, 1.0,
1.0, 1.0, -1.0,
// Facce inferiore
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
// Facce destra
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// Facce sinistra
-1.0, -1.0, -1.0,
-1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
];
Ogni tripletta di numeri rappresenta un angolo del nostro cubo nello spazio 3D. È come dare a WebGL una mappa del nostro cubo!
Creazione del Buffer
Ora dobbiamo inviare questi dati alla GPU:
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
Questo è come mettiamo il nostro cubo in una valigia (buffer) e lo inviamo alla GPU.
Shader - I Maghi di WebGL
Vertex Shader
Il vertex shader posiziona i nostri vertici:
var vertexShaderSource = `
attribute vec3 aVertexPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);
}
`;
Questo shader prende ogni vertice e applica le nostre matrici di trasformazione. È come un mago che muove gli angoli del nostro cubo!
Fragment Shader
Il fragment shader colora il nostro cubo:
var fragmentShaderSource = `
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
`;
Questo semplice shader colora tutto bianco. È come verniciare il nostro cubo!
Compilazione e Collegamento degli Shader
Ora dobbiamo compilare i nostri shader e collegarli in un programma:
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('Si è verificato un errore durante la compilazione degli shader: ' + 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('Impossibile inizializzare il programma degli shader: ' + gl.getProgramInfoLog(shaderProgram));
}
gl.useProgram(shaderProgram);
Questo è come insegniamo ai nostri maghi (shader) i loro trucchi e li mettiamo sul palco!
Far Girare il Nostro Cubo
Impostazione della Rotazione
Per far girare il nostro cubo, dobbiamo aggiornare l'angolo di rotazione nel tempo:
var cubeRotation = 0.0;
var then = 0;
function render(now) {
now *= 0.001; // convert to seconds
const deltaTime = now - then;
then = now;
cubeRotation += deltaTime;
drawScene();
requestAnimationFrame(render);
}
Questa funzione viene chiamata ripetutamente, aggiornando la rotazione del nostro cubo ogni volta.
Disegno della Scena
Ora mettiamo tutto insieme e disegniamo il nostro cubo rotante:
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);
}
Questa funzione pulisce il canvas, imposta la nostra prospettiva, applica la nostra rotazione e infine disegna il nostro cubo.
Conclusione
Eccoci, ragazzi! Abbiamo creato un cubo 3D rotante utilizzando WebGL. Ricorda, padroneggiare WebGL è come imparare a gjuggare - richiede pratica, ma una volta che lo fai, puoi fare cose incredibili!
Ecco una tabella che riassume i principali metodi che abbiamo utilizzato:
Metodo | Descrizione |
---|---|
gl.createBuffer() |
Crea un nuovo oggetto buffer |
gl.bindBuffer() |
Associa un oggetto buffer a un target |
gl.bufferData() |
Crea e inizializza il deposito dati di un oggetto buffer |
gl.createShader() |
Crea un oggetto shader |
gl.shaderSource() |
Imposta il codice sorgente di un oggetto shader |
gl.compileShader() |
Compila un oggetto shader |
gl.createProgram() |
Crea un oggetto programma |
gl.attachShader() |
Associa un oggetto shader a un oggetto programma |
gl.linkProgram() |
Collega un oggetto programma |
gl.useProgram() |
Imposta l'oggetto programma come parte dello stato di rendering corrente |
gl.clear() |
Pulisce i buffer a valori predefiniti |
gl.uniformMatrix4fv() |
Specifica il valore di una variabile uniforme per l'oggetto programma corrente |
gl.drawArrays() |
Rende primitivi da dati array |
Continua a praticare, continua a codificare e presto creerai grafica 3D incredibile nel tuo browser. Buon coding!
Credits: Image by storyset