La Grande Vague de Kanagawa

Katsushika Hokusai - 1831 retour

Modèle

x y z

Originale

Oeuvre d'art nommée The Great Wave off Kanagawa

Explications Techniques

Utilisation de Three.js pour faire un modèle 3D d'une œuvre d'art.
Pour des raisons de performances le maximum de variables ect... ont été précalculé ce qui permet d'avoir une scène très fluide.
De plus les textures ont des côtés ^2 pour permettre un chargement plus rapide
Possiblité de faire apparaitre les axes avec le panel en haut a droite (la légende apparaîtra aussi).
J'utilise dat.gui pour laisser la posibilité de modifier des parties de l'œuvre et stat.min pour avoir les fps et montrer que le programme est bien optimisé.
Il y a énormément d'option disponible dans le gui avec par exemple dans le dossier settings la possibilité de passer la sscène en plein écran.
L'œuvre est éclairé par une lumière directionnelle sombre venant de l'axe Z elle permet entre autres de créer le relief des bateaux.
La montagne est faite avec deux THREE.CylinderGeometry. Une la montagne et l'autre la neige, la neige est en material basic pour pas ne pas avoir la noirceur de la lumière et bien ressortir.
Les bateaux sont un OBJ avec un material lambert ils sont placés très simplement à l'aide d'une fonction create_boat(x, z, rx, ry, rz) qui permet l'ajout rapide et simple.

Pour la génération de la vague j'utilise un BufferGeometry avec une suite de points qui va dessiner les triangles.
Je calcule la hauteur de ses points à l'aide d'un sin() et d'autres paramètres pour avoir l'effet de courbe montante descendante.
Je dessine donc 2 triangles inversés pour faire une forme pleine sur le haut et de même sur les différents côtés en faisant attention à la visibilité
(Et donc de l'ordre des points).
Quant à la réalisation de la partie blanche de la vague la première étape consiste à retrouver le sommet pour ce faire quand je calcule le y de la vague je vérifie si on n'a x2 < x1 > x, cela signifie qu'on est au haut de la vague et j'y appelle donc white_part_wave(x).
Une fois la zone déterminée je recrée la même forme que la vague sur la partie haute de la vague (je peux déterminer la taille a l'aide de la fréquence). Je positionne cette nouvelle formée légèrement plus haute pour qu'elle soit visible.
Quelques modifications sont aussi effectuées un décalage des UV est effectués aux extrémités de la vague pour que la texture ne parte pas d'un coup mais progressivement pour un effet naturel

Pour adapter les bateaux à la vague j'utilise la relation de Chasles pour déterminer la hauteur sur la vague qui est en pente.
Je calcule deux points assez éloignés du bateau pour déterminer la pente a s'adapter
Une fois les deux points calculés, on détermine leur y (hauteur) de la même manière que pour les vagues et on utilise Chasles pour les remettre par rapport à la pente.
Ensuite avec les deux points de l'extrémité de là où devrait être le bateau on peut déterminer un 3ᵉme points en prenant le x de pt1 et l'y de pt2 ce qui donne un triangle rectangle
Dans ce triangle on connaît l'adjacent et l'opposée on peut donc utiliser tangente(x) = opposée / adjacente. Ce qui nous donnera l'angle de rotation à appliquer. Pour faire tourner l'OBJ je fais une rotation selon l'axe (1,0,0).
Pour les prochaines animations je refais cette même rotation, mais en sens inverse pour préserver l'OBJ et ne pas à avoir à le refaire à chaque animation.

La skybox est faite à l'aide d'une image de ciel recoloriez par mes soins dans les couleurs de l'œuvre et découpé et redimensionné à l'aide de GIMP.
Quant aux animations le fichier reset remet simplement aux valeurs par défaut. L'option Wave règle simplement une variable qui sert de fréquence à la fonction sin pour les vagues. Quant au Live mode celui-ci se charge simplement d'incrémenter un x dans notre sin ce qui va nous faire parcourir la courbe sin, la valeur speed est la valeur d'incrément par tour du x.
Pour le mode aventure je place seulement la caméra sur le bateau à l'aide des mêmes méthodes utilisées que pour placer le bateau et j'adapte le target du CameraControls pour que la caméra suit l'angle du bateau.
Je change aussi la fov pendant le mode aventure pour avoir une meilleure immersion. Et de plus j'ajoute un brouillard de type Exp2 pour plus de réalisme

Pour appliquer la texture, je calcule à l'initialisation les valeurs des UV correspondant à ma texture de ce fait, il n'y a quasiment aucune perte de temps au runtime, et la texture épouse parfaitement la forme de la vague. Pour donner un aspect de vague je vais jouer sur l'offset de la texture je vais l'incrémenter en X de la valeur speed de la vague.
Comme cela la texture va aussi vite que les vagues en mode run ce qui ajoute du réalisme.
Pour gérer les offset, j'utilise deux Tweening qui permettront de gérer l'offset en Z de la vague et de la partie blanche de la vague.

Pour faire des particules d'eau, j'utilise des Sprites que je vais ajouter dans la scène quand le sommet d'une vague apparaît (tout début), pour leur donner un aspect visuel, j'applique une texture transparente récupérer sur le tableau original. Je vais ensuite dans un intervalle de valeur aux alentours de la vague placer aléatoirement un nombre de Sprite
À chaque itération je vais leur appliquer un décalage dans l'axe x pour suivre la vitesse de la vague ensuite pour donner un aspect de gravité sur la particule qui tombe de plus en plus vite.
J'utilise l'allure de la courbe 1/x qui correspond au comportement de la gravité au niveau des particules pour modifier l'axe Y et avoir une particule qui descend légèrement au début jusqu'à tomber extrêmement vite dans le temps
J'ajoute une constante k qui sera incrémenté de ce fait au début la particule monte légèrement ce qui lui donne un effet de propulsion par la vague

Pour pouvoir faire bouger les bateaux avec le drag j'utilise EventsControls je bloque la caméra quand on drag en la posant à ses dernières positions et j'adapte avec la fonction updateBoatWave().
J'ai aussi amélioré les coordinates en fournissant ma propre version pour pouvoir afficher les axes et les retirer sans avoir besoin de redessiner la scène


linkedin | ARIES Lucas | github