WebGL - Translation: Moving Objects in 3D Space

Bonjour, futurs développeurs WebGL ! Aujourd'hui, nous allons entreprendre un voyage passionnant dans le monde de la graphique 3D. Nous allons explorer le concept de translation dans WebGL, ce qui revient essentiellement à dire "bouger des choses". D'ici la fin de ce tutoriel, vous serez capables de faire danser des objets sur votre écran comme un ballet numérique ! Alors, plongeons dedans !

WebGL - Translation

Qu'est-ce que la Translation dans WebGL ?

Avant de commencer à déplacer des triangles comme des pièces d'échecs, comprenons ce que signifie réellement la translation dans le contexte de la graphique informatique.

Les Bases de la Translation

La translation est le processus de déplacement d'un objet d'une position à une autre dans un espace 2D ou 3D. C'est comme prendre une tasse de votre bureau et la placer sur une étagère. La tasse (notre objet) a déplacée de sa position initiale à une nouvelle.

Dans WebGL, nous utilisons des mathématiques pour réaliser ce mouvement. Ne vous inquiétez pas si vous n'êtes pas un as en mathématiques - WebGL fait la plupart du travail lourd pour nous !

Pourquoi la Translation est-elle Importante ?

Imaginez un jeu vidéo où les personnages ne pourraient pas bouger, ou un logiciel de modélisation 3D où les objets seraient figés en place. Pretty boring, non ? La translation nous permet de créer des graphiques dynamiques et interactifs qui réagissent aux entrées utilisateur ou suivent des animations prédéfinies.

Étapes pour Traduire un Triangle

Maintenant que nous comprenons ce qu'est la translation, analysons le processus de déplacement d'un triangle simple dans WebGL. Nous allons le faire étape par étape pour que vous puissiez suivre facilement.

Étape 1 : Définir Votre Triangle

Premièrement, nous devons créer notre triangle. Dans WebGL, nous définissons les formes en utilisant des sommets (points d'angle). Voici comment nous pourrions définir un triangle simple :

const vertices = [
0.0, 0.5,   // Sommet supérieur
-0.5, -0.5,  // Sommet inférieur gauche
0.5, -0.5   // Sommet inférieur droit
];

Cela crée un triangle avec son point supérieur à (0, 0.5) et ses coins de base à (-0.5, -0.5) et (0.5, -0.5).

Étape 2 : Créer une Matrice de Translation

Pour déplacer notre triangle, nous devons créer une matrice de translation. Cette matrice indique à WebGL combien déplacer notre objet le long de chaque axe (x, y, et z). Voici comment nous créons une matrice de translation :

const translationMatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
tx, ty, 0, 1
];

tx et ty sont les quantités que nous voulons déplacer le long des axes x et y respectivement.

Étape 3 : Appliquer la Translation dans le Shader de Vertex

Maintenant vient la partie passionnante ! Nous devons modifier notre shader de vertex pour appliquer la translation. Voici un shader de vertex simple qui inclut la translation :

attribute vec2 a_position;
uniform mat4 u_translation;

void main() {
gl_Position = u_translation * vec4(a_position, 0, 1);
}

Ce shader prend chaque position de sommet, la convertit en vecteur 4D (nécessaire pour la multiplication de matrices), puis le multiplie par notre matrice de translation.

Étape 4 : Mettre à Jour les Valeurs de Translation

Pour faire bouger notre triangle, nous devons mettre à jour les valeurs de translation au fil du temps. Nous pouvons le faire dans notre code JavaScript :

function updateAndDraw() {
tx += 0.01;  // Se déplacer à droite
ty += 0.005; // Se déplacer vers le haut

// Mettre à jour la matrice de translation
gl.uniformMatrix4fv(translationLocation, false, translationMatrix);

// Dessiner le triangle
gl.drawArrays(gl.TRIANGLES, 0, 3);

requestAnimationFrame(updateAndDraw);
}

Cette fonction met à jour nos valeurs de translation, envoie la nouvelle matrice à la GPU, et redessine notre triangle. L'appel requestAnimationFrame assure que cela se produit en douceur, image par image.

Exemple – Traduire un Triangle

Mettons tout ensemble avec un exemple complet. Ce code va créer un triangle qui se déplace diagonalement à travers l'écran :

// Shader de vertex
const vertexShaderSource = `
attribute vec2 a_position;
uniform mat4 u_translation;

void main() {
gl_Position = u_translation * vec4(a_position, 0, 1);
}
`;

// Shader de fragment
const fragmentShaderSource = `
precision mediump float;

void main() {
gl_FragColor = vec4(1, 0, 0, 1);  // Couleur rouge
}
`;

// Initialiser WebGL
const canvas = document.getElementById('glcanvas');
const gl = canvas.getContext('webgl');

// Créer et compiler les shaders
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);

const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);

// Créer le programme
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);

// Créer le tampon et charger les données des sommets
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
const positions = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

// Configurer l'attribut
const positionAttributeLocation = gl.getAttribLocation(program, "a_position");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

// Configurer l'uniforme
const translationLocation = gl.getUniformLocation(program, "u_translation");

// Variables de translation
let tx = 0;
let ty = 0;

function updateAndDraw() {
// Effacer le canvas
gl.clear(gl.COLOR_BUFFER_BIT);

// Mettre à jour la translation
tx += 0.01;
ty += 0.005;

// Créer la matrice de translation
const translationMatrix = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
tx, ty, 0, 1
];

// Envoyer la matrice au shader
gl.uniformMatrix4fv(translationLocation, false, translationMatrix);

// Dessiner
gl.drawArrays(gl.TRIANGLES, 0, 3);

// Demander la prochaine image
requestAnimationFrame(updateAndDraw);
}

// Démarrer l'animation
updateAndDraw();

Ce code crée un triangle rouge qui se déplace diagonalement à travers l'écran. Voici un résumé de ce qui se passe :

  1. Nous définissons nos shaders, qui incluent la matrice de translation.
  2. Nous configurons WebGL, créons notre programme, et chargeons nos sommets du triangle.
  3. Nous créons des variables pour notre translation (tx et ty).
  4. Dans notre fonction updateAndDraw, nous :
  • Effaçons le canvas
  • Mettons à jour nos valeurs de translation
  • Créons une nouvelle matrice de translation
  • Envoyons cette matrice à la GPU
  • Dessinons notre triangle
  • Demandons la prochaine image d'animation

Et voilà ! Vous avez créé un triangle en mouvement dans WebGL. Félicitations !

Conclusion

La translation dans WebGL peut sembler complexe au départ, mais c'est vraiment juste une question de déplacement d'objets de manière intelligente. Nous avons couvert les bases ici, mais il y a tellement plus que vous pouvez faire avec la translation - combinez-la avec la rotation et l'échelle, créez des animations complexes, ou même construisez des environnements 3D interactifs.

Souvenez-vous, chaque voyage commence par un seul pas - ou dans notre cas, un seul déplacement de triangle. Continuez à pratiquer, continuez à expérimenter, et avant de vous en rendre compte, vous créerez des graphiques 3D qui se déplacent et interagissent de manières que vous n'auriez jamais imaginées.

Bonne programmation, et puissent vos triangles toujours trouver leur chemin à la maison !

Credits: Image by storyset