WebGL - Rotation de Cube

Salut à toi, futurs magiciens de WebGL ! Aujourd'hui, nous allons entreprendre un voyage passionnant dans le monde de la graphique 3D. D'ici la fin de ce tutoriel, vous serez capable de créer un cube tournant en utilisant WebGL. Ça ne vous tente pas ? C'est parti !

WebGL - Cube Rotation

Comprendre les Bases

Avant de faire tourner des cubes comme un DJ, penchons-nous sur quelques concepts fondamentaux.

Qu'est-ce que WebGL ?

WebGL (Web Graphics Library) est une API JavaScript qui nous permet de rendre des graphiques 3D dans un navigateur web. C'est comme donner à votre navigateur une paire de lunettes 3D !

Pourquoi un Cube ?

Vous vous demandez peut-être, "Pourquoi commencer par un cube ?" Eh bien, mes chers élèves, un cube est comme le "Hello World" de la graphique 3D. Il est suffisamment simple pour être compris mais suffisamment complexe pour nous enseigner des concepts importants. Et qui n'aime pas un bon cube ?

Préparer Notre Environnement WebGL

Le Canvas HTML

Premières choses premières, nous avons besoin d'une scène pour que notre cube puisse se produire. Dans WebGL, cette scène s'appelle un canvas. Mettons-le en place :

<canvas id="glcanvas" width="640" height="480">
Votre navigateur ne supporte pas le canvas HTML5
</canvas>

Cela crée un canvas de 640x480 pixels. Si vous ne le voyez pas, ne vous inquiétez pas - c'est comme une piste de danse invisible pour le moment.

Initialiser WebGL

Maintenant, mettons WebGL prêt à la fête :

var canvas = document.getElementById('glcanvas');
var gl = canvas.getContext('webgl');

if (!gl) {
console.log('WebGL non supporté, recours à experimental-webgl');
gl = canvas.getContext('experimental-webgl');
}

if (!gl) {
alert('Votre navigateur ne supporte pas WebGL');
}

Ce code obtenir notre contexte WebGL. Si votre navigateur ne supporte pas WebGL, c'est comme essayer de lire un DVD sur un lecteur VHS - ça ne marchera tout simplement pas !

Créer Notre Cube 3D

Définir les Vertices

Un cube a 8 coins (vertices). Nous devons dire à WebGL où ces coins se trouvent :

var vertices = [
// Face avant
-1.0, -1.0,  1.0,
1.0, -1.0,  1.0,
1.0,  1.0,  1.0,
-1.0,  1.0,  1.0,

// Face arrière
-1.0, -1.0, -1.0,
-1.0,  1.0, -1.0,
1.0,  1.0, -1.0,
1.0, -1.0, -1.0,

// Face supérieure
-1.0,  1.0, -1.0,
-1.0,  1.0,  1.0,
1.0,  1.0,  1.0,
1.0,  1.0, -1.0,

// Face inférieure
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0,  1.0,
-1.0, -1.0,  1.0,

// Face droite
1.0, -1.0, -1.0,
1.0,  1.0, -1.0,
1.0,  1.0,  1.0,
1.0, -1.0,  1.0,

// Face gauche
-1.0, -1.0, -1.0,
-1.0, -1.0,  1.0,
-1.0,  1.0,  1.0,
-1.0,  1.0, -1.0
];

Chaque ensemble de trois nombres représente un coin de notre cube dans l'espace 3D. C'est comme donner à WebGL une carte de notre cube !

Créer le Buffer

Maintenant, nous devons envoyer ces données au GPU :

var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

C'est comme emballer notre cube dans une valise (buffer) et l'envoyer au GPU.

Les Shaders - Les Magiciens de WebGL

Shader de Vertex

Le shader de vertex positionne nos vertices :

var vertexShaderSource = `
attribute vec3 aVertexPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);
}
`;

Ce shader prend chaque vertex et applique nos matrices de transformation. C'est comme un magicien déplaçant les coins de notre cube !

Shader de Fragment

Le shader de fragment colore notre cube :

var fragmentShaderSource = `
void main(void) {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
`;

Ce simple shader colore tout en blanc. C'est comme peindre notre cube !

Compiler et Lier les Shaders

Maintenant, nous devons compiler nos shaders et les lier en un programme :

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('Une erreur est survenue lors de la compilation des shaders : ' + 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('Impossible d\'initialiser le programme des shaders : ' + gl.getProgramInfoLog(shaderProgram));
}

gl.useProgram(shaderProgram);

C'est comme enseigner à nos magiciens (shaders) leurs tours et puis les mettre sur scène !

Faire Tourner Notre Cube

Préparer la Rotation

Pour faire tourner notre cube, nous devons mettre à jour son angle de rotation au fil du temps :

var cubeRotation = 0.0;

function render(now) {
now *= 0.001;  // convertir en secondes
const deltaTime = now - then;
then = now;

cubeRotation += deltaTime;

drawScene();

requestAnimationFrame(render);
}

Cette fonction est appelée à plusieurs reprises, mettant à jour la rotation de notre cube à chaque fois.

Dessiner la Scène

Mettons tout ensemble et dessinons notre cube tournant :

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);
}

Cette fonction efface le canvas, configure notre perspective, applique notre rotation, et finalement dessine notre cube.

Conclusion

Et voilà, les amis ! Nous avons créé un cube 3D tournant en utilisant WebGL. Souvenez-vous, maîtriser WebGL est comme apprendre à jongler - cela nécessite de la pratique, mais une fois que vous l'avez, vous pouvez faire des choses incroyables !

Voici un tableau résumant les principales méthodes que nous avons utilisées :

Méthode Description
gl.createBuffer() Crée un nouvel objet buffer
gl.bindBuffer() Lie un objet buffer à une cible
gl.bufferData() Crée et Initialise le magasin de données d'un objet buffer
gl.createShader() Crée un objet shader
gl.shaderSource() Définit le code source d'un objet shader
gl.compileShader() Compile un objet shader
gl.createProgram() Crée un objet programme
gl.attachShader() Attache un objet shader à un objet programme
gl.linkProgram() Lie un objet programme
gl.useProgram() Définit l'objet programme comme faisant partie de l'état de rendu actuel
gl.clear() Efface les buffers à des valeurs prédéfinies
gl.uniformMatrix4fv() Spécifie la valeur d'une variable uniforme pour l'objet programme actuel
gl.drawArrays() Rend des primitives à partir des données d'array

Continuez à pratiquer, continuez à coder, et bientôt vous créerez des graphiques 3D incroyables dans votre navigateur. Bon codage !

Credits: Image by storyset