{"pageProps":{"posts":[{"content":"\n\n
\n\nDe plus en plus, la 3D pour le web devient une nouvelle tendance dans le webdesign. N'étant pas très utilisée dans les sites dits \"classique\", elle permet de se démarquer en proposant des expériences interactives allant jusqu’à la création de petits jeux vidéos.\n\n## LES DIFFÉRENTES FAÇONS DE CRÉER SON SITE INTERNET EN 3D\n\nDepuis 2011, la majorité des navigateurs utilise l’interface **webgl** (codée en Javascript et issue de OPENGL) pour intégrer de la 3D en **HTML**. Cependant, coder un site en webgl peut s’avérer complexe. C’est pourquoi différents logiciels, **frameworks** et **librairies** ont vu le jour pour faciliter l’intégration en 3D.\n\n\n## Le plus complet : Three.js\n\n![Three.js exemple](/img/3d-web/threeJsOpti.jpg)\n\nThree.js est une librairie codée en Javascript (**WebGL**). Il est **open source** et gratuit et la doc est claire et intuitive.\n\nThree.js a de bonnes performances et permet de simplifier la création de scènes 3D. Il permet de créer des expériences interactives. Il permet alors de faire des animations, d’intégrer des systèmes de light et de **shading** assez complets ainsi que d’importer d’autres moteurs de rendus physiques par exemple Cannon.js ou ammo.js.
\nIl est également possible de créer des petits jeux vidéos.\nBeaucoup de sites réalisés en three.js sont classés comme meilleurs sites sur Awwards.\nDes exemples de sites créés en three.js sont consultables sur la doc: threejs.\n\n\n\n### Des frameworks utilisant Three.js :\n* react-three-fiber\n* https://aframe.io/\n* https://spline.design/\n* Whitestorm.js\n\n\n#### Dans le même principe : Babylon.js\n\n\nBabylon.js est similaire à Three.js, la principale différence est que celui-ci est codé en Typescript. Voici un article qui vous fait un bon comparatif des 2 bibliothèques.\n\nComparatif Three.js & Babylon.js\n\n## Le moteur de jeu pour le web : Playcanvas\n\"PlayCanvas\n\nPlayCanvas est un logiciel en ligne codé en Javascript (**WebGL**) spécifique pour créer des jeux vidéo pour le web. Il est open source mais la plateforme en ligne est payante. Après 1GB de stockage gratuit, il faut payer 15$/ mois pour l’offre personnelle et 50$/mois pour les organisations. Son avantage est qu’il est disponible sur tous les navigateurs. La différence avec three.js est qu’il est possible d’utiliser dans Playcanvas une interface graphique pour aider à créer la scène 3D alors que dans three.js il faut tout faire soi-même. Cette interface graphique permet notamment la collaboration en temps réel, cela facilite donc le travail en équipe.\n\n\n### * Notabene unity & unreal *\nIl existe des moteurs de jeux spécifiques pour les jeux vidéos autres que le web (pc, playstation, téléphone mobile etc) comme Unity et Unreal Engine.\nMais ces moteurs peuvent quand même permettre d’exporter les jeux en webgl, et donc pour le web. Cependant, il peut y avoir des soucis de compatibilité, des limitations et des temps de chargement très conséquents.\n\nLien d’un tuto youtube : Export Unity Games to WebGL and Upload them to the Web
\nLien d’un tuto youtube : Unreal Engine 4 on Web Browser is AMAZING!
\n\n## Pour les non dev mais artistes 3D : **Blend4Web**, **Verge 3D**.\n\n\nPour ceux qui ne codent pas, il existe des outils pour tout de même créer son site en 3D.\n\n\"Blend4Web\n\nTout d’abord, **Blend4Web** est un plugging du logiciel Blender qui permet d’exporter les scènes 3D créées directement sur le web. L’outil est sous licence GPL, ce qui signifie qu’il est gratuit pour l’usage personnel mais payant pour le commerce.\nTout comme **Evee**, Blend4Web agit comme moteur de rendu en temps réel et permet donc de visualiser son rendu directement dans le navigateur (et non pas sur Blender) avant de l’exporter par la suite en **HTML** ou en **JSON**.\n
\nAvec Blend4web, on peut également créer des interactions simples avec l’utilisateur grâce à un node Editor.\nIl n’est par contre pas possible d’aller jusqu’à la création d’interactions complexes ou de jeux vidéos comme avec Three.js ou Playcanvas.\nL’utilisation est donc beaucoup plus limitée, c'est plutôt pour des petites animations ou configurateurs.\nPar exemple pour un e-commerce de voiture, on pourra visualiser la voiture ou changer sa couleur mais pas aller jusqu’à la création du nouveau Need for speed.\n\nLien vers Blend4Web\n
\n\"Verge3D\n\n**Verge 3D** est également un plugging utilisable pour Blender mais aussi Maya et 3Ds max. Il est payant que ce soit à usage personnel ou pour le commerce.\nIl agit comme Blend4web (rendu temps réel dans le navigateur et création d’interactions).\nCependant, les interactions sont plus développées car il utilise du post-processing qui est un langage de programmation graphique mais sans code (un peu comme Scratch).\n
\nSon utilisation principale est de créer des configurateurs mais il est également possible de créer des jeux vidéos pour le web.\nCependant, les performances sont lentes et ne valent pas celles de three.js ou Playcanvas.\n\nLien vers Verge 3D\n\n\n## Limites et perspectives\n\n

Pour qu’un site soit fonctionnel et utilisable, il faut penser à la performance. L’utilisateur doit pouvoir consulter le site sans latence et sans temps de chargement, surtout s'il est sur mobile. D’après la dernière étude Google, à partir de 5s d'attente sur mobile , 90 % des utilisateurs quitte la page. On appelle cela des taux de rebond. De plus, qui dit performance, dit aussi visibilité du site (SEO).

\n
\n

En 3D web, une des principales contraintes est donc de faire en sorte que les scènes ne soient pas trop lourdes afin d’éviter les taux de rebond.

\n
\n

Pour éviter cela, il faut compresser au maximum tous les assets à importer et ainsi réduire leur taille.\nÀ cause de cette contrainte, les éléments de la scène 3D doivent être limités et les animations bien réfléchies.

\n\n\n### WebGPU : L’utilisation de la carte graphique\n\n\nWebGPU est très ressemblant au Webgl et tend à remplacer l’API de Webgl. Le principe est de pouvoir utiliser la carte graphique de l’utilisateur en plus du processeur et donc permettre d’avoir de meilleures performances. Même s'il est toujours en développement, il est déjà possible de coder en WebGPU. Vous pouvez le tester en téléchargeant des navigateurs spécifiques compatibles :
\n* Google Canary\n* Firefox Nightly\n\n## Les 3D web et contraintes.\n\nPour conclure, nous avons vu les différentes façons de créer un site en 3D. Pour chacune des solutions proposer il faut savoir quels sont vos objectifs et contrainte. Gardez à l'esprit que pour qu’un site soit fonctionnel et utilisable, il faut penser performance. L’utilisateur doit pouvoir utiliser le site sans latence ni temps de chargement, surtout s'il est sur mobile. La 3D pour web évolu et pourra de plus en plus créer des expériences intéractives complexes, mais pour le moment le navigateur préfère des scènes légères.","data":{"title":"La 3D pour le Web","description":"L'ensemble des possibilités pour créer des expériences et jeux vidéo pour le web","publishedAt":"2021-08-17","imageLink":"/img/3d-web/_3d-web.jpg","tag":["3D web","Javascript"]},"filePath":"3d-web.mdx"},{"content":"\n
\n\n## Bon lien a checker\n\nLes maitres du domaines :\nici\n\n","data":{"title":"Les FX temps réel","description":"Les principes d'animation FX, comment mettre en valeur une action dans un ejux vidéo.","publishedAt":"2022-03-17","imageLink":"","tag":["hidden","FX","temps réel","tips"]},"filePath":"FX-temps-reel.mdx"},{"content":"
\n\nCe cours consiste à observer le monde qui nous entoure et à trouver des\nmoyens astucieux de simuler ce monde avec du code. Nous commencerons par\nexaminer la physique de base - comment une pomme tombe d’un arbre,\ncomment un pendule se balance dans l’air, comment la terre tourne autour\ndu soleil, etc. Tout ce dont nous allons parler ici nécessite\nl’utilisation de l’élément de base de la programmation du mouvement, le\nvecteur. Et c’est donc ici que nous commençons notre histoire. Le mot\n“vecteur” peut signifier beaucoup de choses différentes. Vector est le\nnom d’un groupe de rock new wave formé à Sacramento, en Californie, au\ndébut des années 1980. C’est le nom d’une céréale pour petit-déjeuner\nfabriquée par Kellogg’s Canada. Dans le domaine de l’épidémiologie, un\nvecteur est utilisé pour décrire un organisme qui transmet une infection\nd’un hôte à un autre. Dans le langage de programmation C++, un vecteur\n(std::vector) est une implémentation d’une structure de données de type\ntableau redimensionnable dynamiquement. Bien que toutes ces définitions\nsoient intéressantes, elles ne sont pas ce que nous recherchons.\n\nCe que nous voulons est appelé un **vecteur euclidien** (du nom du\nmathématicien grec Euclide et également connu sous le nom de vecteur\ngéométrique). Lorsque vous verrez le terme “vecteur” dans ce cours, vous\npourrez supposer qu’il s’agit d’un **vecteur euclidien**, défini comme\nune entité ayant à la fois une **magnitude** et une **direction**. Un\nvecteur est généralement dessiné sous la forme d’une flèche ; la\ndirection est indiquée par l’endroit où pointe la flèche, et la\nmagnitude par la longueur de la flèche elle-même.\n\n## Pourquoi utiliser les vecteurs? \n\nAvant de nous plonger dans les détails des vecteurs, examinons un\nprogramme de base qui démontre pourquoi nous devrions nous intéresser\naux vecteurs en premier lieu.\n\n``` JavaScript\n// Adapted from Dan Shiffman, natureofcode.com\n\nvar x = 100;\nvar y = 100;\nvar xspeed = 1;\nvar yspeed = 3.3;\n\nvar draw = function() {\n background(255, 255, 255);\n \n // Move the ball according to its speed.\n x = x + xspeed;\n y = y + yspeed;\n \n // Check for bouncing.\n if ((x > width) || (x < 0)) {\n xspeed = xspeed * -1;\n }\n if ((y > height) || (y < 0)) {\n yspeed = yspeed * -1;\n }\n \n noStroke();\n fill(181, 181, 181);\n // Display the ball at the location (x,y).\n ellipse(x, y, 32, 32);\n};\n```\n\nDans l’exemple ci-dessus, nous avons un monde très simple - un écran\nblanc avec une forme circulaire (une “balle”) qui se déplace. Cette\nballe a quelques propriétés, qui sont représentées dans le code comme\ndes variables.\n\n$Position: x ,y$\n\n$Vitesse: xSpeed, ySpeed$\n\nOn pourrait imaginer d’autres variables:\n\n$Acceleration: xAcceleration, yAcceleration$\n\n$Position de la cible: xTarget, yTarget$\n\n$Vent: xWind, yWind$\n\n$Force de friction: xFriction, yFriction$\n\nIl devient de plus en plus clair que pour chaque concept de ce monde\n(vent, position, accélération, etc.), nous aurons besoin de deux\nvariables. Et ceci n’est qu’un monde à deux dimensions. Dans un monde en\n3D, nous aurons besoin de x, y, z, xSpeed, ySpeed, zSpeed, et ainsi de\nsuite.\n\nNe serait-il pas agréable de simplifier notre code et d’utiliser moins\nde variables ? Au lieu de:\n\n``` JavaScript\n var x = 5;\n var y = 10;\n var xSpeed;\n var ySpeed;\n```\n\nOn pourrait n’avoir que 2 variables:\n\n``` JavaScript\n var position;\n var speed;\n```\n\nCette première étape dans l’utilisation des vecteurs ne nous permettra\npas de faire quelque chose de nouveau. Le simple fait d’utiliser des\nobjets vectoriels pour vos variables ne permettra pas à votre programme\nde simuler la physique comme par magie. Cependant, ils simplifieront\nvotre code et fourniront un ensemble de fonctions pour les opérations\nmathématiques courantes qui se produisent encore et encore et encore\nlors de la programmation du mouvement.\n\nEn guise d’introduction aux vecteurs, nous allons vivre en deux\ndimensions. Tous ces exemples peuvent être assez facilement étendus à\ntrois dimensions (et l’objet que nous utiliserons, PVector, permet\nd’utiliser trois dimensions).\n\n## Programmer avec PVector \n\nUne façon d’envisager un vecteur est la différence entre deux points.\nRéfléchissez à la manière dont vous pourriez donner des instructions\npour marcher d’un point à un autre.\n\nVous l’avez probablement déjà fait en programmant des mouvements. Pour\nchaque image de l’animation (c’est-à-dire un seul cycle de la boucle\ndraw() de ProcessingJS), vous demandez à chaque objet à l’écran de se\ndéplacer d’un certain nombre de pixels horizontalement et d’un certain\nnombre de pixels verticalement.\n\nPour chaque image :\n\n**nouvelle position = vitesse appliquée à la position actuelle**\n\nSi la vitesse est un vecteur (la différence entre deux points),\nqu’est-ce que la position ? Est-ce aussi un vecteur ? Techniquement, on\npourrait dire que la position n’est pas un vecteur, puisqu’elle ne\ndécrit pas comment se déplacer d’un point à un autre - elle décrit\nsimplement un point singulier dans l’espace.\n\nNéanmoins, une autre façon de décrire une position est le chemin suivi\ndepuis l’origine pour atteindre cette position. Cela signifie qu’une\nposition peut être le vecteur représentant la différence entre la\nposition et l’origine.\n\nExaminons les données sous-jacentes pour la position et la vitesse. Dans\nl’exemple de la balle rebondissante, nous avions les données suivantes :\n\n$position: x, y$\n\n$vitesse: xSpeed, ySpeed$\n\nRemarquez que nous stockons les mêmes données pour les deux - deux\nnombres à virgule flottante, un x et un y. Si nous devions écrire\nnous-mêmes une classe vectorielle, nous commencerions par quelque chose\nde plutôt basique :\n\n``` JavaScript\nvar Vector = function(x, y) {\n this.x = x;\n this.y = y;\n};\n```\n\nÀ la base, un PVector est juste un moyen pratique de stocker deux\nvaleurs (ou trois, comme nous le verrons dans les exemples 3D). Et donc:\n\n``` JavaScript\n var x = 100;\n var y = 100;\n var xSpeed = 1;\n var ySpeed = 3.3; \n```\n\ndevient:\n\n``` JavaScript\n var position = new PVector(100,100);\n var velocity = new PVector(1,3.3); \n```\n\nMaintenant que nous avons deux objets vectoriels (position et vitesse),\nnous sommes prêts à implémenter l’algorithme de mouvement **position =\nposition + vitesse**. Sans vecteurs, nous avions :\n\n``` JavaScript\n x = x + xSpeed;\n y = y + ySpeed; \n```\n\nDans un monde idéal, on écrirait maintenant:\n\n``` JavaScript\n position = position + vitesse; \n```\n\nToutefois, en JavaScript, l’opérateur d’addition + est réservé aux\nvaleurs primitives (nombres, chaînes de caractères). Dans certains\nlangages de programmation, les opérateurs peuvent être “surchargés”,\nmais pas en JavaScript. Heureusement pour nous, l’objet PVector comprend\ndes méthodes pour les opérations mathématiques courantes, comme add().\n\n## Addition de vecteurs \n\nAvant de continuer à étudier l’objet PVector et sa méthode add(),\nexaminons l’addition de vecteurs en utilisant la notation que l’on\ntrouve dans les manuels de mathématiques et de physique.\n\nLes vecteurs sont généralement écrits en caractères gras ou avec une\nflèche en haut. Dans le cadre de ces leçons, pour distinguer un vecteur\nd’un scalaire (le scalaire fait référence à une valeur unique, telle\nqu’un nombre entier ou un nombre à virgule flottante), nous utiliserons\nla notation fléchée :\n\n- Vecteur : $\\vec{u}$\n\n- Scalaire : $x$\n\nSi $\\vec{u} = (5,2)$ et $\\vec{v} = (3,4)$\n$\\vec{w} = \\vec{u} + \\vec{v} = (8,6)$\n\nMaintenant que nous savons comment additionner deux vecteurs, nous\npouvons examiner comment l’addition est implémentée dans l’objet PVector\nlui-même. Écrivons une méthode appelée add() qui prend un autre objet\nPVector comme argument, et ajoute simplement les composantes x et y\nensemble.\n\n``` Javascript\n var Vector = function(x, y) {\n this.x = x;\n this.y = y;\n };\n \n Vector.prototype.add = function(v) {\n this.y = this.y + v.y;\n this.x = this.x + v.x;\n };\n```\n\nMaintenant que nous voyons comment add() est écrit à l’intérieur de\nPVector, nous pouvons revenir à notre exemple de balle rebondissante\navec son algorithme de **position + vitesse** et implémenter l’addition\nvectorielle :\n\n``` Javascript\n position.add(vitesse);\n```\n\nEt maintenant, nous sommes prêts à réécrire l’exemple de la balle\nrebondissante en utilisant l’objet PVector ! Jetez un coup d’œil au code\net notez les différences par rapport à la version précédente.\n\n``` Javascript\n // Adapted from Dan Shiffman, natureofcode.com\n \n var position = new PVector(100, 100);\n var velocity = new PVector(2, 5);\n \n var draw = function() {\n background(255, 255, 255);\n \n position.add(velocity);\n \n // We still sometimes need to refer to the individual components of a PVector and can do so using the dot syntax: location.x, velocity.y, etc.\n if ((position.x > width) || (position.x < 0)) {\n velocity.x = velocity.x * -1;\n }\n if ((position.y > height) || (position.y < 0)) {\n velocity.y = velocity.y * -1;\n }\n \n noStroke();\n fill(179, 179, 179);\n ellipse(position.x, position.y, 16, 16);\n };\n \n```\n\nNous devons noter un aspect important de la transition ci-dessus vers la\nprogrammation avec des vecteurs. Même si nous utilisons des objets\nPVector pour décrire deux valeurs - les x et y de la position et les x\net y de la vitesse - nous devons souvent faire référence aux composantes\nx et y de chaque PVector individuellement. Lorsque nous voulons dessiner\nun objet dans ProcessingJS, nous ne pouvons pas le coder comme ceci :\n\n``` Javascript\n ellipse(position, 16, 16);\n```\n\nLa fonction ellipse() ne permet pas d’utiliser un vecteur PVector comme\nargument. Une ellipse ne peut être dessinée qu’à l’aide de deux valeurs\nscalaires, une coordonnée x et une coordonnée y. Nous devons donc\ncreuser dans l’objet PVector et en extraire les composantes x et y en\nutilisant la notation par points orientée objet :\n\n``` Javascript\n ellipse(position.x, position.y, 16, 16);\n```\n\nLe même problème se pose lorsqu’il s’agit de vérifier si le cercle a\natteint le bord de la fenêtre, et nous devons accéder aux composantes\nindividuelles des deux vecteurs : position et vitesse.\n\n``` Javascript\n if ((position.x > width) || (position.x < 0)) {\n vitesse.x = vitesse.x * -1;\n }\n```\n\nVous pourriez être quelque peu déçu. Après tout, ce passage à\nl’utilisation de vecteurs peut sembler au départ avoir rendu le code\nplus compliqué que la version originale. Bien qu’il s’agisse d’une\ncritique parfaitement raisonnable et valide, il est important de\ncomprendre que nous n’avons pas encore pleinement réalisé la puissance\nde la programmation avec des vecteurs. Regarder une simple balle\nrebondissante et n’implémenter que l’addition de vecteurs n’est que la\npremière étape.\n\nAu fur et à mesure que nous avançons dans un monde plus complexe\nd’objets multiples et de forces multiples (que nous présenterons\nbientôt), les avantages de PVector deviendront plus évidents. Continuez\ncomme ça !\n\n## Vecteurs en mathématiques\n\nL’addition n’était vraiment que la première étape. Il existe de\nnombreuses opérations mathématiques qui sont couramment utilisées avec\nles vecteurs. Vous trouverez ci-dessous une liste complète des\nopérations disponibles sous forme de fonctions dans l’objet PVector de\nProcessingJS. Nous allons maintenant passer en revue quelques-unes des\nprincipales opérations. Au fur et à mesure que nos exemples deviendront\nplus sophistiqués dans les sections suivantes, nous continuerons à\nrévéler les détails d’autres fonctions.\n\n- add() — add vectors\n\n- sub() — substract vectors\n\n- mult() — scale the vector with multiplication\n\n- div() — scale the vector with division\n\n- mag() — calculate the magnitude of a vector\n\n- normalize() — normalize the vector to a unit length of 1\n\n- limit() — limit the magnitude of a vector\n\n- heading2D() — the 2D heading of a vector expressed as an angle\n\n- dist() — the Euclidean distance between two vectors (considered as\n points)\n\n- angleBetween() — find the angle between two vectors\n\n- dot() — the dot product of two vectors\n\n- cross() — the cross product of two vectors (only relevant in three\n dimensions)\n\nAyant déjà abordé l’addition, commençons par la soustraction. Celle-ci\nn’est pas si difficile : il suffit de remplacer le signe plus par un\nsigne moins !\n\n$\\vec{w} = \\vec{u} - \\vec{v} = (5,2) - (3,4) = (2,-2)$\n\nDans la classe PVector:\n\n``` Javascript\n PVector.prototype.sub = function(vector2) {\n this.x = this.x - vector2.x;\n this.y = this.y - vector2.y;\n };\n \n```\n\nExemple avec la différence entre 2 points : la position de la souris et\nle centre de l’écran:\n\n``` Javascript\n // Adapted from Dan Shiffman, natureofcode.com\n \n mouseMoved = function() {\n background(255, 255, 255);\n // Two PVectors, one for the mouse location and one for the center of the window\n var mouse = new PVector(mouseX, mouseY);\n var center = new PVector(width/2, height/2);\n // PVector subtraction!\n mouse.sub(center);\n \n // Draw a line to represent the vector - \n // Simplify drawing it by first translating to center\n // and drawing the line from there\n pushMatrix();\n translate(width/2, height/2);\n stroke(255, 0, 0);\n strokeWeight(3);\n line(0, 0, mouse.x, mouse.y);\n popMatrix();\n };\n \n```\n\n## Multiplication de vecteurs \n\nPour passer à la multiplication, nous devons penser un peu différemment.\nLorsque nous parlons de multiplier un vecteur, nous parlons généralement\nde mettre à l’échelle un vecteur. Si nous voulions mettre à l’échelle un\nvecteur à deux fois sa taille ou à un tiers de sa taille (en laissant sa\ndirection inchangée), nous dirions : “Multipliez le vecteur par 2” ou\n“Multipliez le vecteur par 1/3”. Notez que nous multiplions un vecteur\npar un scalaire, un nombre unique, et non par un autre vecteur.\n\nPour mettre un vecteur à l’échelle, nous multiplions chaque composante\n(x et y) par un scalaire.\n\n$\\vec{w} = \\vec{u} * n$\n\nPeut être écrit:\n\n$w_x = u_x *n$\n\n$w_y = u_y *n$\n\nDans la classe PVector:\n\n``` Javascript\n PVector.prototype.mult = function(n) {\n this.x = this.x * n;\n this.y = this.y * n;\n }\n // on utilise la fonction mult():\n var u = new PVector(-3,7);\n // This PVector is now three times the size and is equal to (-9,21).\n u.mult(3);\n```\n\nVoici l’exemple de tout à l’heure, mais nous multiplions le vecteur par\n0,5 à chaque fois, pour qu’il soit mis à l’échelle de moitié :\n\n``` Javascript\n // Adapted from Dan Shiffman, natureofcode.com\n \n mouseMoved = function() {\n background(255, 255, 255);\n // Two PVectors, one for the mouse location and one for the center of the window\n var mouse = new PVector(mouseX, mouseY);\n var center = new PVector(width/2, height/2);\n // PVector subtraction!\n mouse.sub(center);\n \n mouse.mult(0.5);\n \n // Draw a line to represent the vector - \n // Simplify drawing it by first translating to center\n // and drawing the line from there\n resetMatrix();\n translate(width/2, height/2);\n stroke(255, 0, 0);\n strokeWeight(3);\n line(0, 0, mouse.x, mouse.y);\n };\n```\n\nAu lieu de multiplier par 0,5 ci-dessus, nous aurions également pu\ndiviser par 2. La division fonctionne comme la multiplication : il\nsuffit de remplacer le signe de multiplication (astérisque) par le signe\nde division (barre oblique). C’est ainsi que la méthode div est\nimplémentée en interne :\n\n``` Javascript\n PVector.prototype.div = function(n) {\n this.x = this.x / n;\n this.y = this.y / n;\n }\n // on utilise div():\n var u = new PVector(8, -4);\n u.div(2);\n \n```\n\n## Vecteurs: magnitude et normalisation \n\nLa multiplication et la division, comme nous venons de le voir, sont des\nmoyens par lesquels la longueur du vecteur peut être modifiée sans\naffecter la direction. Vous vous demandez peut-être : “OK, alors comment\npuis-je savoir quelle est la longueur d’un vecteur ? Je connais les\ncomposantes (x et y), mais quelle est la longueur (en pixels) de la\nflèche réelle ?”. Comprendre comment calculer la longueur (également\nappelée **magnitude**) d’un vecteur est incroyablement utile et\nimportant.\n\nRemarquez dans le schéma ci-dessus comment le vecteur, dessiné sous\nforme de flèche et de deux composantes (x et y), crée un triangle\nrectangle. Les côtés sont les composantes et l’hypoténuse est la flèche\nelle-même. Nous avons beaucoup de chance d’avoir ce triangle rectangle,\ncar il était une fois un mathématicien grec nommé Pythagore qui a mis au\npoint une jolie formule pour décrire la relation entre les côtés et\nl’hypoténuse d’un triangle rectangle.\n\nLe théorème de Pythagore est le suivant : $a^2 + b^2 = c^2$\n\nLa magnitude $|\\vec{v}| = \\sqrt{v_x^2 + v_y^2}$\n\nDans la classe PVector:\n\n``` Javascript\n PVector.prototype.mag = function() {\n return sqrt(this.x*this.x + this.y*this.y);\n };\n```\n\nL’exemple suivant permet de visualiser la magnitude d’un vecteur avec\nune barre en haut :\n\n``` Javascript\n // Adapted from Dan Shiffman, natureofcode.com\n \n mouseMoved = function() {\n background(255, 255, 255);\n resetMatrix();\n \n // Two PVectors, one for the mouse location and\n // one for the center of the window\n var mouse = new PVector(mouseX, mouseY);\n var corner = new PVector(width/2, height/2);\n // PVector subtraction!\n mouse.sub(corner);\n \n var m = mouse.mag();\n fill(0, 0, 0);\n rect(0, 0, m, 10);\n \n // Draw a line to represent the vector.\n translate(width/2, height/2);\n stroke(255, 0, 0);\n strokeWeight(3);\n line(0, 0, mouse.x, mouse.y);\n };\n```\n\nLe calcul de la magnitude d’un vecteur n’est qu’un début. La fonction de\nmagnitude ouvre la porte à de nombreuses possibilités, dont la première\nest la **normalisation**.\n\nLa normalisation est le processus qui consiste à rendre quelque chose\n“standard” ou, en fait, “normal”. Dans le cas des vecteurs, supposons\npour l’instant qu’un vecteur standard a une longueur de 1. Normaliser un\nvecteur, c’est donc prendre un vecteur de n’importe quelle longueur et,\nen le gardant orienté dans la même direction, changer sa longueur en 1,\nle transformant en ce qu’on appelle un vecteur unitaire.\n\nComme il décrit la direction d’un vecteur sans tenir compte de sa\nlongueur, il est utile d’avoir le vecteur unitaire à portée de main.\nNous verrons que cela s’avère pratique lorsque nous commencerons à\ntravailler avec les forces dans la section suivante. Pour tout vecteur\ndonné $\\vec{u}$ son vecteur unitaire (écrit comme $\\hat{u}$ u avec,\nchapeau) se calcule comme suit :\n\n$\\hat{u} = \\frac{\\vec{u}}{|\\vec{u}|}$\n\nEn d’autres termes, pour normaliser un vecteur, il suffit de diviser\nchaque composante par sa magnitude. C’est assez intuitif. Disons qu’un\nvecteur a une longueur de 5. 5 divisé par 5 est égal à 1. Donc, en\nregardant notre triangle rectangle, nous devons réduire l’hypoténuse en\nla divisant par 5. Dans ce processus, les côtés diminuent, divisés par 5\négalement.\n\nEn code:\n\n``` Javascript\n PVector.prototype.normalize = function() {\n var m = this.mag();\n this.div(m);\n };\n```\n\nVoici un programme dans lequel nous normalisons toujours le vecteur qui\nreprésente la position de la souris à partir du centre (puis nous le\nmultiplions pour pouvoir le voir, car 1 pixel est minuscule !) :\n\n``` Javascript\n // Adapted from Dan Shiffman, natureofcode.com\n \n mouseMoved = function() {\n background(255, 255, 255);\n \n // Two PVectors, one for the mouse location and\n // one for the center of the window\n var mouse = new PVector(mouseX, mouseY);\n var corner = new PVector(width/2, height/2);\n // PVector subtraction!\n mouse.sub(corner);\n \n // In this example, after the vector is normalized, it is multiplied by 50 so that it is viewable onscreen. Note that no matter where the mouse is, the vector will have the same length (50) due to the normalization process.\n mouse.normalize();\n mouse.mult(50);\n \n // Draw a line to represent the vector.\n resetMatrix();\n translate(width/2, height/2);\n stroke(255, 0, 0);\n strokeWeight(3);\n line(0, 0, mouse.x, mouse.y);\n };\n```\n\n## Le mouvement avec les vecteurs \n\nToutes ces mathématiques vectorielles semblent être quelque chose que\nnous devrions connaître, mais pourquoi ? En quoi cela va-t-il nous aider\nà écrire du code ? La vérité est que nous devons faire preuve d’un peu\nde patience. Il faudra un certain temps avant que les merveilles de\nl’utilisation de la classe PVector ne se révèlent pleinement.\n\nC’est en fait un phénomène courant lors de l’apprentissage d’une\nnouvelle structure de données. Par exemple, lorsque vous apprenez à\nconnaître un tableau, il peut sembler beaucoup plus difficile d’utiliser\nun tableau que d’avoir plusieurs variables pour représenter plusieurs\nchoses. Mais ce plan s’effondre rapidement lorsque vous avez besoin de\ncent, mille ou dix mille choses.\n\nLa même chose peut être vraie pour PVector. Ce qui peut sembler être un\nsurcroît de travail aujourd’hui sera rentabilisé plus tard, et de\nmanière très satisfaisante. Et vous n’aurez pas à attendre trop\nlongtemps, car votre récompense viendra dans le prochain chapitre.\n\n## Vitesse \n\nPour l’instant, cependant, nous voulons nous concentrer sur la\nsimplicité. Que signifie programmer un mouvement en utilisant des\nvecteurs ? Nous en avons vu les prémices dans l’exemple de la balle\nrebondissante. Un objet à l’écran a une position (où il se trouve à tout\nmoment) ainsi qu’une vitesse (instructions sur la façon dont il doit se\ndéplacer d’un moment à l’autre). La vélocité/vitesse est ajoutée à la\nposition :\n\n``` Javascript\n // on ajoute la vitesse a la position\n position.add(vitesse);\n // on dessine l'objet\n ellipse(position.x, position.y, 16, 16);\n```\n\nDans l’exemple de la balle rebondissante, tout ce code se trouvait dans\nla fonction draw de ProcessingJS. Ce que nous voulons faire maintenant,\nc’est encapsuler toute la logique du mouvement dans un objet. De cette\nfaçon, nous pouvons créer une base pour la programmation d’objets\nmobiles dans tous nos programmes ProcessingJS.\n\nDans ce cas, nous allons créer un objet Mover générique qui décrira un\nobjet se déplaçant à l’écran. Et donc nous devons considérer les deux\nquestions suivantes :\n\n- Quelle data contient un objet Mover?\n\n- Quelles fonctionnalités contient un objet Mover?\n\nUn objet Mover possède deux données : la position et la vélocité, qui\nsont toutes deux des objets PVector. Nous pouvons commencer par écrire\nla fonction du constructeur qui initialise ces propriétés à des valeurs\naléatoires appropriées :\n\n``` Javascript\n var Mover = function() {\n this.position = new PVector(random(width), random(height));\n this.velocity = new PVector(random(-2, 2), random(-2, 2));\n };\n```\n\nSa fonctionnalité est tout aussi simple. Le Mover doit se déplacer et il\ndoit être vu. Nous implémenterons ces besoins sous forme de méthodes\nnommées update() et display(). Nous placerons tout notre code de logique\nde mouvement dans update() et dessinerons l’objet dans display().\n\n``` Javascript\n Mover.prototype.update = function() {\n this.position.add(this.velocity);\n };\n \n Mover.prototype.display = function() {\n stroke(0);\n strokeWeight(2);\n fill(127);\n ellipse(this.position.x, this.position.y, 48, 48);\n };\n```\n\nSi la programmation orientée objet vous est totalement inconnue, un\naspect de ce chapitre peut sembler un peu déroutant. Après tout, nous\navons passé le début de ce chapitre à parler de PVector. L’objet PVector\nest le modèle pour créer l’objet position et l’objet vélocité. Alors que\nfont-ils à l’intérieur d’un autre objet, l’objet Mover ? En fait, c’est\nla chose la plus normale qui soit. Un objet est simplement quelque chose\nqui contient des données (et des fonctionnalités). Ces données peuvent\nêtre des nombres, des chaînes de caractères, des tableaux ou d’autres\nobjets ! Nous le verrons maintes et maintes fois dans ce cours. Par\nexemple, dans le tutoriel sur les particules, nous allons écrire un\nobjet pour décrire un système de particules. Cet objet ParticleSystem\naura comme données un tableau d’objets Particle... et chaque objet\nParticle aura comme données plusieurs objets PVector !\n\nTerminons l’objet Mover en incorporant une fonction pour déterminer ce\nque l’objet doit faire lorsqu’il atteint le bord de la fenêtre. Pour\nl’instant, faisons quelque chose de simple, et faisons en sorte qu’il\ns’enroule autour des bords :\n\n``` Javascript\n Mover.prototype.checkEdges = function() {\n \n if (this.position.x > width) {\n this.position.x = 0;\n } \n else if (this.position.x < 0) {\n this.position.x = width;\n }\n \n if (this.position.y > height) {\n this.position.y = 0;\n } \n else if (this.position.y < 0) {\n this.position.y = height;\n }\n };\n```\n\nMaintenant que l’objet Mover est terminé, nous pouvons voir ce que nous\ndevons faire dans notre programme principal. Nous commençons par\ndéclarer et initialiser une nouvelle instance de Mover :\n\n``` Javascript\n var mover = new Mover();\n // puis nous appelons les fonctions dans draw()\n draw = function() {\n background(255, 255, 255);\n \n mover.update();\n mover.checkEdges();\n mover.display(); \n };\n```\n\n## Fonctions statiques VS. méthodes d’instance \n\nNous devons aborder un autre aspect assez important du travail avec les\nvecteurs et l’objet PVector : la différence entre l’utilisation de\nfonctions statiques et de méthodes d’instance. Oublions les vecteurs\npour un instant et regardons le code suivant :\n\n``` Javascript\n var x = 0;\n var y = 5;\n x = x + y;\n```\n\nPlutôt simple, non ? x a la valeur 0, nous lui ajoutons y, et maintenant\nx est égal à 5. Nous pourrions écrire le code correspondant assez\nfacilement en nous basant sur ce que nous avons appris sur PVector.\n\n``` Javascript\n var v = new PVector(0,0);\n var u = new PVector(4,5);\n v.add(u);\n```\n\nLe vecteur v a la valeur de (0,0), nous lui ajoutons u, et maintenant v\nest égal à (4,5). Facile, non ?\n\nVoyons un autre exemple de mathématiques simples :\n\n``` Javascript\n var x = 0;\n var y = 5;\n var z = x + y;\n```\n\nx a la valeur 0, nous lui ajoutons y et stockons le résultat dans une\nnouvelle variable z. La valeur de x ne change pas dans cet exemple, et\ncelle de y non plus ! Ce point peut sembler trivial et assez intuitif\nlorsqu’il s’agit d’opérations mathématiques avec des nombres. Cependant,\nce n’est pas si évident avec les opérations mathématiques dans PVector.\nEssayons d’écrire le code sur la base de ce que nous savons jusqu’à\nprésent.\n\n``` Javascript\n var v = new PVector(0,0);\n var u = new PVector(4,5);\n var w = v.add(u); // Ceci n'est pas correct\n```\n\nCe qui précède peut sembler être une bonne supposition, mais ce n’est\npas la façon dont l’objet PVector fonctionne. Si nous regardons la\ndéfinition de add()...\n\n``` Javascript\n PVector.prototype.add = function(v) {\n this.x = this.x + v.x;\n this.y = this.y + v.y;\n };\n```\n\n...nous voyons que ce code n’atteint pas notre objectif. Premièrement,\nil ne renvoie pas un nouveau PVector (il n’y a pas d’instruction de\nretour) et deuxièmement, il modifie la valeur du PVector sur lequel il\nest appelé. Afin d’ajouter deux objets PVector ensemble et de retourner\nle résultat comme un nouveau PVector, nous devons utiliser la fonction\n“static” add().\n\nUne fonction “statique” est une fonction qui est définie sur un objet,\nmais qui ne modifie pas les propriétés de l’objet. Alors pourquoi la\ndéfinir sur l’objet ? En général, elle a quelque chose à voir avec\nl’objet, il est donc logique de l’y rattacher. L’objet est traité comme\nun espace de noms. Par exemple, toutes les fonctions statiques de\nPVector effectuent une sorte de manipulation sur des objets PVector\npassés et renvoient toujours une valeur. Nous pourrions également\ndéfinir ces fonctions de manière globale, mais de cette façon, nous\névitons les fonctions globales et disposons de meilleurs moyens de\nregrouper les fonctionnalités connexes.\n\nFaisons un contraste. Voici comment nous utilisons la méthode d’instance\nadd() :\n\n``` Javascript\n var w = PVector.add(u, v);\n```\n\nSi nous n’avions pas enregistré le résultat de cette fonction dans une\nvariable, cette ligne de code serait inutile, car la version statique ne\nmodifie pas les objets eux-mêmes. Les fonctions statiques de PVector\nnous permettent d’effectuer des opérations mathématiques génériques sur\nles objets PVector sans avoir à ajuster la valeur de l’un des PVectors\nd’entrée.\n\nVoilà comment on aurait écrit la fonction add():\n\n``` Javascript\n PVector.add = function(v1, v2) {\n var v3 = new PVector(v1.x + v2.x, v1.y + v2.y);\n return v3;\n };\n```\n\nIl y a plusieurs différences ici :\n\n- Nous définissons la fonction directement sur l’objet, et non sur son\n prototype.\n\n- Nous n’accédons jamais au mot-clé this à l’intérieur de la fonction.\n\n- Nous retournons une valeur à partir de la fonction\n\nL’objet PVector possède des versions statiques de add(), sub(), mult()\net div(). Il possède également des fonctions statiques supplémentaires\nqui n’existent pas en tant que méthodes d’instance, comme\nangleBetween(), dot() et cross(). Nous serons amenés à utiliser ces\nfonctions au fur et à mesure que nous créerons des programmes avec\nPVector.\n\nMouvement interactif avec les vecteurs \n======================================\n\nPour terminer cette section, essayons quelque chose d’un peu plus\ncomplexe et de beaucoup plus utile. Nous allons calculer dynamiquement\nl’accélération d’un objet selon la règle : l’objet accélère en direction\nde la souris.\n\nChaque fois que nous voulons calculer un vecteur sur la base d’une règle\nou d’une formule, nous devons calculer deux choses : la magnitude et la\ndirection. Commençons par la direction. Nous savons que le vecteur\naccélération doit pointer de la position de l’objet vers la position de\nla souris. Disons que l’objet est situé au point (x,y) et la souris à\n(mouseX,mouseY).\n\n$dx = mouseX - x$\n\n$dy = mouseY - y$\n\nRéécrivons ce qui précède en utilisant la syntaxe PVector. En supposant\nque nous sommes dans la définition de l’objet Mover et que nous avons\ndonc accès à la position du PVector de l’objet, nous avons alors :\n\n```Javascript\nvar mouse = new PVector(mouseX, mouseY);\n// Look! We're using the static sub() \n// because we want a completely new PVector\nvar dir = PVector.sub(mouse, position);\n```\n\nNous avons maintenant un PVector qui pointe depuis la position du mover\njusqu’à la souris. Si l’objet devait réellement accélérer en utilisant\nce vecteur, il apparaîtrait instantanément à la position de la souris.\nCela ne permet pas de faire une bonne animation, bien sûr, et ce que\nnous voulons faire maintenant, c’est décider à quelle vitesse l’objet\ndoit accélérer vers la souris.\n\nAfin de définir la magnitude (quelle qu’elle soit) de notre vecteur PV\nd’accélération, nous devons d’abord ?????????? ce vecteur directionnel.\nC’est vrai, vous l’avez dit. Normaliser. Si nous pouvons réduire le\nvecteur à son vecteur unitaire (de longueur un), nous avons alors un\nvecteur qui nous indique la direction et qui peut facilement être mis à\nl’échelle à n’importe quelle valeur. Un multiplié par n’importe quoi est\négal à n’importe quoi.\n\n``` Javascript\n var anything = ??;\n dir.normalize();\n dir.mult(anything);\n```\n\nPour résumer, nous suivons les étapes suivantes :\n\n- Calculer un vecteur qui pointe de l’objet vers la position cible\n (souris).\n\n- Normaliser ce vecteur (en réduisant sa longueur à 1)\n\n- Mettre à l’échelle ce vecteur à une valeur appropriée (en le\n multipliant par une certaine valeur)\n\n- Assigner ce vecteur à l’accélération\n\nVoici à quoi ressemble le programme, avec ces étapes entièrement\nimplémentées :\n\n``` Javascript\n // Adapted from Dan Shiffman, natureofcode.com\n \n var Mover = function() {\n this.position = new PVector(width/2, height/2);\n this.velocity = new PVector(0, 0);\n this.acceleration = new PVector(0, 0);\n };\n \n Mover.prototype.update = function() {\n var mouse = new PVector(mouseX, mouseY);\n var dir = PVector.sub(mouse, this.position);\n dir.normalize();\n dir.mult(0.5);\n this.acceleration = dir;\n this.velocity.add(this.acceleration);\n this.velocity.limit(5);\n this.position.add(this.velocity);\n };\n \n Mover.prototype.display = function() {\n stroke(0);\n strokeWeight(2);\n fill(127);\n ellipse(this.position.x, this.position.y, 48, 48);\n };\n \n Mover.prototype.checkEdges = function() {\n \n if (this.position.x > width) {\n this.position.x = 0;\n } else if (this.position.x < 0) {\n this.position.x = width;\n }\n \n if (this.position.y > height) {\n this.position.y = 0;\n } else if (this.position.y < 0) {\n this.position.y = height;\n }\n };\n \n var mover = new Mover();\n \n var draw = function() {\n background(255, 255, 255);\n \n mover.update();\n mover.checkEdges();\n mover.display(); \n };\n```\n\nVous vous demandez peut-être pourquoi le cercle ne s’arrête pas\nlorsqu’il atteint la cible. Il est important de noter que l’objet en\nmouvement ne sait pas qu’il doit s’arrêter à une destination ; il sait\nseulement où se trouve la destination et essaie de s’y rendre aussi vite\nque possible. En allant aussi vite que possible, il dépassera\ninévitablement la position et devra faire demi-tour, pour aller à\nnouveau aussi vite que possible vers la destination, la dépasser à\nnouveau, et ainsi de suite. Restez à l’écoute ; dans les sections\nsuivantes, nous apprendrons comment programmer un objet pour qu’il\narrive à une position (ralentissement à l’approche).\n\nCet exemple est remarquablement proche du concept d’attraction\ngravitationnelle (dans lequel l’objet est attiré par la position de la\nsouris). L’attraction gravitationnelle sera traitée plus en détail dans\nla section suivante. Toutefois, il manque ici une chose : la force de la\ngravité (l’ampleur de l’accélération) est inversement proportionnelle à\nla distance. Cela signifie que plus l’objet est proche de la souris,\nplus il accélère.\n\nVoyons à quoi ressemblerait cet exemple avec un tableau de movers\n(plutôt qu’un seul).\n\n``` Javascript\n // Adapted from Dan Shiffman, natureofcode.com\n \n var Mover = function() {\n this.position = new PVector(random(width), random(height));\n this.velocity = new PVector(0, 0);\n this.acceleration = new PVector(0, 0);\n };\n \n Mover.prototype.update = function() {\n var mouse = new PVector(mouseX, mouseY);\n var dir = PVector.sub(mouse, this.position);\n dir.normalize();\n dir.mult(0.2);\n this.acceleration = dir;\n this.velocity.add(this.acceleration);\n this.velocity.limit(5);\n this.position.add(this.velocity);\n };\n \n Mover.prototype.display = function() {\n stroke(0);\n strokeWeight(2);\n fill(127);\n ellipse(this.position.x, this.position.y, 10, 10);\n };\n \n Mover.prototype.checkEdges = function() {\n \n if (this.position.x > width) {\n this.position.x = 0;\n } \n else if (this.position.x < 0) {\n this.position.x = width;\n }\n \n if (this.position.y > height) {\n this.position.y = 0;\n } \n else if (this.position.y < 0) {\n this.position.y = height;\n }\n };\n \n var movers = [];\n \n for (var i = 0; i < 20; i++) {\n movers[i] = new Mover(); \n }\n \n draw = function() {\n background(255, 255, 255);\n for (var i = 0; i < movers.length; i++) {\n movers[i].update();\n movers[i].display(); \n }\n };\n \n \n```\n","data":{"title":"Introduction aux vecteurs ","description":"Observer le monde qui nous entoure et à trouver des moyens astucieux de simuler ce monde avec du code.","publishedAt":"2021-11-09","imageLink":"https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Processing_Logo_Clipped.svg/1200px-Processing_Logo_Clipped.svg.png","tag":["Algorithmie","javascript"]},"filePath":"Introduction-aux-vecteurs.mdx"},{"content":"\n## Un ordinateur est bête !\n\nLe noyeau de l'ordinateur ne peux pas faire de tâche complexe.\n\n* un bug = un problème lié à l'incompréhension d'un humain face à la machine\n* un ordibnateur ne calcule que la memoire alloué.\n* Nous sommes capable de reconnaître nos amis, notre famille de dos, car nous exécution pas comme un ordinateur, mais plus complexe. Un ordinateur est incapable de reconnaître un visage (l'inteligence artificiel n'utilise pas l'algorithmie pour la reconnaissance). \n\nExemple : \n* Il ne peux pas faire de multiplication\n* si 5*3 l'ordinateur ferra 5+5+5\n\nPour comprendre un ordinateur il faut être bête !\n\n**⚠ Un algorithme n'est pas une équation, mais une suite d'intruction** \n\nAlgorithmie très vieux datant du 8e siècle qui se nomme AL KARWAZI qui donne Algorithmie.\nTuring a imaginé la machine de Turing qui permet de résoudre pleins de problème mathématique.\nLes ordinateur ce sont basé sur les machines de Turing avec des case d'instruction, de case et d’exécution. \nPour intervertir des valeurs je suis obligé d'utiliser une 3e variable.\n\n\nUn trie en quick sort, est un trie rapide qui se base sur plusieurs fonction, de processus ce basant sur une médiane distribué à chaque fonction jusqua avoir une valeur par fonction. \n\n## Cas pratique\n\nPouvoir créer des sortes de recettes pour executer une tâche.\nTuring a Imaginer une machine :\n* Des cases \n\n### Trier un jeu de carte :\n\n3 méthodes proposé :\n\nProposition **quick sort** : \neffectué plusieurs tâche en parallèle\nValeur médianne entre 1-5\net 5-10 \nle procésseur va donner la carte a que\n\n### Démontrer en Code\n\n**Méthode de Aimé :** \n\n*pseudo code :*\n```python\ncarte_trier[10] ={0,0,0,0,0,0,0,0,0,0}\ncarte_non_trier[10] = {7,6,10,9,3,4,2,1,5,8}\n\nfor i = 0 to i = 9 \n i++\n carte_a_placer = carte_non_trier[i]\n carte_a_trier[carte_a_placer - 1] = carte_a_la_place\n\n\n# output\n# 1ère iteration\n# {0,0,0,0,0,0,7,0,0,0}\n```\n\nPratique :\n\n\n**Méthode a bulle**\n\n![Methode a bulle](https://upload.wikimedia.org/wikipedia/commons/5/54/Sorting_bubblesort_anim.gif)\n\nLe tri à bulles ou tri par propagation1 est un algorithme de tri. Il consiste à comparer répétitivement les éléments consécutifs d'un tableau, et à les permuter lorsqu'ils sont mal triés. Il doit son nom au fait qu'il déplace rapidement les plus grands éléments en fin de tableau, comme des bulles d'air qui remonteraient rapidement à la surface d'un liquide. \n\n*def venant de wikipedia*\n\n\n*python :*\n```python\ncarte = [4,9,2,10,3,7,6,1,5,8]\n\ndef algo(i):\n first_local = carte[i]\n second_local = carte[i+1]\n \n if first_local > second_local :\n carte[i] = second_local\n carte[i+1] = first_local\n else:\n carte[i] = first_local\n i = i + 1\n\nif __name__ == '__main__':\n while carte != [1,2,3,4,5,6,7,8,9,10]:\n for i in range(0,9):\n algo(i)\n print(carte)\n```\n![result](/img/python-maya/result.JPG)\n\n\n## Corection du professeur\n\n```python\nTableau_trier(taille_tableau)\n je commence avec i = 0 et tant que i < taille_tableau alors incremente i de 1\n case = tableau[i]\n case_au _dessus = tabelau[i+1]\n si case > case_au_dessus \n alors retourne pas_trier\n retourne tableau_trier\n\ntant que Tableau_trier est faux \n case_a_analyser = 0\n je commence avec case_a_analyser = 0 et tant que i < taille_tableau alors incrémente i de 1\n premiere_case = tableau[case_a_analyser]\n deuxieme_case = tableau[case_a_analyser + 1]\n si premiere_case > deuxieme_case\n intervertir(premiere_case avec deuxieme_case) # on sais pas encore le faire\n\n```\n\n
\n\n\n**Méthode shaker**\n![méthode shaker](https://upload.wikimedia.org/wikipedia/commons/e/ef/Sorting_shaker_sort_anim.gif)\n\nLa différence entre cet algorithme et le tri à bulles est qu'il exécute un tri dans chaque direction à chaque passe le long de la liste à trier2. Cet algorithme de tri n'est que légèrement plus difficile à comprendre et à mettre en œuvre que le tri à bulles, et il résout en partie le problème des tortues du tri à bulles (les tortues sont les petits éléments situés près de la fin de la liste d'origine, qui ne remontent que très lentement, un emplacement par itération, vers leur emplacement définitif).\n\n*def venant de wikipedia*\n\n*python :*\n```python\n\ncarte = [4,9,2,10,3,7,6,1,5,8]\n\ndef up(i, y):\n if carte[i] > carte[i+y] :\n first_local = carte[i]\n second_local = carte[i+y]\n carte[i] = second_local\n carte[i+y] = first_local\n\n i = i + y\ndef down(i, y): \n if carte[i] < carte[i+y] :\n first_local = carte[i]\n second_local = carte[i+y]\n carte[i] = second_local\n carte[i+y] = first_local\n\n i = i + y\n\nif __name__ == '__main__':\n i = 0\n while carte != [1,2,3,4,5,6,7,8,9,10]:\n while i < 9:\n up(i, 1)\n i = i + 1\n while i > 0:\n down(i, -1)\n i = i - 1\n \n print(carte)\n\n\n```\n![result](/img/python-maya/result.JPG)\n\n## Correction professeur \n\n*pseudo code* \n\n```javascript\ncaseEnCours = 0\ncaseSuivante = 0\ncaseAuBout = Faux\n\n//je veux intervir deux case array[indice1] et array[indice2]\nFonction intervertir(array[],indice1,indice2)\n\ttemp = array[indice1]\n\tarray[indice1] = array[indice2]\n\tarray[indice2] = temp \n\n//je parcours le tableau mais je ne peux pas sortir du tableau\nFonction parcoursTableau(array[] , step) //\n\tcaseAuBout = Faux\n\tcaseEnCours = caseEnCours + step //caseEnCours = caseEnCours + 1 = 1 \n\tsi caseEnCours > taille(array[]) -1 \n\t\tcaseEnCours = taille(array[]) -1 \n\t\tcaseAuBout = Vrai\n\tsi caseEnCours < 0\n\t\tcaseEnCours = 0 \n\t\tcaseAuBout = Vrai\n\n//je remonte la carte la plus haute\nFonction remonteCartePlusHaute(array[]) {1,5,7,2}\nX\tTant que caseAuBout = Faux //tant que je n'ai pas parcouru tout mon tableau\nX\t\tindice1 = caseEnCours\n\t\tparcoursTableau(array, 1)\t //caseEnCours = 1\n\t\tindice2 = caseEnCours\nV\t\tsi array[indice1] > array[indice2] alors\n\t\t\tintervertir(array,indice1 , indice2 )\n\n//je redescend la carte la plus base\nFonction redescendCartePlusBasse(array[])\nTant que caseAuBout = Faux //tant que je n'ai pas parcouru tout mon tableau\nX\t\tindice1 = caseEnCours\n\t\tparcoursTableau(array, -1)\t //caseEnCours = 1\n\t\tindice2 = caseEnCours\nV\t\tsi array[indice1] < array[indice2] alors\n\t\t\tintervertir(array,indice1 , indice2 )\n\n//Est-ce que mon tableau est trier?\nFonction isArraySorted(array[])\n\ttableauTrier = Vrai\n\tTant que caseAuBout = Faux \n\t\tindice1 = caseEnCours\n\t\tparcoursTableau(array, 1)\t //caseEnCours = 1\n\t\tindice2 = caseEnCours\n\t\tsi array[indice1] > array[indice2] alors\n\t\t\t\ttableauTrier = Faux\n\t\t\t\texit\n\n\n//Je veux trier un jeu de carte\nFonction sort(array[])\n\t//Est-ce que mon tableau est trier?\n\tsorted = isArraySorted(array)\n\t//tant que mon tableau est pas trier alors\n\ttant que pas sorted \n\t\tremonteCartePlusHaute(array)\n\t\tredescendCartePlusBasse(array)\n\t//j'affiche mon tableau\n\n\n```\n\n## Méthode quick sort\n\n![quickSort](https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif)\n\nPour trier chaque carte nous créeon un *arbre binaire*.\nLe principe est de séparer chaque partie en la médiane (la moitier de chaque nombre). Puis nous repartissons chaque partie encore en la médianne.\n\n-> jeux de couloir","data":{"title":"L'algorithmie, base de tri","description":"Méthode a bulle, shaker et quick sort","publishedAt":"2021-10-05","imageLink":"/img/algorithmie/definition-tri-de-cartes.jpg","tag":["algorithmie"]},"filePath":"algorithmie.mdx"},{"content":"
\n\nQuelques bon livres :\nLightning et rendering\n\n## Mise en place de l'espace colorimétrique\n\n**> Télécharger dossier et le configurer sur Maya**\n\nDossier à télécharger : \n\nDossier “aces_1.2” qui est un espace colorimétrique important. Il permet une bonne qualité de rendu. \n\nConfiguration sur Maya : \n\n\n\n* soit Windows > Settings Preferences > Preferences\n* soit icône bonhomme qui court > Color Management > cliquer sur OCIO et aller chercher le dossier aces_1.2 > selectionner le fichier config.ocio > cocher Use OCIO Configuration \n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image1.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image2.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image3.png \"image_tooltip\")\n\n\n**> Quelques tips sur Maya**\n\nCréation d’un tout nouveau dossier lié à notre projet \n\nFile > Project Window > modifier nom du projet et destination \n\nEn cas de crash du Maya :\n\nFile > Set project > Sélectionner le dossier de projet \n\nFormat de Maya :\n\n\n\n* Maya ASCII : plus lourd mais si le fichier crash, on peut l’éditer avec un document texte et le debug. => Toujours opter pour celui-ci\n* Maya Binary : si le fichier est corrompu c’est mort\n\nNomenclature :\n\n“Prout_de_Sandy.ma” et non “Prout de Sandy.ma”\n\nT-es_bete.ma\n\n“T_es_mechante.ma” et non “T’es méchante.ma”\n\n/!\\ Bien penser à renommer les objets que l’on crée\n\n## **> Nouveau projet - cours 1**\n\nSe mettre en vu renderCam : \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image4.png \"image_tooltip\")\n\n\nFaire apparaître le resolution gate :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image5.png \"image_tooltip\")\n\n\n> Activer le plug-in arnold \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image6.png \"image_tooltip\")\n\n\n> Faire un rendu avec la bonne caméra (par défaut, c’est la vue persp qui est active)\n\nPour prendre notre renderCam, faire un clic droit sur la première icône et sélectionner la renderCam\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image7.png \"image_tooltip\")\n\n\n> Pour éviter la fenêtre flottante il est possible de prendre dans l’une des 4 view un onglet consacré au render view : Panels > Render view\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image8.png \"image_tooltip\")\n\n\n> Lumière arnold : attribute editor (selec light > ctrl+a)\n\n\n\n* Intensity : toujours laisser à 1 ! \n\nLe problème avec son augmentation c’est le calcul qu’il faut faire si l’on demande de baisser à moitié la light (par exemple si on demande de baisser à moitié l’intensité à 1580, flemme de calculer alors que si l’expo est à 11, pour baisser à moitié faut juste mettre 10).\n\n* Exposure : l’augmenter pour augmenter la luminosité !\n\n Le principe de l’exposure permet de monter par step (ouvrir/fermer diaphragme en photographie) c’est un multiplicateur : lorsqu’on le monte par unité (de 10 à 11 par exemple) ça multiplie.\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image9.png \"image_tooltip\")\n\n\n> Augmenter l’area light permet d’adoucir l’ombre :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image10.png \"image_tooltip\")\n\n\n> Pour voir le Before/After du rendu : bouger la slide \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image11.png \"image_tooltip\")\n \n\n> Bon à savoir ! Dans les lights de maya il y’a aussi les paramètres arnold \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image12.png \"image_tooltip\")\n\n\n> Utilisation des lights selon contexte de la scène \n\narea light : rendu intérieur, fenêtres etc\n\ndirectional light : rendu extérieur; soleil etc\n\n> Adoucir les ombres dures :\n\ndirectionalLight > augmenter angle \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image13.png \"image_tooltip\")\n\n\n> Skydome d’Arnold et HDRI\n\nOn peut y insérer des map d’HDRI \n\nhdrlabs.com > gallery \n\nhdri haven \n\nle mettre dans le dossier sourceimages \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image14.png \"image_tooltip\")\n\n\nInsérer l’HDRI en sélectionnant un file et en uploadant l’image dans file\n\nPour appliquer correctement l’HDRI, il faut changer l’espace colorimétrique à partir de l’onglet file : Color Space : Utility Linear sRGB\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image15.png \"image_tooltip\")\n\n\nrésultat après :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image16.png \"image_tooltip\")\n\n\nPour ne pas avoir le décor en fond, cliquer sur le skydome > visibility : camera = 0\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image17.png \"image_tooltip\")\n\n\n> Shader Arnold : \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image18.png \"image_tooltip\")\n\n\nou Windows > rendering editor > hypershade\n\nShader correspond à comment la surface va réagir à la lumière (brillance, transparence, etc)\n\nPour assigner mon shader à mon objet selectionné :\n\nselect mon objet > clic droit dans mon hypershade pour assign \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image19.png \"image_tooltip\")\n\n\nPour assigner un material sans hypershade : dans le viewport normal\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image20.png \"image_tooltip\")\n\n\n> Documentation material pbr \n\n[https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Materials/PhysicallyBased/](https://docs.unrealengine.com/4.27/en-US/RenderingAndGraphics/Materials/PhysicallyBased/)\n\n> Sauvegarder une image \n\nclic droit sur le viewport > vérifier option du save image > option : color managed image > png\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image21.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-1/image22.png \"image_tooltip\")\n\n\n## Cours 2\n\n**> Settings du projet **\n\n\n\n* Nouveau : Project window\n* Importer objet rollingTeapot\n* Créer un plane\n* Créer une caméra\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image1.png \"image_tooltip\")\n ou \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image2.png \"image_tooltip\")\n\n\n\n permet de lock la caméra\n\n* Vérifier que l’aces est toujours actif (windows > preferences > color management)\n\n**> Smooth objet plusieurs possibilités**\n\n\n\n* Méthode 1 - preview : sélectionner l’objet > ‘3’\n* Méthode 2 : sélectionner l’objet > onglet Mesh > smooth\n* Méthode 3 - seulement en prévisualisation : attribut editor aller dans l’onglet shape > arnold > subdivision > Type : catclark > itération : 2 \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image3.png \"image_tooltip\")\n\n* Méthode 4 - si pleins d’objets : Cela va venir créer un set dans l’outliner qui correspond à un groupe dont les modifications vont venir être appliqués sur le set donc un ensemble. \n\n onglet Create > Sets > Sets (créé dans l’Outliner un set) > déplacer objets à smooth dans le set de l’Outliner > Attribute editor du set : Arnold / Add (Fenêtre Add Overide Attribute) > Chercher dans la fenêtre ‘aiSubdivType’ + ‘aiSubdivideIteration’ et cliquer sur Add > dans l’attribute Editor du set faire les mêmes manip que la méthode 3 çàd ‘catclark’ et ‘iteration = 2’\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image4.png \"image_tooltip\")\n\n\n\n**> Créer un shader pour mon objet : **\n\nHypershade > créer aiStandardSurface \n\nAssigner mon material à mon objet : sélectionner l’objet > clic droit sur la fenêtre Teapot_grey_mat : Assign\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image5.png \"image_tooltip\")\n\n\nParamètres du shader :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image6.png \"image_tooltip\")\n\n\n**> Visualisation rendu before/after**\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image7.png \"image_tooltip\")\n\n\n \n\n**> Three points lights**\n\nNomenclature : \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image8.png \"image_tooltip\")\n\n\n\n\n* **LIGHT 1 - Key Light : (area light d’Arnold)**\n\nLa key light est la lumière principale, c’est la plus puissante des trois lights.\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image9.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image10.png \"image_tooltip\")\n\n\nOn peut choisir d’utiliser une couleur température ou bien color \n\nNe pas hésiter à montrer l’exposure \n\n\n\n* **LIGHT 2 - Fill light (area light d’Arnold)**\n\nLa fill light atténue les ombres toutes noires. Elle ne doit jamais prendre le pas sur la Key light. Elle donne de l’information de couleur dans les ombres. On peut mettre un couleur bleutée afin d’avoir un contraste. On peut aussi utiliser la même température tant que ça atténue les ombres. Il faut absolument éviter les pixels noirs ! \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image11.png \"image_tooltip\")\n\n\n\n\n* **LIGHT 3 - Rim/Back light (area light d’Arnold)**\n\nLa rim light se trouve derrière mon objet et permet d’ajouter du relief à mon objet pour qu’il se démarque du fond. \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image12.png \"image_tooltip\")\n\n\n**> Light Linking (déconseillé en studio tout ça - la meilleure option c’est les layers)**\n\nPermet de ne plus avoir la rim light qui touche sur le sol par exemple.\n\nWindows > Relationship Editors > Light Linking : light-centric \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image13.png \"image_tooltip\")\n\n\nSélectionner la lumière en question à gauche puis à droite déselectionner ce sur quoi la lumière influence\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image14.png \"image_tooltip\")\n\n\n**> Rendu de Sandy **\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-2/image15.png \"image_tooltip\")\n\n## Cours 3\n\n**I/ AUTOMATISER SES SAVES DE RENDUS : RENDER SEQUENCE**\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image1.png \"image_tooltip\")\n\n\nSe mettre en mode ‘Rendering’ puis chercher l’onglet Render > Render Sequence > appuyer sur le bouton des options. \n\nOptions :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image2.png \"image_tooltip\")\n\n\n**II/ RENDERING SETTINGS**\n\n\n\n1. **File output**\n* **File name prefixe **: définir le nom de son fichier \n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image3.png \"image_tooltip\")\n\n\n\n Il est possible de faire un clic droit dans le champs de texte afin d’ouvrir un menu de balises \n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image4.png \"image_tooltip\")\n\n\n\n Cela permet de créer une arborescence donc des sous-dossiers dans le dossier /img/arnold-moteur-de-rendu/cours-light-3 de notre projet. \n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image5.png \"image_tooltip\")\n balise 1 ‘/’ balise 2\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image6.png \"image_tooltip\")\n la dernière balise est celle qui renomme tandis que les balises d’avant font l’arborescence du dossier\n\n2. **Meta data**\n* **Frame/ Animation ext : **Permet d’incrémenter nos fichiers quand on va rendre des séquences. \n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image7.png \"image_tooltip\")\n\n\n\n Le nom de monfier _#incrémentation.exr\n\n* **Frame padding : **4 (correspond au nombre de 0)\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image8.png \"image_tooltip\")\n\n\n3. **Frame range**\n\nPar défaut il commence à la frame 1 jusqu’à la frame 10\n\nOr, notre image est statique car on veut juste calculer une image :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image9.png \"image_tooltip\")\n modifier end frame à 1\n\n\n\n4. **Renderable Cameras**\n\nBien sélectionner sa caméra\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image10.png \"image_tooltip\")\n\n\n\n\n5. ** Image Size :**\n\nChanger les formats de la caméra \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image11.png \"image_tooltip\")\n\n\nMaintain ratio : après avoir sélectionné la forme (carré rectangle etc)\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image12.png \"image_tooltip\")\n\n\n**III/ LAYERS DE RENDUS**\n\n**Afficher l’onglet Render Layer : **\n\nPreferences > Rendering > Legacy render layers dans preferred render Setup System.\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image13.png \"image_tooltip\")\n\n\n**Créer mes layers**\n\n\n\n* 1 layer obj\n* 1 layer plane \n\nOn commence par créer deux empty (3e icone)\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image14.png \"image_tooltip\")\n\n\nSélectionner tous mes objets (obj + lights + smooth set) dans l’outliner puis clic droit et **add selected object** a mes layers charaLayer et envLayer\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image15.png \"image_tooltip\")\n\n\n**Rendre des objets visibles dans des calques ou non**\n\nIl faut faire un **override **çàd que c’est un paramètre qui va se faire juste sur un seul layer.\n\nSélectionner le calque charaLayer + objet sol > ctrl+A (attribute editor du sol)/Render stats ( ce qui va être calculé au rendu)\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image16.png \"image_tooltip\")\n\n\nSi je décoche le **primary visibilty **: le sol est invisible mais il y’a toujours les rebonds de lumière du sol sur mon objet. Mon sol n’est plus visible mais il a une influence sur la caméra.\n\nLe problème c’est qu’en le décochant ça affecte tous les layers. Si on veut que ça n’affecte qu’un layer faut clic droit > create layer override \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image17.png \"image_tooltip\")\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image18.png \"image_tooltip\")\n\n\nDonc ça veut dire que c’est actif là, donc je peux ensuite le déselectionner \n\nsur mon environnement layer je veux juste sélectionner mon perso > ctrl+a > render stats : override sur primary visibility puis je décoche. Si je fais juste un rendu de mon envLayer on voit que le sol mais avec l’obj de mon perso qui influe sur mon décor.\n\n**IV/ INTRODUCTION AU SAMPLING**\n\nPermet de lisser le grain du rendu final. \n\nRender Settings/Arnold Renderer/Sampling :\n\n\n\n* **Camera(AA) soit Anti Aliasing **\n\n Permet d’éviter l’effet d’escalier dans les /img/arnold-moteur-de-rendu/cours-light-3 en smooth l’image \n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image19.png \"image_tooltip\")\n\n\n\nArnold utilise du Global Illumination : le moteur de rendu renvoie comme dans la vraie vie les lumières. Il s’inspire de la physique de la vraie vie. \n\n\n\n* **Diffuse **\n\n Diffuse en 0 veut dire qu’il n’y a pas de rebonds de lumières dans ma scène\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image20.png \"image_tooltip\")\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image21.png \"image_tooltip\")\n\n\n\n Before/After d’un diffuse à 1 : il y’a un rebond de lumière qui se reflète sur la partie basse de mon objet.\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image22.png \"image_tooltip\")\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-3/image23.png \"image_tooltip\")\n\n\n* **Specular**\n* **Transmission** : transparence\n\n## Cours 4\n\n**Programme :**\n\n* **LES LUMIÈRES DE REBONDS**\n* **VOLUMÉTRIQUES**\n* **LAYERING**\n\n**> QUELQUES FIXATIONS DE PROBLÈMES DE VISU SUR MAYA : **\n\n\n\n* Fixer le fait que la modé disparaisse : sélectionner la caméra au choix (celle que l’on utilise) > attribute editor > Near Clip Plane/ Far Clip Plane\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image1.png \"image_tooltip\")\nCela influe sur la distance où l’on voit l’objet.\n* Focus sur un objet : sélectionné mon objet (face ou object mode) > f \n\n**> NIGHT SCENE INTERIOR TIPS :**\n\n\n\n* **Assigner un mat à mon objet et set ses paramètres**\n\n Commencer par assigner un aiStandardSurface shader à mon objet puis baisser la couleur et baisser la Roughness.\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image2.png \"image_tooltip\")\n\n\n* **Poser la première KeyLight**\n\nPoser une keyLight sur la fenêtre de gauche = “moonLight_Key”. \nLorsque l’on fait une scène de nuit, il ne faut pas penser à ce que ça soit tout noir partout. \nL’area marche moins bien qu’un spot lorsque l’on utilise la volumétrie. Le choix de la light est très importante lorsqu’il s’agit de la keyLight. \n\nLa taille de la scène aussi a une importance, le comportement de la lumière sera forcément différent entre un objet de 2 cm ou 30 cm. \nLorsque l’on modélise de manière réaliste, faire attention à l’échelle de l’objet. (Se créer des repères : Create > Measure Tools) (Pour vérifier l’échelle de maya : Preferences > Settings)\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image3.png \"image_tooltip\")\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image4.png \"image_tooltip\")\n\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image5.png \"image_tooltip\")\n\n\n* **Pour faire ses tests de rendus : **\n\n Options > Test Resolution > 50% Settings\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image6.png \"image_tooltip\")\n\n\n## Gérer les rebonds de lumière :\n\n* Se concentrer sur la fenêtre Render Settings, enlever les paramètres qui ne nous intéressent pas (laisser à 0). \n\nC’est le **Ray depth** qui va jouer sur le rebond. \nOn constate que les noms sont les mêmes dans l’onglet sampling et dans l’onglet ray depth, \nsi on veut utiliser des options du ray depth, activer au moins à 1 ceux de l’onglet sampling. \n\n* Diffuse = couleur, specular = _, transmission = transparence des objets \n\n* Ray Depth \n\nLa lumière tape au sol puis rebondit une seule fois.\n\n**On va créer nous mêmes nos rebonds de lumière :**\n\nPositionner notre nouvelle areaLight (‘bounceLight_01’) au niveau du centre de la lumière de la keyLight afin d’éclairer la zone.\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image7.png \"image_tooltip\")\n\n\n\n Il est plus intéressant de créer nos rebonds de lumières nous même car on a plus de contrôle sur ce que l’on fait.\n\n* **RimLight pour le télescope : **\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image8.png \"image_tooltip\")\n\n\n\nOn constate un souci en dessous sur le sol, la lumière de la spotLight se projette au sol. \nIl faut utiliser un Fall Off : Light Filters qui permet d’ajouter un filtre. On peut utiliser le filtre **aiLightDecay **puis double cliquer sur ce paramètre. \nIl va permettre de définir une zone manuellement où l’on peut mettre de l’ombre de ma lumière comme un masque. Far end permet de définir la zone éloignée où l’ombre sera coupée. \n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image9.png \"image_tooltip\")\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image10.png \"image_tooltip\")\n\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image11.png \"image_tooltip\")\n\n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image12.png \"image_tooltip\")\n\n\n* **Régler les paramètres pour ne pas qu’il y’ai d’ombres brutes :**\n\n Attribute Editor > Arnold > Radius \n\n\n \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image13.png \"image_tooltip\")\n\n\n* **Ne pas monter les Samples au-delàs de 3 dans les paramètres des lights d’Arnold**\n\n Car il visuellement il n’y aura pas de changement drastique et ça augmentera le temps de chargement de l’image.\n\n\n**> VOLUMETRIE**\n\nRender Settings > Environment > Atmosphere : checkeur \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image14.png \"image_tooltip\")\n : Create aiAtmosphereVolume > Cliquer sur l’icône \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image15.png \"image_tooltip\")\n Pour accéder à ses paramètres.\n\n**Créer des Renders layers :**\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image16.png \"image_tooltip\")\n\n\nUn layer volumetricLayer qui contient la keyLight + le décor \n\nUn layer beautyLayer qui contient toute ma scène : aiAtmosphereVolume = 0 > clic droit sur le paramètre Density : Create Override (Density devient orange) et changer les valeurs à celles qui conviennent pour avoir le god rays.\n\n**On aimerait que les rayons soient séparés de mon objet pour ne pas que l’objet renvoit qqch**\n\nCréer un shader ‘matte_black’ et l’appliquer à mon obj. Maya comprend mon assignement de shader à un layer particulier : le volumetricLayer et par conséquent ne va pas changer le shader de mon obj dans le beautyLayer\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image17.png \"image_tooltip\")\n\n\nRésultat : \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image18.png \"image_tooltip\")\n\n\nOn isole les rayons seuls sans qu’ils n’impactent la fenêtre, la pièce etc.\n\n**> LES GOBOS (ombres chinoises)**\n\nMettre une texture en noir et blanc dans une lumière pour simuler une ombre\n\nLight Filters : aiGOBO\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image19.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image20.png \"image_tooltip\")\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-4/image21.png \"image_tooltip\")\n\n## Cours 5\n\n**PROGRAMME DU JOUR :**\n\n\n* Layering\n* Compositing (sur AE)\n\n**Télécharger le plug-in pour AE :**\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image1.png \"image_tooltip\")\n > Installer dans le dossier de plug-ins d’AE \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image2.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image3.png \"image_tooltip\")\n\n\n**AOV (Render Settings):**\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image4.png \"image_tooltip\")\n\n\nN’utiliser que ce qui est nécessaire, par exemple si l’on a un objet transparent, prendre un AOV qui prend en compte de la transparence, sinon c’est pas nécessaire.\n\nPour notre scène actuelle (intérieur) on utilise la diffuse, puis on constate aussi des reflets donc specular. \n\n**Rappel pour la nomenclature de mes fichiers :**\n\nSous dossier ‘Scene’, un deuxième sous dossier ‘RenderLayer’ et pour rappel le nom tout à droite correspond au nom de mes fichiers enregistrer. Donc on veut que mes fichiers aient bien le nom de mes AOV \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image5.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image6.png \"image_tooltip\")\n\n\nChanger aussi les settings Frame/Animation ext : choisir name_#.ext pour qu’il y ait une incrémentation (0,1,2,...) à côté de nos noms.\n\nChanger dans Frame Range la start frame et end frame à 1 parce qu’on à qu’une frame, ce n’est pas une animation ici.\n\nEn dessous changer de caméra en mettant notre caméra de rendu.\n\n**Rendering :**\n\nMode Rendering > Onglet Render > Render Sequence \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image7.png \"image_tooltip\")\n\n\nChanger les paramètres : Current Camera, All Render-Enabled Layers\n\n**Rappel pour avoir des paramètres spécifiques à un calque :**\n\nOn veut supprimer un AOV dans le layer volumetric \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image8.png \"image_tooltip\")\n\n\nLe procédé est le suivant : par défaut tout est enabled > faire un override pour conserver l’enabled pour tous les calques sauf celui qui est overridé qu’on modifiera par disabled.\n\nPour bien trier mes fichiers volumetric : \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image9.png \"image_tooltip\")\n\n\nFaire un override à File name prefix, puis modifier avec les éléments ci-dessus.\n\n**Sur After Effect WORKFLOW :**\n\nOn n’utilise pas de photoshop car AE est un logiciel de compo. Faire la distinction entre retouche et compo.\n\n> Possibilité de directement drag&drop les fichiers à l’intérieur d’AE : \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image10.png \"image_tooltip\")\n\n\n> Organisation des fichiers :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image11.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image12.png \"image_tooltip\")\n\n\n> Retrouver un bon espace colorimétrique sur AE :\n\nClic droit sur mon layer > Interpréter un métrage > Principal \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image13.png \"image_tooltip\")\n\n\nCocher ‘conserver les valeurs RGB’ dans l’onglet gestion des couleurs \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image14.png \"image_tooltip\")\n\n\nEnsuite créer un calque d’effet\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image15.png \"image_tooltip\")\n\n\nRenommer ‘ACES’ \n\nSélectionner dans la comp le calque d’effet > Ajouter l’effet Color io (plug-in dl)\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image16.png \"image_tooltip\")\n\n\nModifier les paramètres de cet effet\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image17.png \"image_tooltip\")\n\n\nEt aller chercher le config.cio soit le plug-in téléchargé au deuxième cours.\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image18.png \"image_tooltip\")\n\n\nModifier les valeurs par rapport à ce qu’on a comme donné dans maya : \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image19.png \"image_tooltip\")\n\n\nDonc Input Space: ACESrg\n\nOutput Space : Output - sRGB\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image20.png \"image_tooltip\")\n\n\nOn récupère alors les bonnes couleurs de notre compo sur AE ! : \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image21.png \"image_tooltip\")\n\n\n[Manipulation à appliquer à chaque éléments Layers de notre compo]\n\n> Bits\n\nPlus on augmente les bits, mieux c’est.\n\nPar défaut, un exr nous sort une valeur en 32 bit donc best, le seul défaut est son poid \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image22.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image23.png \"image_tooltip\")\n\n\n> Utiliser les modes de fusion en compositing : \n\ndiffuse (couleur) \n\nspecular (reflets) \n\nLa beauty est en fait la fusion entre diffuse et specular \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image24.png \"image_tooltip\")\n\n\nOn fait la même chose mais avec des AOV indirect et direct de la specular et la diffuse. On fait un rendu pour avoir mes exr dans mes fichiers organisés.\n\nOn supprime dans ma comp la specular et la diffuse pour les remplacer par :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image25.png \"image_tooltip\")\n\n\nNe pas oublier de changer le mode de fusion en Addition pour tout sauf la diffuse direct \n\nTips pour voir en détail le calque en augmentant sa luminosité :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image26.png \"image_tooltip\")\n\n\n**Masques : Cryptomat par exemple**\n\nIl est possible de faire des masques d’objets 3D :\n\nOn assigne des couleurs RVB qu’on convertis en sélection ce qui va faire qu’on peut sélectionner plusieurs parties de l’image.\n\nAujourd’hui il existe les cryptomatte qui permettent d’isoler chacun des objet de la scène.\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image27.png \"image_tooltip\")\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image28.png \"image_tooltip\")\n\n\n> La méthode à la main pour faire des sélections d’objets : \n\nCréer un nouveau calque de rendu ‘matteRGBLayer’\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image29.png \"image_tooltip\")\n (ici tout est déselec à part mon nouveau layer)\n\nMettre tous les éléments de la scène dedans (voir la procédure à 16:h30 pour séparer mes objets)\n\n> Smooth : \n\nSauf qu’attention il a perdu le smooth : sélectionner tous les mesh > Select > Set > ‘Smooth_set’ > ctrl+a : Arnold : Add : aiSubdivType et SubdivIteration. \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image30.png \"image_tooltip\")\n\n\n> Créer un shader R, V et B \n\nAller dans l’HyperSahde : créer un Surface Shader *3, un rouge un bleu et un vert.\n\nNe pas oublier de renommer\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image31.png \"image_tooltip\")\n\n\nChanger les valeurs par 255 car le ACES les a modifié \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image32.png \"image_tooltip\")\n\n\nNomenclature :\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image33.png \"image_tooltip\")\n\n\n> Assigner les shaders \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image34.png \"image_tooltip\")\n\n\nPermet de choisir la sélection : des objets, caméras etc\n\nAssigner à ma scène obj : matte_black soit mon surface shader noir \n\nMaintenant on veut créer un masque pour mon téléscope : sélectionner à la main puis assigner le shader bleu\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image35.png \"image_tooltip\")\n\n\nOn va créer un override pour la nomenclature dans les render settings ainsi que _\n\n**Sur after effect** \n\nPour avoir les dernières modifications de mes fichiers: tout sélectionner mes fichiers : recharger le métrage \n\nMettre le matteRGB Layer:\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image36.png \"image_tooltip\")\n\n\nSélectionner mon layer telescope (duplication du layer beauty qui a été rename)\n\nAjouter l’fx ‘Appliquer un cache’\n\nOn veut qu’il récupère l’information depuis le matteRVB layer \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image37.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-5/image38.png \"image_tooltip\")\n\n\nSélectionner à partir du calque : matteRGB Layer et utiliser comme cache : bleu \n\n\n## Cours 7\n\n\n\n\n### **LES METHODES DOF 3D :**\n\n**POUR AVOIR UN FOCUS SUR UN OBJET **(même si la caméra change de place) \n\n\n\n* Méthode 1 \n\n1/ mettre deux locators (nearLocator et farLocator) \n\n2/ en assigner un à caméra et un autre à mon objet (tips pour snap : v + middle button mouse) \n\n\n\n* Méthode 2\n\n1/ sélectionner nearLocator puis camera (ou l’inverse pour constraint) et aller dans (onglet animation) Constrain > Parent \n\n> Les paramètres de constraint : \n\n\n\n* Aim : suivre la direction en restant statique (comme pour un regard) \n\nManip à faire dans l’Outliner : Display > Shapes (ok) \n\nOn veut connecter des attributs sur des objets, soit ici distanceDimension dans mon Outliner et le Focus distance de ma renderCam. \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-7/image1.png \"image_tooltip\") \n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-7/image2.png \"image_tooltip\") \n\n\n(je crois qu’il y’a encore d’autres manip à faire ici 15h15) \n\n/!\\ aux problématiques en compositing on peut s'apercevoir que c’est pas bon une fois que c’est rendu. C’est pourquoi il est possible de le faire en compositing. \n\n\n### AOV DE Z - DOF\n\nAOV de Z encode la profondeur de la scène par un dégradé allant de blanc jusqu’au noir. En compo on récupère ses valeurs et on dit : plus c’est blanc plus c’est net, plus c’est noir plus c’est flou.\n\nRender settings > AOV > AOV Browser > double clic ou double flèche pour ajouter Z de gauche à droite.\n\nIl est aussi possible de faire du Fog avec !\n\nQuand on importe sur after effect, il la met en non remappé c’est pourquoi c’est tout blanc. si on test en baissant l’expo, on constate que ça marche bien. \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-7/image3.png \"image_tooltip\")\n\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-7/image4.png \"image_tooltip\")\n\n\nOn va du coup faire les manipulations pour bien le mettre :\n\nCréer une précomposition de mon calque z > Ajouter un effet exposition \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-7/image5.png \"image_tooltip\")\n\n\nOn veut appliquer l’effet de profondeur de champ sur l’image maintenant.\n\nAttention celui d’AE il est pas ouf pour la DOF (utiliser un plug-in lenscare si possible car mieux [https://www.frischluft.com/lenscare/](https://www.frischluft.com/lenscare/) )\n\n### DOF sur AE avec l’AOV Z :\n\n \n\ncalque d’effet ‘DOF’ > effet ‘flou objectif appareil photo’ > link le calque d’effet DOF à ma Z \n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-7/image6.png \"image_tooltip\")\n\n\n\n\n### 2. AOV DE Z - PROFONDEUR ATMOSPHÉRIQUE / FOG VOLUMÉTRIQUE\n\n1/ Sur la precomp Z ajouter un effet niveaux et changer les courbes\n\n2/ Mode de fusion : Additif ou Écran \n\n3/ Ajouter à ma precomp Z un effet de teinte\n\n4/ Baisser l’opacité de mon calque precom Z\n\n\n![alt_text](/img/arnold-moteur-de-rendu/cours_light_aime/image7.png \"image_tooltip\")\n\n### II. MOTION BLUR\n\nActiver le Motion Blur en animation sur Maya : \n\nRender Settings > Arnold Renderer / Motion Blur > **Enable** \n\nActiver l’option **Deformation **pour déformer l’objet \n\nActiver l’option **Camera **pour les mouvements de camera \n\nActiver l’option **Shader **en cas de texture animé \n\nLes **Keys** c’est si on l’a un objet qui bouge dans tous les sens (zigzag, hélice, etc) pour avoir un **effet de traînée**. Augmenter > 2.\n\nTout pareil pour Lenght. 0.5 c’est un bon point de départ.\n\n**Position**- **Center of Frame** : \nVa faire une interpolation avec la frame actuelle et la frame d’après. Il va en faire un mélange pour venir floutter en faisant une moyenne des trois \n\nAméliorer les mouvements pixellisés avec l’Anti Aliasing (Render Settings > Arnold Renderer > Camera AA)\n\n## texture et displacement\n\nMême si bump c’est sympa, on se rend compte en changen d’angle que tout reste plat avec un bump 2D\n\nOn a une meilleur impresion avec bump 3D mais ça passe mieux\n\nLe 3e marche mieux parce qu’il va se mettre dans le displacement\n\nLe map de displacement ca se fait dans les logiciels de sculpt.\n\nThe arnlold bounding box can limit the bump map donc il faut parfois augmenter le bounds padding: \n![alt_text](/img/arnold-moteur-de-rendu/cours_light_aime/image1.png \"image_tooltip\")\n\n\nVector displacemenent\n\n## Displacement \n\nutiliser des EXR car il il y a 32 bit de donné a la place de 8bit sur un png.\n\nQuand on est en ACES il faut changer le mode de hdr : \n**linear Utility**\nou \n**linear raw**\n\n![alt_text](/img/arnold-moteur-de-rendu/cours-light-9/linear_srgb.jpg \"image_tooltip\")\n\nPour les texture linear \n![alt_text](/img/arnold-moteur-de-rendu/cours-light-9/srgb_utilities_srgb-texture.jpg \"image_tooltip\")\n\nOn peut automatiser cela avec les paramètre de texture.\n\n\n## Rendu réaliste \n\nIl est important lors d'un rendu réaliste de faker la réalité commune. \nNotre oeil est habitué à la vidéo sur caméra et lorsque que l'on veut faire un rendu réaliste il faut y rajouter les effets qu'une caméra a ! \nLorsque l'on fait un rendu 3D, le logiciel sort une image dite *parfaite* , et notre but est de la rendre réaliste, donc d'y aouter ces default.\n* Aberration chromatique\n* Grain\n* Vignetting\n* Lensflare\n* Deformation de lentille\n* effet de compression\n* motion Blur\n* profondeur de champs (bokeh)\n* Exposition\n\n\nSi vous voulez d'autre info c'est ici :\nPdf du cours de light\n\n### AOV\n\n\n\nLien vers le model\nAlgorithme du rubics cube expliqué.\n
\n\n**Une rotation = 3 opérations mathématiques = rotation en xyz**\n\n* X - Rotation du cube vers la face droite\n* Y - Rotation du cube vers la face haute\n* Z - Rotation du cube vers la face avant\n\n## ANGLE D’EULER\nL’Angle d’Euler permet de faire des rotations dans n’importe quelle ordre.\n
\n\n![matrice et l'origine](/img/matrices-base/astrolabe.gif) \nExemple : Astrolabe \n\nPour réaliser il faut verrouiller les positions des axes.\n*Dans maya : Clic droit sur l’outil rotation > Gambal*\n![lockselected.JPG](/img/matrices-base/lockselected.JPG)\n*Le Gambal Lock verrouille sur une des rotations ce qui ne nous permet plus de ne plus pouvoir la manipuler.* \n\n\n## QUATERNIONS\n\nBeaucoup de gens disent qu’une Quaternion est le fait d’avoir une rotation par rapport à un axe → c'est faux ! \nOn peut trouver une correspondance effectivement mais le quaternion ce n’est pas ça ⚠.\n\nIl est difficile de s'imaginer les rotations dans un espace 3d, car en fonction du point de vue cela peut paraitre simple. \nPar exemple notre sytème solaire :\n
\n\n
\nSi nous prennons le soleil comme point de vue cela nous est facile. \nMais imaginons maintenant le point de vue d'une lune qui tourne autour de la terre. Nous aurons beaucoup plus de problème a nous l'imaginer. \n\nC'est pour cela que nous allons utiliser les quaternions, qui nous permet de changer de point de vue, et de passer d'un espace 3 dimensions a la 4ème dimensions.\n\n**Les quaternions sont des nombres hypercomplexes**\n
\nN’importe quelle rotation peut être résumée en 1 seul chiffre hypercomplexe ⚠\n
\n\nUtilisation du **quaternion** : \nLes quaternions unitaires fournissent une notation mathématique commode pour représenter l'orientation et la rotation d'objets en trois dimensions. Comparés aux angles d'Euler, ils sont plus simples à composer et évitent le problème du blocage de cardan. \n**Exemple :**\n```python\ni est un nombre imaginaire.\ni² = -1\n3i² = -3 = 3*i²\n(2+3i)² = (2+3i)*(2+3i)=2²+2*2*3i+3i²=4 +12i² -3 = 1 + 12i\nX => cosx + sinxi\nY => cosy + sinyi\nZ => cosz + sinzi\n```\nLes quaternions sont des nombres giga complexes.\ni j et k sont des nombres imaginaires, les trois ensembles sont les quaternions ijk\n```python\ni² = j² =k² = ijk = -1\n```\nN’importe quelle rotation peut être résumée en 1 seul chiffre hypercomplexe.\n* i le nombre imaginaire pour l’axe X\n* j le nombre imaginaire pour l’axe Y\n* k le nombre imaginaire pour l’axe Z\n\n**Exemple :**\n```python\n4 + 3i - 2j + 6k # est un quaternion, donc une rotation dans l’espace.\n```\n* (+) Permet de résoudre des problèmes de rotations.\n* (-) Peu voir illisible.\n\nBeaucoup d’avantage avec quaternion mais assez illisible. \nGénéralement, si un jour il y a plein de rotations qui posent pb, il faut passer aux quaternions\n\nL’un des meilleurs algorithmes de skinning est basé sur du dual quaternion !\n\n\n## Slerp et Lerp\n\nToute rotation peut être représenté sur une droite \n
\n\n![lerp & slerp](https://pbs.twimg.com/ext_tw_video_thumb/1176137452228108289/pu/img/LJabgJX0bmt_uLPk.jpg)\n\n
\n* Le slerp = je traverse sur la sphère\n* Le lerp = je fais un trou pour traverser\n\n
\n\n![lerp & slerp](/img/matrices-base/lerp_slerp.JPG)\n\n\n## Différentes technique de modélisation pour les objets 3d\n\nIl existes de nombreuses techniques de modélisation. Chacune dépends des cas d'utilisation pour être utile. \n\n### La modélisation Volumétrique → Voxels\n\n* (+) Très utile pour l'architecture( par exemple les simulations de destruction) car l'ordinateur calcule le volume de la structure.\n* (-) Plus gourmand en performance\n\n### Les Nurds (bezier 3D)\n\nLes Nurds ou courbes de bezier sont des courbes en formule mathématique. Cela repose sur un algorithme avec les courbes de bézier → idée qu’en fait il y a un point et d’avoir un autre point lié pour faire la direction de la courbe\n* (+) Sont plus légé que les polygone\n* (+) Puisque c'est des formules mathématiques c'est plus modulable et pas de problème de poids car les nurds sont plus légers à stocker que les polygones(comme dans illustrator ou en **svg**) \n* Comme les nurbs sont des surfaces mathématiques c'est intéressant par exemple pour les choses à grande echelle ou pour placer des objets sur les autres\n* (-) Formule mathématique -> certaines forme sont très complexe a exprimer en mathématique\n\nIl existe sur maya un outil qui permet de lié les nurds en faces : \n![nurds](/img/matrices-base/nurds.JPG)\n\n### Méthode Polygones\n\nUn polygone → vertex , faces et arêtes. **Un objet est un ensemble de point qui forme des triangles qui forment des face** \n(lire Digital Scuplt de Bay Raitt)\n
\n\n(≠ graphe) qui possède des vertex, des faces et des arêtes. Cette méthode est le \"faux polysmooth\" de maya (lorsque l'on appuis sur 3). \n⛔ Ne pas utiliser cette méthode dans le rendu final car cela peut créer des nsoucis de modélisation lors du rendu. Elle peut être par contre pratique pour visualisé facilement.\n\n## Méthode de détection de collisions\n\nBounding box/ Bounding sphere/ Maille simplifié convexe (convex box (?))/ Convex Mesh/\nSPRITE en 2D \n
\n\n### Bounding box\nC'est un cube invisible que l’on met autour d’un objet complexe pour simplifier sa forme et pour permettre de gérer plus facilement les collisions et l'espace qu'il prend. \n\n![nurds](/img/matrices-base/boundingBox.JPG)\n\n### Bounding sphere\nRayon à partir du centre d’un objet complexe pour déterminer un périmètre pour simplifier sa forme et pour permettre de gérer plus facilement les collisions et l'espace qu'il prend. (même chose que bounding box mais c'est une sphère)\n\n### Convex Mesh\n\n![nurds](/img/matrices-base/convex.JPG)\n![nurds](/img/matrices-base/concavevsconvex2d.jpg)\n\nconvex cube c’est presque une boule(rouge = cube, vert = cube convex)\nConvex : extérieur / Concave : intérieur (?)\n\nWhat is the difference between Concave and Convex?\n\n\n\n## Normal Map\n\n\nOn peut mettre une infité de cartes **UV** sur un objet\nChaque couture a au moins 2 coordonnées **UV**\n\nQu’est ce qu’une normale ? Un axe perpendiculaire à la surface\nQue peut-on faire avec les normales pour savoir ou sont les contours ? C’est obtenir le moment de la bascule (dans maya c’est Sampler Info)\nUne carte (info stockée dans un endroit précis sur la maillage) ne sert pas que pour le rendu\n\n* Normal = Axe perpendiculaire à la surface. Si la normale pointe vers la cam alors elle est visible sinon inversement \n\n![Normal](/img/matrices-base/normal.JPG)\n\n\n* Normal map = Déformation de l’information de la normal pour avoir la normale voulue. C’est une illusion optique car ce n’est qu’une seule face. \n\n![normal map](/img/matrices-base/normal_map.png)\n\n* Parallaxmap = Le parallax mapping est une technique de rendu d'image de synthèse tridimensionnelles, utilisant des normal map en plus des textures diffuses afin d'émuler le relief de ces dernières. \n\n![paralax map](/img/matrices-base/paralaxmap.JPG)\n\nLes maps nous offres beaucoup de possibilité. \n* En **démo** une technique consiste de simuler de la lumière garce a 2 normalMap que l'on va mixer en 2 pour simuler de la fausse ombre -> Gain énorme de performance.\n* En **photogramétrie** on peut récupérer les maps des gens scanner pour les mixers pour créer des visages différents...\n\nCe n'est que 2 exemples de toutes les possibilités que les maps nous offres 😵\n\n\n**En gros :**\nLa normal maps c'est noté le decallage de la map que j'aurais aimer avoir et celle que j'ai.\n\nLes polygones ont une structure qui repose sur des graph\nOn a à notre dispo des coordonnées **UV** → avantage pour stocker des infos (info de tout genre) → si je fais un tissu et que je veux savoir s’il est solide (par exemple)\nOn a plusieurs niv pour calculer des collisions et on peut faire nos propres mesh → mix entre nurbs et polygones\n\n\n\nSi vous voulez un bon article : Différences entre normal map, bump map et displacement map\n\n\n## Revoir les bases des matrices\n\nDans un environnement 3D, les matrices permette de placer les différents élement d'une scène. \n\n* Une matrice = tableau\nToute les images utilise des matrices !\nLes vecteurs utilise les matrice -> un tableau a 3 cases \n\n* |**matrice origine**\n\n\n### Comment utiliser les matrices ?\n\n```python\nMatriceA * MatriceB ≠ MatriceB * MatriceB\n```\n\n![matrice-1](/img/matrices-base/matrice-1.png)\n![matrice-2](/img/matrices-base/matrice-2.png)\n\n\nPour les matrice a 2 vecteur et 3 vecteurs\n\n### **Matrice identitaire**\n\nMatrice identitaire = C’est une matrice carré avec des 1 en diagonale et 0 le reste. \n```python\n# matice identitaire : \n[1 , 0 ]\n[0 , 1 ]\n```\n\n### Matrices symétriques \n\n![symetrie](/img/matrices-base/symetrie.JPG)\n\n```python\n# matrice de symétrie en X\n[-1 , 0 ]\t\n[0 , 1 ]\n\n# matrice de symétrie en Y\n[1 , 0 ]\t\n[0 , -1 ]\n\n```\n\n### **matrice de taille**\n![img matrice](/img/matrices-base/scale_matrice.JPG)\n\n```python\n[3 , 5 , 4]\t\t\t[9 , 0 , 2]\n[7 , 0 , 2]\t\t\t[5 , 3 , 1]\n[1 , 8 , 6]\t\t\t[1 , 6 , 7]\n\n# matrice résultat :\n[(3*9+5*5+4*1) , (3*0+5*3+4*6) , (3*2+5*1+4*7)]\n[() , 5 , 4]\n[3 , 5 , 4]\n\n\n# matrice de scale de 2 en X \n[2 , 0]\t\t[-4]\n[0 , 1]\t\t[3]\n\n# résultat\n[-8]\n[3]\n\n```\n\n### **matrice de rotation**\n\n![img matrice](/img/matrices-base/matrice_rotation.JPG)\n\n\n```python\n#Matrice de rotation\n[0 , 1]\t\t[-4]\n[1 , 0]\t\t[3]\n\n# résultat\n[3]\n[-4]\n```\n\n### **matrice de deplacement**\n\n\n\nSur maya il exite la command Xfrom pour utiliser les matrices \nLien de la doc\n
\nLien d'un bon tuto\n \n\nQuand il faut faire des calcules de matrices 3D -> Matrices4x4\n\n**Toute les cartes graphique utilisent des matrices 4x4 pour leurs calcules !!!**\n\n### Matrice d'image\n\n* Une image est composé d'une matrice 4x4 -> RGBA\n\n![img matrice](/img/matrices-base/rgba.JPG)\n\nIl est possible de prendre n'importe quel tableau a plusieurs dimensions pour le mettre en 1.\n\nUn ordianteur \"déplie\" les tabelau sur l'écran ce qui créer les pixels de l'écran !\nCe qui permet de plus facilement accéder au data qui si il était en plusieurs dimensions\n\nComment les données de ce même tableau sont stockées en une seule dimension : \n\nmatrcie en 2 dimension déplier \n
\n\n\n#### Formule 2 dimensions\n\n```python\nLigne*largeurimage + colonne\n```\n
\n\n\n## Matrice/Couleurs\n\nUne couleur correspond à un vecteur à 3 valeurs : RGB \n\n![img matrice](/img/matrices-base/img_matrice.JPG)\n\n* => Toute matrice à n dimension peut être ramenée à une matrice à 1 dimension.\n\n![img matrice](/img/matrices-base/3d_tab_array.JPG)\n\n### Formule 3 dimensions\n\n![img matrice](/img/matrices-base/tab_explication.jpg)\n\n```python\nprofondeur * largeurimage * hauteurimage + ligne * largeurimage + colonne\n# pour tableau\n# soit n nombre dans le tableau\nPr * Li * H + l(n) * Li + c(n)\n```\n![matrices_3D](/img/matrices-base/matrices_3D.JPG)\n![matrice_rgb_pixel](/img/matrices-base/matrice_rgb_pixel.JPG)\n\n=> équivalent à 12 Octets. \nZ-buffer → stock la profondeur d’un pixel\n\n\nLien d'un bon tuto 4ème dimension\n\n\n\n\n\n\n\nLes matrices sont très importante en particules !! \n\nProblème stocker les particules en fonction du temps :\n\n
\n\n```python\nprofondeur * largeurImage* hauteurImage + ligne * largeurImage + colone\n```\n\n\n\n","data":{"title":"Les bases des matrices","description":"Comprendre les matrices et son environnement 3D","publishedAt":"2021-10-10","imageLink":"https://media.sketchfab.com/models/4cc7c1bf585f4b929ddd32f6cab3ba58/thumbnails/76823bf8cae04f1ea9fa5fe2bee2542a/302b1593a29c41e396216f081d82f59d.jpeg","tag":["Matrice","algoritmie"]},"filePath":"matrices-base.mdx"},{"content":"\n## Sommaire\n\n\nThis is a tutorial to import your script in maya. All the code of the project are in my github here\n\n1. [Problematic](#Problematic)\n2. [Maya and path not a good love storie](#Maya-and-path-not-a-good-love-storie)\n3. [Solution](#Solution)\n\n## Video \n\n\n\n\nA retenir pour les UV :\nDécocher cette option lors de l'unfold :\n![unfoldEdege](/img/maya-modelisation/unfold_edge.JPG)\n\n\n## Principe de Uv & Udim\n\nEn modélisation pour appliquer des textures (image 2d) sur notre objets 3d il nous faut le déplier.\n\n![uv déplier](https://upload.wikimedia.org/wikipedia/commons/f/fe/Cube_Representative_UV_Unwrapping.png)\n\n\nVoici une superbe vidéo qui récap une grande partie des processes de la techniques des UV :\n\n\n\n\nPour gagner du temps lors de la séléction de notre objet on peut utiliser la symetrie :\n\n![symétrie](/img/maya-modelisation/symetrie.JPG)\n\nOn peut séléctionner les edges mais aussi les faces puis y récupérer le périmetre pour gagner du temps !\n![symétrie](/img/maya-modelisation/edge_parameter.JPG)\n\nPuis ensuite cut et Unfold !\n\n\nPour voir si nos UV ne sont pas distordu on peut vérifier en regardant ici :\n![symétrie](/img/maya-modelisation/uv_distorsion.JPG)\n\n* Blanc -> 👌\n* rouge -> comprésser \n* bleu -> trop amples\n\nremettre ensemble certaine partie :\n![assembler](/img/maya-modelisation/stichTogether.JPG)\n\n\nGerer les tiles :\n![gerer les tiles](/img/maya-modelisation/tilesU.JPG)\n\ntexel density :\n* get part of reference \n![gerer les tiles](/img/maya-modelisation/texelDensity.JPG)\n* selectionner tout et appuyer sur set\n![gerer les tiles](/img/maya-modelisation/settexel.JPG)\n\n\nLors de l'importation des textures en Udim sur subtance painter, il faudra bien cocher que l'on utilise des UDIM !\n\n\n## Documentation pour les UDIM\n\nUDIM Workflow\n\n\nPour checker si nos UV sont bon :\nTéléchager des UDIM et checker en les assignant a votre model. Voir si vos UV ont la même tales c'est bon !\n\nhttp://uvchecker.byvalle.com/\n\n \n
\n\n\n\n## Faire Uv d'un élement\n\nPour créer correctement des UVs, il faut choisirs les endroits moins visibles de notre objets. Dans notre exemple je vais utiliser les le coté pointue de ma lame.\n\nAprès avoir ouvert l'Uv editor je peux assembler mes cuts grace au layout.\n\n![animation snashot](/img/maya-modelisation/layout_maya.JPG)\n\n\n\n## Commprendre les Seems :\n\n