Transcription
1. Code a Lava Lamp: Salut, je suis Isaac et je fais des jeux Innkeeper. Dans cette classe, nous allons créer une lampe à lave entièrement numérique en utilisant des shaders et le moteur de jeu Godot, qui est un moteur de jeu libre et open source. Le but ici est le jeu et l'expérimentation. Il y a des tonnes de possibilités pour votre lampe à lave pendant que vous le codez et après le fait. Vous pouvez modifier des choses comme la taille et la vitesse des blobs, la couleur d'arrière-plan, les couleurs de premier plan, les dégradés, la lueur de chaque blob individuel, ainsi que la base elle-même. Nous allons écrire notre code de lampe de lave en utilisant le langage d'ombrage Godot, qui est très similaire à GLSL, le populaire langage d'ombrage OpenGL. À la fin de la classe, nous créerons un GIF en boucle transparente de
votre projet de lampe à lave à partager dans la galerie du projet et ailleurs. En prime, je vais même vous montrer comment vous pouvez garder votre lampe de lave en marche sur votre bureau. Cette classe sert d'introduction aux shaders de fragment 2D, qui sont souvent utilisés dans le développement de jeux pour obtenir effets visuels
soignés qui s'exécutent rapidement via le traitement parallèle. Être capable d'écrire des shaders est une compétence précieuse qui peut ajouter beaucoup de flair à vos projets de jeu, et après avoir créé votre lampe de lave, vous aurez une assez bonne compréhension de leur fonctionnement. Je ferai attention à expliquer chaque étape en détail, mais une expérience antérieure avec le codage ou moteurs de
jeu en général serait très utile pour votre compréhension. Si vous rencontrez des problèmes, veuillez me le faire savoir dans l'onglet Discussions et je serai sûr de vous aider. Avec ça, commençons. Assurez-vous de me suivre ici sur Skillshare pour plus de cours de développement de jeux comme celui-ci. Dans notre première leçon, nous allons observer une vraie lampe à lave pour comprendre comment nous allons l'émuler avec notre code shader.
2. Observer une référence de lampe Lava Lamp: Jetons un coup d'oeil à cette lampe à lave pour référence avant de commencer à coder. Premièrement, la lave se sépare en un blobs sphériques distinctifs, s'étirant, se séparant et fusionnant ensemble. Nous allons utiliser quelque chose de similaire aux métaballs pour obtenir cet effet. Deuxièmement, la lave a tendance à couler rapidement, vers le haut ou vers le bas, ralentir lorsqu'elle atteint un point d'extrémité et finalement à changer de direction. Nous allons examiner certaines fonctions mathématiques qui oscillent comme ça au fil du temps. Troisièmement, la lave est vraiment
brillante en bas et une couleur complètement différente en haut. Il semble briller un peu. Nous pouvons essayer d'utiliser quelques gradients ici pour imiter cet effet. Quatre, de même, la solution d'alcool est la plus brillante sur les bords de la lampe et plus sombre au milieu. Encore une fois, nous pouvons essayer d'utiliser des gradients ici. Nous garderons ces idées à l'esprit lorsque nous commencerons à coder. Dans la prochaine leçon, nous allons télécharger et configurer Kidlo pour que nous puissions commencer.
3. Configurer le moteur: Dans cette leçon, nous allons télécharger le moteur et mettre en place un projet de base. Si vous n'avez pas encore le moteur de jeu Godot, vous pouvez l'obtenir sur Godotengine.org, cliquez sur Téléchargements et trouvez le téléchargement qui correspond à votre système d'exploitation et à votre architecture système. Vous pouvez également télécharger le moteur à partir de Steam. Si vous le faites, il sera livré pré-chargé avec un tas de démos que vous pouvez vérifier pour voir comment fonctionnent les projets de base. Allez-y et faites tourner le moteur si vous ne l'avez pas déjà fait. Si vous avez téléchargé l'image Godot à partir du site Web, une fois que vous l'avez extraite du fichier zip et que vous essayez de l'exécuter pour la première fois, vous risquez de rencontrer un avertissement de sécurité de votre système d'exploitation. Sous Windows, vous pouvez rassurer Windows Defender en appuyant sur plus d'informations, puis en exécutant quand même. Godot est un logiciel open source, donc vous pouvez lire le code vous-même si vous le souhaitez. C' est le chef de projet de Godot. Si vous téléchargez le moteur de Steam, vous trouverez un tas de démos ici. Depuis que j'ai téléchargé le moteur à partir du site, je n'ai encore rien ici. Je vais appuyer sur ce bouton Nouveau projet à droite. Je voudrais que ce projet soit sur mon bureau donc je vais taper bureau ici. Vous devrez peut-être appuyer sur ce bouton « Parcourir » pour trouver un dossier dans lequel vous souhaitez placer votre projet Godot. Godot dit, « Veuillez choisir un dossier vide, » parce qu'il pense que je veux mettre les fichiers directement sur mon bureau. Il voudrait mettre des choses comme mes sprites et mes textures juste à côté de la poubelle de recyclage, ce qui n'est pas ce que je veux. De toute évidence, le bureau n'est pas vide. Il contient, au moins, le raccourci de la corbeille de recyclage. Je vais taper Lava Lamp dans la section du nom du projet et appuyez sur ce bouton pratique « Créer un dossier », et maintenant Godot a créé un dossier appelé Lava Lamp sur mon bureau afin que tous les fichiers de projet pour ce projet puissent vivre directement dans ce dossier. Puisque je n'ai pas besoin de cette application pour s'exécuter dans un environnement Web, je vais laisser l'option de rendu par défaut. Dans la leçon suivante, j'appuie sur ce bouton et nous allons créer notre structure de projet et commencer à écrire notre code de shader.
4. Créer un Sprite et un shader: Dans cette leçon, nous allons mettre en place une structure de projet et commencer à écrire du code Shader. Je vais appuyer sur le bouton « Créer et modifier ». Voici l'éditeur Godot. Au milieu, vous verrez essentiellement une représentation de la scène actuelle que vous créez. Ici, à gauche, nous avons la possibilité de créer le nœud racine pour cette scène. Dans Godot, les nœuds représentent de petits blocs de construction de jeux. Ce sont des nœuds pour créer des images, des caractères, des éléments d'interface utilisateur, des animations, etc. Puisque nous nous concentrons sur l'écriture d'un Shader pour ce tutoriel, nous n'avons pas vraiment besoin de beaucoup de nœuds, mais nous avons besoin d'au moins un nœud auquel nous pouvons appliquer notre Shader. Ce nœud devrait également dessiner notre base de ligne de niveau lorsque nous arrivons à cette étape. Nous pouvons écrire des Shaders 2D via des matériaux pour n'importe quel nœud héritant d'un élément Canvas. Pour vous montrer ce que sont ces nœuds, je vais appuyer sur « Autre nœud ». C' est un arbre entier qui se
compose finalement de tous les nœuds que Godot a à offrir. Nous recherchons des choses qui héritent de l'élément Canvas. Les éléments qui existent sous ce menu déroulant appelé élément Canvas. Je vais aller pour Node2D et tout le chemin au fond Sprite, parce que je veux aussi rendre la base de la lampe de lave et ensuite rendre notre Shader dans une partie spécifique de la base. Je vais appuyer sur « Créer » pour faire un Sprite. Maintenant, vous pouvez voir que j'ai ce Sprite
ici sur la gauche comme nœud racine de ma scène actuelle. Ici, sur la droite, nous avons accès à
plus de propriétés pour le nœud que nous venons de créer. En haut, vous pouvez voir ce sont des propriétés qui sont spécifiques au nœud Sprite, juste en dessous de ce que nous avons des propriétés qui sont spécifiques à tous les Node2D, et étant que nous avons des propriétés qui sont spécifiques à tous les éléments Canvas. Bien sûr, encore une fois, tous les nœuds. Encore une fois, c'est parce que si nous revenons en arrière et regardons l'arbre, nous avons un nœud en haut de l'arbre, élément
Canvas en dessous de cela, et Node2D en dessous. Ce sont les propriétés de Sprites, ce sont les propriétés de Node2D, ce sont les propriétés des éléments Canvas et ce sont les propriétés de tous les nœuds. Je vais appuyer sur « Annuler » parce que je voulais juste te montrer l'arbre. Depuis que j'ai créé un nœud 2D comme nœud racine pour la scène, Godot nous a automatiquement basculé vers la vue 2D. Cette boîte bleue représente ici la taille de l'écran qui
se produira lorsque j'appuie sur « Play » pour déboguer le jeu. Vous pouvez voir que j'ai sélectionné le Sprite, donc ce réticule représente ici l'emplacement actuel du Sprite. Il ne rend actuellement aucune texture, et vous pouvez le voir en voyant aussi que la texture est vide. Je vais faire glisser icon.png dans la propriété Sprite, et maintenant vous pouvez voir que icon.png est rendu comme texture de ce Sprite. Nous allons juste utiliser icon.png temporairement pour voir comment fonctionne Sprites et aussi pour écrire notre premier code Shader juste pour écraser la texture de base. Vous pouvez voir que le nœud Sprite s'étend désormais en dehors de la boîte bleue que nous avons créée. Vous pouvez voir que le Sprite s'étend désormais en dehors de la région, marqué par la boîte bleue, ce qui signifie que beaucoup de cela ne sera pas réellement rendu à l'écran. Je vais lancer le jeu en appuyant sur le bouton « Jouer ». Il va se plaindre parce que je n'ai pas mis de scène principale. Parce que c'est un projet très simple pour les démonstrations Shader. Pour sauver mon travail, je vais faire « Control S ». Vous pouvez faire « Command S » si vous êtes sur un Mac. Pour sauver mon travail jusqu'à présent, je vais aller à Scène et appuyer sur « Enregistrer la scène ». Puisque je n'ai pas sauvegardé cette scène avant, ça me demande un nom. Je vais juste l'appeler lamp.scn et appuyer sur « Enregistrer ». Vous pouvez également voir que lamp.scn est apparu dans les fichiers du projet. Si j'appuyais sur « Play » ici, Godot m'avertirait que je n'ai jamais défini de scène principale. C' est parce que la façon dont les jeux sont généralement structurés dans Godot, ceux sont la racine vu que le jeu fonctionne comme la chose fondamentale que toutes les autres scènes dans les nœuds sont des enfants de. Nous n'en avons pas encore défini un, nous devons donc le sélectionner. Je vais à nouveau choisir lamp.scn que nous venons de créer, et appuyez sur « Ouvrir ». Parce que par défaut l'origine d'un Sprite est 00 le centre de l'objet, vous pouvez voir que le Sprite est coupé dans trois des quatre quadrants. Je vais fermer ça. Pour revenir à notre projet, nous pouvons regarder offset et décocher centré. Maintenant, vous pouvez voir que le Sprite s'intègre complètement à l'intérieur de cette boîte bleue, qui représente la taille de l'écran que vous obtiendrez lorsque vous jouez au jeu. Maintenant, commençons à écrire du code Shader. J' ai dit plus tôt que nous pouvons écrire du code Shader pour n'importe quel nœud qui hérite d'un élément Canvas. Je vais chercher ici les propriétés de tous les nœuds qui héritent de l'élément Canvas, et sous le matériau, vous pouvez voir qu'il dit actuellement, matériau vide. Je vais cliquer sur cette flèche déroulante et appuyer sur « NewShaderMaterial ». Vous verrez un aperçu du matériel de base que nous venons de créer ici dans cette sphère. Je vais cliquer dessus, puis là où il est dit Shader, je vais cliquer sur la flèche déroulante et définir un nouveau Shader. Ensuite, je vais cliquer sur le « Shader », et vous pouvez voir qu'il est ouvert une petite fenêtre de code ici. Nous avons actuellement une erreur. Il dit que prévu un type de Shader au début de Shader, types
valides de notre élément Canvas, les particules et l'espace. Nous écrivons un CanvasItemShader, donc je vais écrire type Shader : Canvas élément, et un point-virgule pour indiquer que j'ai fini avec la ligne. Vous pouvez voir que cela a fait disparaître l'erreur. Il est important de noter que ce que nous écrivons ici n'est pas un script Judy, que vous auriez peut-être utilisé dans un tutoriel vidéo précédent de moi. Mais un langage spécifiquement créé pour écrire Shaders dans Godot. C' est similaire à GSL si vous l'avez déjà utilisé. Commençons par définir un fragment Shader qui définit simplement la couleur à chaque point couvert par le Sprite sur blanc. Je vais zoomer un peu sur le Sprite en utilisant la la souris et maintenez la molette de la souris enfoncée pour épingler, juste que je peux voir un peu plus clairement ce que je fais. Commençons par écrire la fonction de fragment. Cette fonction va écrire va être appelée par le moteur à chaque point individuel sur lequel notre Shader fonctionne. D' abord, nous écrivons, « Void », parce que cette fonction ne retourne rien à la fonction qui a codé, puis nous allons écrire, « Fragment », parce que nous implémentons la fonction de fragment. Vous pouvez voir que Godot a essayé de remplir automatiquement pour moi. La fonction de fragment ne prend aucun paramètre, donc c'est des parenthèses vides là. Puis ouvrez le support bouclé, Entrée. Maintenant, c'est le bloc de code qui s'exécutera chaque fois que le moteur appelle la fonction de fragment. Pour définir chaque fragment individuel couvert par le Sprite sur blanc, j'écrirai la couleur égale vec4, ce qui signifie vecteur 4 ou une collection de quatre nombres dans ce cas. Ensuite, je vais écrire, 1.0, 1.0, 1.0. Ce que cela signifie dans ce contexte, vous pouvez voir qu'il vient de mettre à jour et est maintenant complètement démontrant blanc est 1.0, ce qui signifie complètement rouge, 1.0 qui signifie complètement vert, 1.0 qui signifie complètement bleu, et 1.0, ce qui signifie complètement opaque. C' est la valeur Alpha, donc c'est RGBA. Quand nous disons que la couleur est égale au blanc, ce que nous disons vraiment c'est pour chaque point sur lequel ce Shader fonctionne, je veux que la couleur à ce point spécifique soit blanche. Il y a un moyen abrégé de le faire qui est d'écrire vec4 et puis juste un seul 1.0. Je vais supprimer tout ça. Vous pouvez voir que c'est bon. Le moteur est juste de remplir 1.0 dans toutes les positions vec4 automatiquement. Dans la leçon suivante, nous allons créer des blobs noirs et blancs de base.
5. Créer de nombreux gobages: Dans cette leçon, créons des blobs noirs et blancs de base. Commençons par définir la couleur d'arrière-plan sur noir. Puisque la valeur RVB de noir est 000, vous pourriez penser que le réglage de zéro ici créerait une sortie de fond noir. Mais en fait, puisque la valeur Alpha est également définie à zéro lorsque nous définissons les quatre composants du vecteur 4 zéro, nous obtenons une valeur noire avec une sortie entièrement transparente. Nous devons dire 000, puis 1.0 sur l'Alpha. Maintenant, nous avons notre sortie de fond noir. Maintenant, je veux ajouter des blobs blancs. Pour ce faire, je dois remplacer une couleur que nous
venons de définir en blanc dans les zones où nous voulons que nos blobs apparaissent. abord, je vais créer une liste qui
contient juste les points centraux de chacun de ces blobs, ainsi que la force de ce blob, relativement analogue à la taille du blob. Commençons par écrire vec3, blob_centers, et je veux que cela ait actuellement deux éléments pour deux blobs, puis ajoutez un point-virgule pour la nième ligne. Maintenant, je vais assigner chacun de ces centres blob à un point et une force. Pour le 0e blob ou le premier blob de la liste, j'attribuerai cela égal à un vector3, et c'est une coordonnée relative ici. Si je dis 1.0,1.0, puis imprimer un zéro, cela fait référence à 1.0 sur tout le chemin, 100 pour cent sur la texture sur l'axe des x et 100 pour cent sur la texture sur l'axe des y. J' ai actuellement mis la force à zéro. Disons que je veux cela peut-être ici pour 0,6 sur le x et 0,6 sur le y, ou 60 pour cent sur la texture dans les deux directions. Je vais mettre la force à 0,5. Je vais faire quelque chose de similaire avec le prochain centre blob. Peut-être que je veux que celui-ci soit un peu plus à gauche. Je dirai 0,5, 0,55, et puis je veux que ce soit un peu plus grand, disons 0,6. Maintenant, nous avons défini les emplacements pour deux blobs ici et ici. Rappelez-vous que le shader de fragment que nous écrivons s'exécute individuellement sur chaque point de cette texture. Ce que je veux faire, c'est pour ce point actuel sur lequel nous sommes, voir à quel point il est influencé par ces centres de blobs utilisant la force. Si elle est influencée plus qu'un certain seuil, nous pouvons définir cette couleur sur le blanc. Commençons par mesurer l'influence que chacun
des blobs a sur ce point individuel. Je vais dire float pour la valeur à virgule flottante, et je vais taper influence et le mettre à 0.0 pour commencer. Ensuite, je vais parcourir la liste des blobs pour mesurer
combien ce point individuel est affecté par chacun d'eux. Je dirai pour, parenthèse ouverte, int i égal à 0, parce que nous voulons commencer à compter à zéro, i moins que blob_centers.length. Nous voulons que je reste moins de deux parce que ce tableau n'a que les indices zéro et un parce qu'il a deux éléments. Un autre point-virgule, et je dirai i++, pour incrémenter i d'un après chaque fois que nous itérons à travers les blobs. Je vais ouvrir quelques crochets bouclés ici, et c'est le code qui fonctionnera pour chacun des blobs. abord, nous allons calculer la distance entre
ce centre blob sur lequel nous sommes actuellement sur le point sur lequel nous travaillons actuellement. Je dirai float distance_to_blob_center, et je dirai distance pour la bonne vieille fonction de distance intégrée. Ouvrez les parenthèses et un point-virgule. La fonction de distance veut que deux positions mesurent la distance entre. Je dirai blob_centers, crochets ouverts, et puis i, parce que je veux le blob sur lequel nous sommes actuellement, et puis je dirai .xy pour construire un vecteur avec juste le composant x et le composant y du vecteur actuel. blob_centers i, si nous sommes sur le 0 en ce moment, sera 0.6, 0.6 et ce sera aussi un vecteur. Ensuite, je veux mesurer la distance entre le centre blob actuel et notre position actuelle, qui est représentée par l'entrée uv. Maintenant, cette fonction de distance est bien pour l'instant, puisque nous avons actuellement une texture carrée dans le sprite. Mais plus tard, nous voudrons utiliser une texture rectangulaire pour le sprite afin que nous puissions ajouter notre base de lampe à lave. Disons que la texture était en fait de cette taille, par exemple. Rappelez-vous que pour les positions que nous utilisons ici, blob centre xy et uv, il est relatif au maximum global x et y. Ceci est 1.0 sur l'axe x, et même si c'est maintenant un rectangle, c'est toujours 1,0 sur l'axe des y, car il est relatif à la taille globale. Cela signifie que notre fonction de distance sera un peu déformée. Plus nous obtenons d'une texture de sprite carrée parfaite. Je vais diviser chacune de ces positions par la taille des pixels de texture. Pour la texture actuelle, nous utilisons icon.png. taille des pixels de texture est également un vecteur qui contient 1 sur 64 et 1 sur 64. Ce que cela fait en fait ici est de multiplier par composant une coordonnée relative, représentée entre zéro et 1.0, par le nombre de pixels dans chaque direction. Il le convertit d'une coordonnée relative en une position absolue sur la texture. Je vais mettre à l'échelle un sprite à la façon dont il était auparavant en allant sous la liste déroulante de transformation 2D du nœud, et en réinitialisant l'échelle. Maintenant, ajoutons une certaine influence à ce point en fonction de sa distance par rapport au blob spécifique. Ajoutez une nouvelle ligne ici et dites influence plus égale pour dire que je veux ajouter et réaffecter, puis je dirai blob_centers i, encore une fois, pour le blob actuel. Je dirai .z parce que nous voulons seulement ce troisième composant, qui nous a dit représente la force de ce blog particulier a. Votre instinct d'instinct pourrait maintenant être de multiplier cela par la distance au centre blob-. Mais rappelez-vous que cela signifie que plus le blob est loin de ce point spécifique, plus cette valeur sera grande
et plus l'influence globale sera grande. Nous voulons l'inverse de cela. Les points les plus proches du blob doivent être les plus influencés par le blob et plus susceptibles d'être blancs. Ce que nous voulons réellement est 1,0 divisé par la distance au centre blob-. Je vais juste capturer cela entre parenthèses, et cela nous donnera la relation correcte entre influence et la distance entre le blob et le point spécifique. Maintenant, c'est là qu'un peu de magie va arriver. Nous voulons dire que si l'influence est au-dessus d'un certain seuil, nous voulons changer la couleur de ce qu'elle est actuellement, du noir au blanc. Je vais courir si l'influence est au-dessus, disons, 0.3, nous voulons définir la couleur sur blanc. Souviens-toi, on a ce joli raccourci. Nous pouvons dire vec4, puis remplir tous ces composants avec 1.0. Là. Maintenant, nous avons quelques petits blobs qui sont apparus à l'écran. Je vais zoomer et vous pouvez voir comment cela fonctionne un peu plus clairement. Comme nous nous attendions, nous avons une zone de blanc autour de chacun des blobs. C' est toujours une bonne idée de faire des exemples pour tester votre code et vous assurer que vous comprenez comment tout fonctionne. Prenons un exemple de point juste entre les deux centres blob. Si je regarde les points à mi-chemin entre ceux-ci, c'est environ le point 0,55 sur l'axe des x, 0,575 sur l'axe des y. C' est quelque part par ici. Examinons notre code en utilisant cela comme exemple. Puisque c'est le point actuel que nous regardons, ses coordonnées seront dans l'entrée uv. Maintenant, passons à travers notre code. abord, l'influence est définie sur 0.0, puis pour chacun des blobs, nous le faisons. que pour le premier blob, celui-ci ici, Disonsque pour le premier blob, celui-ci ici,
nous avons la distance entre blob-center est la distance entre les centres blob i, donc le blob actuel, encore une fois, celui-ci .xy, donc nous avons juste le 0.6 et le 0.6, divisé par pixel de texture taille. Dans ce cas, cela signifie que le composant est divisé par 1 sur 64 et 1 sur 64, ce qui équivaut à multiplier ou à mettre à l'échelle ce vecteur par 64. Ensuite, nous avons la même chose, mais pour uv au lieu des centres blobs xy. Donc, l'uv, encore une fois, est actuellement de 0,55 et 0,575. Si nous calculons la distance entre ces deux choses, nous obtenons environ 3.578. Maintenant, nous voulons ajouter pour influencer une valeur qui correspond à la force blob actuelle et à notre distance par rapport au centre blob. Nous remplacons le composant blob z actuel, qui est 0,5, multiplions 0,5 fois 1,0 sur 3,578. Si nous faisons cela, nous obtenons environ 0,14. Nous ajoutons 0.14 à l'influence, puis passons au blob suivant. Maintenant, on est sur ce blob. Maintenant, nous allons à nouveau par les mêmes calculs. Nous calculons la distance au centre blob, et puisque le point que nous avons choisi d'être uv est à mi-chemin entre ces deux centres de blobs, nous savons que ce sera juste 3.578 à nouveau. Ensuite, nous ajoutons pour influencer le composant actuel blobs z, qui dans ce cas est 0.6 maintenant, puis multiplions cela par 1.0 sur 3.578 à nouveau. Ce que nous obtenons pour l'influence à ajouter ici est 0.17. Nous ajoutons 0.17 à l'influence, et maintenant nous avons 0.31 comme influence actuelle, puisque 0.14 plus 0.17 est 0.31. Maintenant, en descendant notre code, si l'influence est supérieure à 0,3, nous définissons la couleur sur blanc. Puisque l'influence est actuellement de 0,31, il évalue vrai que cette valeur est effectivement supérieure à 0,3, et donc nous définissons la couleur sur blanc. Le point au milieu entre ces deux blobs est en effet blanc. Juste pour vérifier nos calculs, nous pouvons également augmenter cette valeur de 0,3. Dis, je veux que ce soit 0,31, et je vois que le point entre ceux-ci n'est plus blanc. C' est parce que 0,31 n'est pas supérieur à 0,31, et aussi parce que nous avons arrondi quelques fois quand nous parlions d'ajouter à l'influence. La valeur que nous avons arrondie à 0,31 n'est pas supérieure au point 0,31, donc nous ne définissons pas la couleur sur blanc et elle reste noire, comme nous l'avons dit initialement. Juste parce que je pourrais vouloir modifier cela plus tard, je vais le remplacer par une nouvelle variable que je vais appeler seuil et créer un uniforme en haut du fragment ci-dessus. Je vais déclarer un nouvel uniforme en écrivant le seuil de flotteur uniforme. Je vais dire par défaut, nous allons définir cela à 0.3, ce qui est la valeur que nous avions auparavant. Mais ici, il y a une nouvelle chose, une nouvelle liste déroulante appelée Shader Param, et nous avons ce nouvel uniforme de seuil que nous venons de définir, la configuration 0.3. Maintenant, si j'augmente cette valeur, vous pouvez voir qu'en effet notre shader se met à jour. Vous pouvez également cliquer et maintenir enfoncé et faire glisser dans l'une ou l'autre direction, gauche ou à droite, avec la souris pour regarder que cela s'ajuste. Cela rend vraiment facile d'ajuster le seuil de l'éditeur au lieu de notre code. Cliquer sur ce bouton de réinitialisation comme je viens de le redéfinit à la valeur que vous définissez égale ici, c'est comme une valeur par défaut. Dans la leçon suivante, nous ajouterons quelques blobs supplémentaires et les animerons.
6. Animer les blobs: Dans cette leçon, nous allons ajouter quelques blobs supplémentaires et les
animer pour commencer à ressembler un peu plus à une lampe à lave. Pour commencer, je vais augmenter le nombre de centres de blobs que j'ai. Je vais mettre ça à six au lieu de deux juste pour que nous ayons maintenant six centres blob au total. Je vais juste faire le contrôle C sur cette sélection pour copier et le contrôle V pour le coller quelques fois. Selon votre système d'exploitation, vous devrez peut-être utiliser la commande V ou/et la commande C au lieu de Control, et je vais juste définir ceci sur 2, 3, 4, 5. Maintenant, nous avons en effet six centres blob au total. Vous verrez que la taille de blob a beaucoup augmenté ici, et c'est parce que nous ajoutons pour chacun des blobs, certains ont influencé le point actuel. Même pour les blobs qui sont loin ici, vraiment loin de l'un des centres blob, ils ont toujours de plus en plus d'influence juste parce que nous avons ajouté plus de blobs. Ils sont plus susceptibles d'être inclus dans cette fourchette qu'auparavant, simplement parce qu'il y en a plus. Je vais zoomer un peu en utilisant la molette de la souris juste pour que je puisse voir un peu plus clairement ce qui se passe, et je vais juste déplacer les coordonnées x un peu pour m'assurer que je peux voir un peu plus clairement où se trouvent chacun de ces blobs, parce qu'à l'heure actuelle, beaucoup d'entre eux ont exactement la même position. 0,6, 0,5. Disons que c'est à 0.55, celui-là à 0.45 , celui-là à
0.62, disons 0.7. Ils auraient dû s'étaler un peu, comme vous pouvez le voir. Maintenant, je veux que le composant y de chacun de ces centres blobs dépend du temps. Plus précisément, je veux une fonction mathématique qui prend le temps en entrée et
me renvoie une valeur comprise entre 0.0 et 1.0 en fonction du temps que je lui ai donné. Maintenant, il y a deux façons différentes de le faire. Commençons par représenter le sinus x. Imaginez que l'axe x est le temps et que l'axe y est la position y de notre blob. Sine x fonctionne assez bien pour nos besoins, mais il a des valeurs négatives qu'il génère donc nous finirons avec des blobs qui vont au-dessus de notre texture. Pour nous assurer que nos valeurs y du centre blob restent entre zéro et un, nous voulons que le terme sinus x soit positif. Une option serait de ne prendre que la valeur absolue du sinus x, mais cela nous donne ces coins, et si nous imaginons à nouveau que l'axe des x est le temps, cela signifie
que lorsque le blob frappe l'un de ces coins, il est immédiatement rebondit et commence à se déplacer dans la direction y opposée. Ce mouvement serait un peu anormal et il semblerait que le blob rebondi sur le haut de la lampe et
a immédiatement commencé à accélérer vers le bas ou vice versa. Encore une fois, il y a plusieurs façons de gérer cela, mais je préfère utiliser x au carré sinusoïdal ou sinus x fois le sinus x. Cela élimine les valeurs négatives car une valeur négative fois une valeur négative est une valeur positive, et il assouplit ces coins pour les rendre un peu plus ronds. Maintenant, nous avons, disons par exemple, un blob qui commence en bas, accélère
rapidement vers le haut, ralentit, puis reprend la vitesse lorsqu'il remonte vers le bas de la lampe. C' est le comportement parfait que nous recherchons. Pour ajouter un peu de variation entre les blobs, je pourrais aussi être en mesure de contrôler le décalage initial et la vitesse. Puisque notre axe x est le temps ici, la façon dont je peux accélérer un peu les choses, c'est de multiplier l'entrée x par un facteur de vitesse. De même, si je veux décaler un peu le temps, je vais juste ajouter un peu au x. maintenant traduisons cela en code. Je vais définir une nouvelle fonction qui renvoie un flotteur appelé oscillate, et la fonction oscillante que nous définissons prendra le float x, vitesse de
float et le décalage de flotteur. Ajout de mes accolades, et c'est le code ici qui fonctionnera chaque fois que nous appelons la fonction oscillante. Puisque nous voulons sinus au carré x ou sinus x fois sinus x, je vais dire, retourner comment sinus x fois vitesse plus décalage, et puis je veux élever tout ce truc à la deuxième puissance, c'est pourquoi il est contenu dans la puissance fonction. Je vais écrire un point-virgule pour compléter mon expression, et ce sont des fonctions oscillantes de base. Maintenant, je veux utiliser cette fonction oscillante en utilisant le temps comme une entrée pour chacun de mes centres blob y positions. Pourrait également s'appliquer comme avec l'entrée de temps. Tout ce que j'ai à faire est de remplacer le composant y de chaque centre blob par oscillate, le temps, et alors peut-être que je veux que cela fonctionne à mi-vitesse avec un décalage de 0,4. Maintenant, vous pouvez voir que j'ai ce blob qui s'anime d'avant en arrière entre 0.0 sur l'axe y et 1.0 sur l'axe y en utilisant le temps comme entrée. Je vais ajouter quelque chose de similaire pour le reste de ceux-ci. Disons que le temps oscillant, je veux que ça aille encore plus lentement, 0,2, et puis, je ne sais pas, 0,5 sur le décalage. Continuez à faire ça. Maintenant, vous pouvez voir que tous mes blobs vont et viennent dans l'axe y en utilisant notre fonction oscillante. Maintenant, c'est probablement le bon moment de modifier toutes ces valeurs juste pour vous assurer que vous êtes à l'aise avec elles, sorte que vous pouvez peut-être déplacer un peu les blobs sur l'axe x en changeant leur composant x, ou les déplacer sur l'axe y un peu en changeant leur vitesse, leur décalage, puis aussi changer l'influence ici. J' aime rendre la force de chaque blob un peu plus grande s'ils vont plus lentement. Ceux que j'ai mis la vitesse à 0,1, je vais augmenter un peu l'influence sur la force, donc je vais dire que c'est 0.8 et 0.8, et je peux voir que les blobs mobiles plus lents sont un peu plus grands. Si vous voulez pouvoir modifier ces valeurs très rapidement, vous pouvez définir un uniforme pour chacune d'elles comme nous l'avons fait pour le seuil. Je ne vais pas le faire juste parce que c'est beaucoup d'uniformes différents à définir, mais c'est une option si vous voulez que les gens ajustent rapidement des choses comme la vitesse, le décalage ou la position x de l'éditeur. Je suis assez heureux avec cela comme c'est pour le moment, donc je vais aller de l'avant et commencer à ajouter un peu de couleur dans la prochaine leçon.
7. Ajouter des couleurs: Dans cette leçon, nous allons ajouter quelques couleurs à notre lampe à lave. Commençons par ajouter la couleur d'arrière-plan que nous avons observée plus tôt est plus brillante sur les bords et la plus sombre au centre. Je vais faire ces uniformes de couleurs afin que je puisse rapidement les ajuster plus tard si je le veux. Je vais écrire vec4 uniforme depuis encore une fois, nous représentons les couleurs avec des fours vectoriels, et j'écrirai background_edge et je dirai deux-points, hint_color. Cela indique à l'éditeur que je veux que le bord d'arrière-plan ait l'indice d'un sélecteur de couleur. Même si c'est un vecteur quatre, les quatre composants sont RVB et A. L'éditeur met maintenant des valeurs dans ces quatre composants en fonction de la couleur que je choisis dans un bon sélecteur de couleurs, au lieu d'avoir à entrer des nombres manuellement et c'est juste parce que nous avons écrit hint_color ici pour dire à l'éditeur que c'est une couleur. Je veux définir la couleur d'arrière-plan sur le bord à une belle couleur magenta. Je veux que ce soit jusqu'au 255. Je veux que le vert soit à zéro, et que le bleu soit à 255. Maintenant, j'ai cette couleur magenta que j'espère mettre sur les bords, particulier les bords X de la lampe de lave. Maintenant, je vais écrire à nouveau, uniforme vec4 background_center et encore une fois, c'est une couleur. Maintenant, j'en ai un autre qui dit, si je survolais le centre de l'arrière-plan, je vais juste définir cela une couleur pourpre plus foncée et bien sûr que je peux modifier ces valeurs plus tard, sont que des valeurs que je mets pour le moment. Maintenant, je vais définir deux autres uniformes pour ce que je veux que les couleurs des blobs soient en haut et en bas. blob_top et est une couleur similaire et maintenant, il est apparu comme une couleur dans l'éditeur, je vais définir ceci pour être une belle couleur rouge vif et puis, autre vec4 uniforme blob_bottom pour ce que je veux que les blobs soient à le bas et c'est un autre hint_color. J' ai encore un autre sélecteur de couleur
ici et je vais régler ça pour être un joli jaune. Commençons par définir la couleur d'arrière-plan sur un mélange entre le bord d'arrière-plan et le centre d'arrière-plan, créant un dégradé. Je vais commencer par aller à l'endroit où je mets actuellement la couleur en noir, juste ici, et au lieu d'utiliser un vecteur pour cette constante, je vais le définir sur un mix, qui est une fonction d'interpolation linéaire dans Kidlo. Maintenant, je vais écrire centre d'
arrière-plan, bord d'arrière-plan parce que je veux mélanger entre ces deux couleurs, et cela produira un vecteur 4 dans la couleur que nous avons besoin. Alors, disons que je vais commencer par 1.0 ici. Vous pouvez voir que cela a complètement défini tout sur 1.0. Nous avons la couleur de bord de fond définie partout où le noir était auparavant. Si je devais définir ceci sur 0.0, nous avons maintenant totalement la couleur du centre de fond à la place. Si je le mets à 0,5, nous avons à mi-chemin entre le centre de l'arrière-plan et le bord de l'arrière-plan, et ainsi de suite. Si je change cette variable, cela change le mélange que j'utilise entre les deux couleurs et je veux que ce mélange, cette dernière variable de poids, dépend de la proximité que je suis ou de la distance que je suis du centre de la lampe. je suis loin du centre, plus je veux compter sur
le bord de l'arrière-plan, et plus je suis proche du centre, plus je veux compter sur
le centre de l'arrière-plan. Je dirai que je veux la valeur absolue de 0,5 moins la position x actuelle, qui encore une fois, je peux obtenir la position actuelle en disant UV, puis, .x, et puis je multiplierai cela par 2.0. Essayons ceci pour voir comment cela fonctionne. Si je suis au centre, alors ma position X actuelle est 0,5. Je vais faire la valeur absolue de 0,5 moins 0,5, qui est zéro, puis le multiplier par 2.0,
qui est zéro, ce qui signifie que je dépendrai complètement de la couleur centrale de l'arrière-plan. Ce devrait être un violet foncé et il l'est. Maintenant, testons à 0.0. La valeur absolue de 0,5 moins 0,0 est 0,5, fois 2, est 1. Je devrais être complètement dépendante de la couleur du bord de fond et je le suis. De même, si j'essaie une position entre 0,0 et 0,5 sur le x, disons 0,25, j'aurai la valeur absolue de 0,5 moins 0,25, qui est 0,25, fois 2, ce qui est 0,5. Je suis à mi-chemin entre le centre de l'arrière-plan et le bord de l'arrière-plan, que vous pouvez voir que je suis. Je peux changer ces valeurs comme je le veux en
modifiant maintenant le bord de l'arrière-plan et la couleur du centre de l'arrière-plan. Je veux que la couleur des bords de fond soit un peu plus foncée, donc je vais juste le faire tomber un peu. Voilà, tu y vas. Maintenant, je veux faire la même chose, mais pour les blobs. Là où nous définissons la couleur des blobs,
si l' influence est supérieure au seuil, c'est là que nous définissons la couleur du blob sur le blanc. Je vais plutôt utiliser un autre mix, blob_top, blob_bottom et puis, je veux que cela dépend de l'endroit où nous sommes sur l'axe y. Plus je suis loin du haut, plus je veux compter sur le fond. Je vais juste utiliser UV.y de sorte que si je suis à 1.0, je serai complètement dépendante de la couleur du fond blob, que vous pouvez voir que je suis et si mon UV.Y est zéro, je suis au sommet de ce brillant, alors je devrais être complètement dépendante de la couleur supérieure du blob, que vous pouvez voir une fois qu'un blob monte ici, que je dépend de cela complètement là-haut. Cela fonctionne très bien. Maintenant, je veux que les blobs brillent un peu et la façon dont je vais le faire est de créer un mélange entre la couleur d'arrière-plan à la position actuelle et la couleur de blob à la position actuelle. Pour le faire d'abord, je vais juste stocker ce mix ici et je vais dire, il y a un nouveau vec4 appelé current_blob_color et je vais mettre cela à ce mix, mettre le point-virgule, et puis je vais juste remplacer ceci ici par current_blog_ couleur. C' est juste pour éviter d'avoir copié et collé du code. Maintenant, je vais créer un nouveau flotteur appelé glow_multiplicateur, et je vais le définir à ce que j'ai défini mon seuil à, fois 10. C' est assez arbitraire et je vous encourage à expérimenter avec cette valeur pour voir quels types de résultats vous pouvez obtenir. Mais je vais utiliser ce multiplicateur de glow_multiplicateur pour créer un mélange que j'attribuerai à la couleur actuelle. Je dirai que la couleur est égale mélange entre quelle que soit la couleur actuelle, qui est ce dégradé que nous avons mis en place ici, et je veux un mélange entre cette couleur et le current_blob_color à cette position avec un facteur qui dépend le multiplicateur de glow_et l'influence que les blobs ont sur le point spécifique que je regarde actuellement. Je vais dire pow, glow_multiplicateur fois influence, qui est l'influence de ces blobs ont sur cette position actuelle, et puis je vais élever cela pour dire la cinquième puissance, donc 5.0, et puis j'ajouterai un point-virgule. Vous pouvez voir que cela a ajouté une belle petite aura autour des blobs. Vous pouvez également ajuster cette valeur 5.0 à votre goût. Mais si je l'augmente pour dire, 25, la lueur disparaîtra complètement. Alors que si je
le réduit d'un, il en va de même pour ne pas l'élever à n'importe quel pouvoir, vous pouvez voir que la lueur est maintenant massive. La raison de cela, parce que normalement, vous penseriez qu'élever quelque chose à une puissance supérieure le rendrait plus grand. La raison en est que glow_multiplicateur fois influence est souvent une valeur inférieure à un. En multipliant une valeur inférieure à un par une autre valeur inférieure à un, bien
sûr, nous allons réduire la valeur. Par exemple, à moins que nous soyons vraiment proches du centre d'un blob, comme si nous sommes dans cette région brillante, l'influence sera un nombre assez petit. Même en le multipliant par le seuil fois 10, c'est encore moins d'un. Donc, vraiment, une valeur parfaite est, je ne sais pas, peut-être quelque part autour de six ou sept. Ce que j'essaie de faire ici, c'est juste faire quelque chose qui
adoucit juste un peu le bord. J'aime sept. Juste que je peux rapidement modifier cela, je vais faire un nouveau float uniforme glow_power. Je vais revenir en arrière et le faire avoir une valeur par défaut de sept, qui est ce que j'avais non assigné là-bas, donc maintenant vous pouvez voir qu'il a restauré la lueur que je viens d'avoir et maintenant, je peux juste modifier cette valeur pour que vous puissiez voir que le plus petit le faire, plus
la lueur devient grande, et plus je
le fais, plus cette lueur devient subtile. J' aime toujours une valeur autour de sept, juste pour adoucir un peu ce bord et je vais le laisser comme ça pour l'instant. Encore une fois, cependant, modifier et jouer avec ces chiffres fait partie du processus. Je suis vraiment curieux de voir ce que vous pouvez faire en jouant un peu avec cette fonction. Dans la leçon suivante, nous allons ajouter une base de lampe à lave.
8. Ajouter une base: Dans cette leçon, nous allons passer à l'utilisation d'une base de lampe à lave. Pour commencer, je vais remplacer cette icône point png que j' utilise
actuellement avec la base de la lampe de lave que vous pouvez trouver dans la section des ressources du projet. Vous pouvez également créer votre propre base de lampe à lave. La chose importante à propos de cette image est qu'elle a une couleur unie que vous voulez remplacer par notre lampe à lave globe shader. Pour ajouter votre image de base de lampe de lave au projet Godot, vous pouvez soit faire glisser le fichier dans le système de fichiers ici dans le coin inférieur gauche, soit ajouter ce fichier à votre dossier sur votre bureau représentant le projet de lampe de lave. J' ai enregistré l'image de base de la lampe de lave sur mon bureau, donc je
vais juste la faire glisser dans le système de fichiers dans le coin inférieur gauche. Maintenant, vous verrez qu'il est écrit, « lave lampe base dot png » directement dans le dossier res du système de fichiers. Je vais cliquer sur mon nœud « Sprite », et où il est dit Texture ici, je vais juste faire glisser la base de la lampe de lave dans la Texture. L' image de base de la lampe de lave que j'ai créé est beaucoup, beaucoup plus élevé que l'icône point png. Il y a une tonne de pixels de plus, et si je fais un zoom arrière à l'aide de la molette de la souris, vous pouvez voir que c'est une assez longue lampe de lave maintenant. Vous pouvez également voir que les blobs sont très, très minuscules maintenant, et c'est parce que nous mettons tout à l'échelle par taille de pixel de texture, donc la distance au centre de blob est à peu près énorme partout où vous allez. Pour corriger cela, je vais créer un nouveau flotteur uniforme appelé force maximale et je vais le mettre à 16 pour l'instant. Je vais multiplier la force maximale ici. Prenez la force du centre blob pour chaque blob, je vais juste le multiplier par la force maximale. Puisque toutes ces valeurs pour le composant de force ne sont pas plus d'une, c'est en effet la force maximale qu'un blob individuel aura. Vous pouvez voir que cela a rendu nos blobs à une taille normale. Mais je peux aussi aller dans mes paramètres Shader et ajuster cela comme je le veux, pour les
rendre plus grands ou plus petits. Je vais le remettre à 16 pour l'instant ou cliquez sur le bouton de réinitialisation. La prochaine chose que je vais faire est juste de réduire le sprite afin qu'il s'intègre dans cette boîte bleue, qui représente actuellement la taille de l'écran. Pour l'instant, je vais juste mettre ça à 0.4 et 0.4. Je peux voir que c'est encore un peu en dehors de la boîte, donc je vais taper 0.3 et 0.3. Maintenant, nous sommes dans les limites bleues, et nous avons cette lampe à lave basique. Mais en ce moment, puisque nous écrasons la couleur partout, nous ne pouvons jamais voir la base de la lampe de lave elle-même. C' est pourquoi j'ai dit qu'il est important que le globe de lampe soit d'une couleur unie. Si je fais défiler vers le haut et regarde la texture, j'ai créé cette base de lampe de lave et vous pouvez voir que la zone que je
veux remplacer par mon shader est parfaitement magenta. Dans mon shader de fragment, ce que je veux faire est d'abord utiliser la couleur de la texture à ce point actuel, puis si la couleur de la texture à ce point actuel est parfaitement magenta, alors faites toutes ces choses que nous avons déjà écrites. Pour ce faire, je dirai d'abord, « couleur égale », puis Godot a une fonction de texture intégrée pour lire les couleurs des textures, puis je dirai, « TEXTURE » tous les capuchons, et « UV » pour cette position actuelle. Ensuite, si la couleur est maintenant égale au magenta, qui est un vecteur 4 avec 1.0 sur le rouge, 0.0 sur le vert, et 1.0 sur le bleu, 1.0 sur l'alpha, alors dans ce, je veux faire toutes ces choses. Je vais juste faire Control X ou Command X pour couper et coller ça ici. Ensuite, je vais juste ajouter une indentation d'onglet pour le formatage. Vous pouvez voir que maintenant nous avons notre niveau de base et vous pouvez voir que le globe n'apparaît que sur les zones qui étaient magenta. Vous pourriez voir une bordure magenta indésirable autour du globe de la lampe de lave comme je le fais actuellement. Si vous le faites, cliquez sur l'onglet « Importer » dans le coin supérieur gauche, assurez-vous que la base de la lampe de lave est actuellement sélectionnée comme ce que vous importez, puis assurez-vous que les filtres et les mipmaps sont désactivés. J' ai décoché Filter et je vais appuyer sur « Réimporter ». Maintenant, vous pouvez voir que cette bordure magenta indésirable est maintenant partie et j'ai une frontière parfaite entre le gris de l'arrière-plan et mon globe de lampe de lave. La prochaine chose que je veux réparer, c'est que nos blobs peuvent aller jusqu'au bas ici, et nous ne les voyons pas car ils vont dehors où le globe est censé être. Pour résoudre ce problème et faire en sorte que nos blobs ne des allers et
retours dans le contexte de ce globe, nous devons fabriquer deux nouveaux uniformes. Je dirai « haut flotteur uniforme » et je vais attribuer ça à environ 0,2. On dirait que c'est peut-être 20 pour cent ici, de haut en bas, peut-être que c'est 20 pour cent, donc je dirai 0,2. Puis fond flottant uniforme, si c'est 0,2, peut-être que c'est environ 0,5 ici. On dirait que c'est peut-être environ 0,6. Je dirai 0,6 ou environ 60 pour cent par le haut vers le bas. C' est ce que je vais faire pour le haut et le bas, mais comme ce sont des uniformes, encore une fois, en bas de nos paramètres Shader, ils sont vraiment faciles à ajuster. Maintenant, je veux m'assurer que notre fonction oscillante ne retourne que sous forme de valeurs y entre notre haut et notre bas. Ce que je vais dire, c'est des moments en dehors du pouvoir, je vais dire « fois parenthèses ouvertes, bas moins haut ». Actuellement, ces échelles sont fonction sinusoïdale de 0,4 et puis je vais y ajouter haut. Ce que cela fait actuellement est de mettre à l'échelle notre fonction sinusoïdale 0,4, puis de déplacer la fonction vers le haut afin que sa valeur de retour minimale soit 0,2. Vous pouvez voir que cette nouvelle fonction nous donnera des valeurs comprises entre 0,2 et 0,6. Encore une fois, puisque ce sont des uniformes, je peux ajuster leurs valeurs dans la section Shader Parameter. Peut-être que le fond est en fait plus proche de, je ne sais pas, 0,54. Alors je peux avoir le fond 0.54 et les blobs ne vont pas au-dessous de ce niveau. Je pourrais également augmenter le sommet pour être peut-être proche de 0,5, et alors vous pouvez voir que les blobs ne vont pas au-dessus de ce niveau. Je vais les réinitialiser à 0.2 et 0.6, mais sachez juste que vous pouvez jouer avec ceux si vous utilisez peut-être une base différente pour obtenir la valeur qui oscille
parfaitement les blobs entre le haut et le bas. Vous avez peut-être aussi remarqué que notre gradient sur les blobs ne prend pas encore en compte le nouveau haut et le bas. Cette valeur ici en bas n'est certainement pas égale à la couleur que nous avons définie ici pour notre fond de blob. Si je vais à l'endroit où je parle de ce gradient ici, je veux mettre à l'échelle les poids que nous utilisons pour notre fonction mixte ici. Au lieu de simplement compter sur le point UV y, qui est un ici, je veux qu'un soit juste ici, et je veux que zéro soit juste ici. Ce que je dois faire, c'est prendre en considération le haut et le bas du globe. Pour ce faire, je vais dire « UV dot y moins top ». Maintenant, je l'ai déjà fait pour que le haut de notre lampe soit maintenant zéro. Disons que si on est là et qu'on est à 0,2, maintenant on soustrait le top, ce que j'ai dit être 0,2, alors maintenant c'est zéro. Je veux mettre à l'échelle en bas moins haut. Vous pouvez voir que maintenant nous avons le bon gradient. La raison en est que donc je suis au sommet ici, j'ai 0.2, point
UV y est 0.2,
0.2 moins 0.2 est 0 donc cela évalue à zéro, donc nous sommes complètement dépendants de la couleur supérieure blob. Mais si nous sommes au fond, donc UV est actuellement de 0,6, ce qui est évalué à un. Vous pouvez également voir que si je devais dire déplacer le bas plus haut, je pourrais faire de plus en plus de la lampe jaune, ou si je déplace le haut en bas, je peux faire de plus en plus de la lampe que la couleur rouge. Dans la leçon suivante, nous allons exporter les images de notre lampe de lave vers le fichier PNG.
9. Exporter des images vers PNGs: Dans cette leçon, nous allons exporter les cadres de notre lampe à lave vers les PNG. Maintenant, assurez-vous que votre lampe à lave est exactement comme vous le voulez. Alors n'hésitez pas à modifier toutes les couleurs et le haut et le bas et la force et toutes ces sortes de choses pour vous assurer que la lampe de lave est exactement comme vous voulez qu'elle soit exportée dans un GIF. Je vais diminuer un peu la force maximale parce que je me sens comme maintenant que j'ai tout entassé entre 0,2 et 0,6, il y a juste beaucoup de cire par rapport à beaucoup de couleurs de fond. Donc je vais diminuer la force maximale à environ 12, peut-être un peu plus de 12. Essayons, 14 ans. Ouais, cette valeur me semble bonne, donc je vais garder cette valeur et aller de l'avant pour essayer de faire un GIF avec ça. Ce que je veux faire ensuite, c'est adapter la taille de la fenêtre ici, cette boîte bleue vers le bas pour être exactement la taille de ma lampe à lave. Je peux le faire en regardant ici la texture. J' ai 512 en 1584, et j'ai actuellement une échelle de 0.3 et 0.3. Je vais me souvenir de ces chiffres, et je vais aller au projet dans le coin supérieur gauche, puis Paramètres du projet. Faites défiler jusqu'à Fenêtre, et où il est dit largeur et hauteur, je veux que ma largeur soit 512 fois 0,3. Ensuite, je veux à ma taille d'être 1584 fois 0,3 et puis fermer. Vous pouvez voir que ma boîte bleue, si je désélectionne ce brillant, est maintenant la même que mon contour Sprite, ce qui est exactement ce que je veux. Ensuite, je vais revenir dans le coin
supérieur gauche et appuyer sur Scène pour passer à l'onglet scène. Cliquez sur « My Sprite » et appuyez sur ce bouton pour ajouter un nouveau script. Nous allons écrire un script qui génère fichiers
PNG pour chaque image que nous rendons de la lampe de lave. Je suis d'accord avec Lamp.gd étant le nom de ce script donc je vais appuyer sur « Créer ». Donc, je vais écrire une nouvelle fonction qui enregistre les trames dans les PNG. Rappelez-vous que nous travaillons dans gdscript maintenant, ce qui n'est pas le même langage que nous avons travaillé auparavant, donc les choses semblent un peu différentes. Je vais écrire une nouvelle fonction appelée Save frame en disant func save_frame () : enter. Maintenant, nos blocs de code sont définis par indentation et non par des crochets bouclés. Donc, chaque fois que save frame est appelée, je veux capturer la texture qui est actuellement rendue dans la clôture et l'enregistrer en tant que PNG. Tout d'abord, je vais créer une variable pour stocker les données de l'image dans. Je dirai var image=. Donc, pour obtenir cette image, je veux obtenir la texture actuelle de tout ce qui est rendu à la fenêtre. C' est la fenêtre supérieure du moteur de jeu Godot. Donc, je dirai get_tree () pour obtenir toute l'
arborescence de la scène , .get_root () pour obtenir l'élément le plus haut ou la fenêtre, puis je dirai .get_texture () pour obtenir la texture de cette fenêtre, et then.get_data (), pour obtenir les données d'image actuelles de cette texture. Je dois convertir cette image en une image qui préservera la transparence. Je vais faire une nouvelle ligne, puis je dirai image.converge pour changer le format de cette image,
image avec une majuscule, je point RGBA8. Donc je veux celui-ci ici, FORMAT_RGBA8. Ce format préservera en effet la transparence que nous voulons. Maintenant, je vais enregistrer le PNG, donc je vais faire image.save_png. Pour l'instant, je vais simplement taper *frame.png* comme une chaîne. Maintenant, je veux appeler cette fonction save frame chaque fois qu'une nouvelle image a été rendue. Donc, dans la fonction prête qui est appelée lorsque le nœud entre dans l'arborescence de la scène pour la première fois, donc quand notre jeu commence, je vais remplacer pass par VisualServer.connect et je veux ce signal
*frame_post_draw * et je veulent se connecter à ce signal à une méthode sur cet objet, donc je vais taper moi-même, et je veux notre nouvelle méthode save frame. Donc, je vais taper *save_frame* comme une chaîne. Maintenant, ce que cela va faire est chaque fois que le serveur visuel nous dit qu'il vient de dessiner une trame, il appellera la méthode de trame enregistrée sur cet objet. Ainsi, chaque fois qu'un nouveau cadre a été dessiné, la méthode d'image enregistrée sera appelée, nous obtiendrons la texture de la clôture actuelle et l'enregistrerons sous forme d'image. Plus précisément à frame.png. Je vais appuyer sur le bouton de lecture pour rendre un nouveau cadre. Je vais fermer la fenêtre qui est apparue. Vous pouvez voir que maintenant dans le système de fichiers et dans le coin inférieur gauche, il y a une nouvelle image appelée frame.png. Je vais double-cliquer dessus pour obtenir un aperçu. Vous pouvez voir ici à droite, nous avons deux problèmes. Premièrement, l'arrière-plan n'est pas transparent, c'est cette couleur grise ici, et deux, il a été retourné à l'envers. Tout d'abord, résolvons le problème de transparence. Allez dans Projet, puis paramètres du projet dans le coin gauche, puis sous Transparence par pixel dans l'onglet Fenêtre, vérifiez la transparence par pixel autorisée et la transparence par pixel activée. Puis appuyez sur « Fermer ». Ensuite, dans notre script avant de nous connecter au serveur visuel, nous devons récupérer notre viewport à nouveau, qui est exactement ce que nous avons fait ici, get_tree () get_root (). Donc, nous allons dire get_tree () .get_root () et then.set_transparent_background (true) et nous voulons définir cela sur true. Je vais appuyer sur le bouton de lecture pour rendre un autre cadre, fermer la fenêtre qui apparaît, double-cliquez sur frame.png et maintenant vous pouvez voir qu'en effet nous avons un beau fond transparent là-bas. Selon votre système, le tien n'est peut-être pas à l'envers, mais le mien l'est. Donc, après avoir converti le PNG, mais avant de l'enregistrer, je veux taper image. flip_y, et je veux appeler la méthode flip_y sur l'image afin qu'elle la renverse. Je vais appuyer à nouveau sur le bouton de lecture pour rendre encore une autre image, fermer la fenêtre qui apparaît, puis double-cliquer sur frame.png et maintenant vous pouvez voir que j'ai mon très beau cadre ici. C' est parfaitement à droite, j'ai un fond transparent, et généralement il a l'air assez bon. Mais ce que je veux vraiment, c'est une tonne d'images individuelles à compiler dans un GIF animé. ce moment, nous sommes juste remplacer frame.png à chaque fois. Donc, je vais définir une nouvelle variable membre en haut appelée var frame_count = 0 et je vais la mettre à zéro pour commencer. Maintenant, afin de contrôler le nombre d'images que mon GIF de sortie est, je ne vais enregistrer la trame que si le nombre d'images est inférieur à un certain niveau. Au-dessus de la section des variables membres, je vais définir une nouvelle constante qui ne changera pas, et je vais définir cela sur MAX_FRAMES = 60 dans toutes les majuscules, et je vais définir cela sur 60 pour l'instant. Ensuite, dans notre méthode save frame, je vais taper sous image var image_name, et je vais affecter cela à une chaîne vide pour l'instant. Maintenant, juste pour vous assurer que nos trames de sortie sont triées dans le bon ordre, j'écrirai pour i dans range (), puis je dirai la longueur de la chaîne de MAX_FRAMES moins la longueur de la chaîne de notre nombre d'images. Pour chacun d'entre eux, je veux ajouter un zéro au début du nom de l'image. Ensuite, en dehors de cette boucle for-, je vais faire image_name plus égal à la chaîne
du nombre d'images actuel, puis plus. PNG. Ensuite, au lieu d'enregistrer l'image sous frame.png, je l'enregistrerai sous (image_name). Enfin, j'en ajouterai un au nombre de trames. Plus équivaut à un. Mais je veux seulement enregistrer ce PNG si notre nombre de trames actuel est inférieur à MAX FRAMES. Donc, je ne ferai tout cela que si frame_count est inférieur à MAX_FRAMES. Ensuite, puisque nous travaillons avec des indentations, je vais mettre en évidence tout cela et appuyer sur Tab pour le retirer du tout. Nous économisons donc actuellement 60 cadres de notre lampe à lave. Mais si Godot obtient 60 images par seconde, cela signifie
que notre GIF ne dure que 1 seconde, donc je voulais réduire les images cibles de Godot par seconde. Donc, dans la fonction prête, je vais taper le moteur, définir le FPS cible, et je vais le mettre à 15. Cela signifie que Godot ciblera 15 images par seconde et si nous économisons 60 images, cela signifie
que nous avons environ quatre secondes d'exécution de la lampe de lave. En fait, je vais revenir en arrière et augmenter cela un peu plus faire 120 pendant huit secondes d'exécution de la lampe de lave. Appuyez ensuite sur le bouton de lecture et laissez la fenêtre qui apparaît fonctionner pendant huit secondes ou plus. Une fois que ça fait au moins huit secondes, fermez cette fenêtre, et vous verrez que Godot importe tous nos cadres. Donc, si je vais à notre système de fichiers ici dans le coin inférieur gauche, vous pouvez voir que nous avons toutes les 120 images commençant par 000.png et allant jusqu'à un 119.png. Maintenant, nous voulons convertir tous ces fichiers PNG dans un fichier GIF qui va animer.
10. Convertir les PNGs en GIF: Dans cette leçon, nous allons convertir nos PNG exportés en un GIF animé transparent. Ouvrez votre navigateur Web et accédez à un site Web qui peut générer des GIF animés à partir de PNG. Je recommande d'utiliser ezgift.com/maker. Une fois que vous êtes sur le site, appuyez sur « Parcourir » pour télécharger vos images PNG. Une fois que vous avez sélectionné vos PNG, appuyez sur « Upload and make GIF », puis vous verrez tous les PNG de la lampe de lave ici. Si vous faites défiler vers le bas, assurez-vous de régler le délai à zéro, puis appuyez sur « Créer un GIF ». Une fois votre GIF chargé, appuyez sur « Effets », puis faites défiler vers le bas et où il indique Flux d'animation, cochez la case à côté de Exécuter jusqu'à la fin et revenez au début. Ensuite, appuyez sur « Appliquer Selected » et votre GIF de sortie sera bouclée de manière transparente. Une fois cela fait, appuyez sur le bouton « Enregistrer » et enregistrez votre nouveau GIF sur votre ordinateur. Il s'agit d'un projet qui offre des tonnes de possibilités d'expérimentation. Plus vous jouez avec elle, plus vous comprendrez comment
les shaders fonctionnent dans le moteur de jeu Godot. Je vous encourage vraiment à le faire. Dans la prochaine leçon de bonus, nous allons rapidement voir comment laisser votre lampe de lave brûler dans le coin de votre écran pendant que vous faites votre autre travail.
11. (Bonus) Ajoutez la lampe Lava à votre écran: Dans cette leçon de bonus, nous allons rapidement voir comment vous pouvez faire fonctionner la lampe de lave dans le coin de votre écran pendant que vous faites votre autre travail. Je vais commencer par commenter cette ligne de connexion pour la
faire en sorte que nous n'exportons plus nos cadres. J' utilise la livre sterling ou le symbole hashtag pour commenter la ligne. Ensuite, je vais aller à Projet, Paramètres du projet. Faites défiler jusqu'au mode étirement. Je vais dire « 2d » et « Fermer ». Maintenant, si j'appuie sur le bouton « Play », je peux redimensionner ma lampe à lave. Je peux le faire glisser, et je peux le redimensionner comme je le veux. Lorsque vous redimensionnez la fenêtre, le rapport d'aspect des lampes de lave est un peu désactivé. Pour corriger cela, allez dans Projet, Paramètres du
projet, puis là où il est indiqué Aspect sous Étirer, passez de « Aspect Ignorer » à « Aspect Expand ». Maintenant, lorsque vous exécutez la lampe à lave, la lampe à lave restera toujours le même rapport d'aspect, mais elle peut encore augmenter en taille. Cependant, si je clique sur le « Godot Game Engine », ou toute autre fenêtre, ma lampe de lave va derrière elle. Ce que je vais faire est d'aller dans Projet, Paramètres
du projet, puis cochez « Toujours en haut ». Si vous ne voulez pas qu'il soit redimensionnable, vous pouvez décocher « Redimensionnable », et si vous voulez qu'il soit sans bordure, vous pouvez cocher « Sans bordure ». Je vais aller de l'avant et faire ça pour l'instant. Donc maintenant, si je redémarre, vous pouvez voir la lampe de lave fonctionne au centre de mon écran et il n'a aucune des limites Godot dessus. Je vais l'arrêter en appuyant sur le panneau stop. Ensuite, nous allons à l'éditeur dans le coin supérieur gauche, puis Paramètres de l'éditeur. Dans Paramètres de l'éditeur, si je fais défiler vers le bas jusqu'à Exécuter, puis Placement de la fenêtre vous pouvez
actuellement voir que Rect est réglé sur Centré, ce qui explique pourquoi notre lampe de lave fonctionne au centre de l'écran. Je peux définir ceci à la position personnalisée, puis obtenir la taille de mon écran, qui dans mon cas est 1920 par 1080. Donc je peux dire 1920 moins la coordonnée x sur notre lampe de lave est brillante, donc moins 153. Alors on peut dire 1080 moins 475. Je voudrais en soustraire un peu plus de ce nombre juste pour tenir compte de cette barre en bas ici. Donc je vais soustraire 20 supplémentaires de 605. Puis j'appuie sur « Fermer », « Replay ». Maintenant, vous pouvez voir la lampe à lave coule dans le coin de mon écran. Je pourrais même minimiser Godot et avoir la lampe de lave fonctionnant sur mon bureau ou je pourrais ouvrir Firefox. La liste continue. Fondamentalement, la lampe à lave reste dans le coin inférieur droit de mon écran. Si je veux faire en sorte que je puisse déplacer la lampe de lave autour, je vais juste revenir à Project,
Project Settings, puis décocher « Borderless » et redémarrer. Maintenant, si je veux, je peux traîner la lampe à lave pour la mettre où je veux. Mais il reste toujours sur le dessus puisque « Always On Top » est coché afin que je puisse encore minimiser Godot et faire d'autres choses. C' est juste que maintenant je peux aussi le faire glisser si cela arrive à se mettre en travers. C' est comment ajouter une lampe à lave dans le coin inférieur droit de votre écran, une fois que vous l'avez déjà créée à l'aide du moteur de jeu Godot. Je pense que c'est beaucoup de plaisir, juste un peu de divertissement
passif pendant que vous faites votre autre travail. De plus, c'est un démarrage de conversation assez cool si vous à partager un écran sur un appel Zoom ou quelque chose comme ça. Merci de vérifier la leçon bonus. Je te vois dans la prochaine vidéo pour quelques dernières pensées.
12. Réflexions finales: Merci d'avoir vérifié la classe. Si vous ne l'avez pas déjà fait, s'il vous plaît assurez-vous de poster votre cadeau de lampe à lave dans la galerie de projet de classe. J' espère vraiment que vous en êtes sorti avec une meilleure compréhension du fonctionnement des shaders de fragment 2D. J' apprécierais vraiment vos commentaires. S' il vous plaît envisager de laisser un commentaire ici sur Skillshare et suivez-moi si vous voulez plus de cours comme celui-ci. Vous pouvez également me faire savoir ce que vous souhaitez voir par la suite via le sondage dans l'onglet Discussions ou sur la page de mon profil. Je te verrai la prochaine fois.