À propos de Godot, GLSL et WebGL, shaders utilisés dans le mini-jeu

L'article porte principalement sur les shaders GLSL et sur la façon dont je les ai utilisés dans ce mini-jeu de démonstration.



L'article est divisé dans l'ordre suivant:


  • Liens et brève description.
  • Une très brève description de la logique du jeu et des fonctionnalités utilisées de Godot.
  • À propos des shaders utilisés.
  • Un peu plus sur Godot et ses caractéristiques.
  • WebGL2 fonctionne
  • Multijoueur



1. Liens et description


Vous pouvez télécharger la version Win / Linux depuis le lien vers itch.io


Le code source de l'ensemble du jeu est disponible sur github ou gitlab .


Gameplay:


Minimal, ce n'est pas un jeu complet. (pas de son dans le jeu)


Le but du jeu est de tenir le nombre maximum de tours. Les rounds commencent lorsque les sphères HP sont nulles et qu'il n'y a pas de robots dans le jeu.


Lorsque les pièces sont détruites, des bonus apparaissent, une fois par tour , donnent la vitesse de l'animation du tir, les dégâts (uniquement dans la sphère principale) et la hauteur de saut, en couleur bleu, rouge / vert, jaune. Les bots donnent également un bonus mais au hasard. Le personnage du joueur restaure +1 HP à chaque nouveau tour.




2. La logique du jeu et les ressources utilisées


Ressources utilisées:


Blender a été utilisé uniquement pour réduire le nombre de polygones sur les modèles et pour créer des morceaux de modèles cassés.


Le module futari-addon est utilisé . (J'écrirai à ce sujet ci-dessous)


Dans le jeu, deux modèles ont des animations.
Mouvements des personnages que j'ai faits à Godot, le modèle original
Le deuxième modèle est la sphère-bot qui a des animations de haute qualité.


Tous les modèles d'objets tiers prêts à l'emploi sont répertoriés ici .


Logique de jeu et fonctionnalités Godot:


La logique du jeu ne se fait pas de la meilleure façon, je vais lister les points qui se font normalement.


Une seule fenêtre est utilisée pour une scène 3D, et plusieurs fenêtres (basse résolution) dans lesquelles se trouvent des caméras orthogonales pour les fenêtres 2D (également basse résolution) dans lesquelles des ombrages Multipass / Feedback sont traités, plus d'informations à leur sujet ci-dessous.


Toutes les textures ont mipmap et fonctionnent même dans le navigateur. Il existe des paramètres graphiques supplémentaires (Esc - Paramètres) . Par exemple, vous pouvez définir n'importe quelle résolution pour le jeu , jusqu'à 32x32 pixels, par exemple, j'ai défini une résolution de 320x240 dans les paramètres, exécuté le jeu dans un navigateur et activé l'anti-aliasing MSAA maximal.


Toutes les sources lumineuses fonctionnent en temps réel , il y en a 16 au total.


Le sol et la clôture sont les particules les plus simples qui reproduisent plusieurs fois le même modèle, le code est trivial .


La matrice de rotation des particules (morceaux de sol) dans mes shaders n'est qu'une courte entrée de cette formule:


 mat4 rotationAxisAngle( vec3 v, float angle ) { float s = sin( angle ); float c = cos( angle ); float ic = 1.0 - c; return mat4( vx*vx*ic + c, vy*vx*ic - s*vz, vz*vx*ic + s*vy, 0.0, vx*vy*ic + s*vz, vy*vy*ic + c, vz*vy*ic - s*vx, 0.0, vx*vz*ic - s*vy, vy*vz*ic + s*vx, vz*vz*ic + c, 0.0, 0.0, 0.0, 0.0, 1.0 ); } 

par exemple, v=vec3(0.0,0.0,1.0) est la rotation le long de l'axe z et l' angle=PI/2. remplacez-les et obtenez le tour souhaité.


L'animation de blocs destructibles est considérée comme un moteur physique en temps réel



La physique à Godot est assez limitée, et elle commence à réduire considérablement le FPS même avec une douzaine d'objets actifs, donc toutes les collisions entre les pièces détruites sont désactivées, et d'autres sont définies, les niveaux pour la physique sont définis, il y a aussi une limite au nombre de destructions simultanées et au nombre maximal de bots en même temps (six).


La physique de l'inertie et l'interaction du personnage du joueur avec des objets dynamiques. Il est désactivé par défaut dans Godot, j'ai écrit une interaction minimale, le code dans les fichiers:


fonction bot_hit.gd _integrate_forces et tout ce qui y est appelé sont les mouvements de l'adversaire-bot
player_l.gd tout d'abord, la fonction move_and_slide désactive l'inertie infinie et la fonction process_collision repousse les objets.


La précharge (précharge) au début du jeu est utilisée pour éviter le décalage lorsque l'objet apparaît pour la première fois, cela aide cependant lorsque vous activez les ombres (et certaines autres options), les décalages réapparaissent à la première apparition de l'objet. Également dans le navigateur, cela n'aide pas en raison des particularités des navigateurs travaillant avec des shaders.


Plusieurs objets dupliqués en un, et plusieurs GIProbe, les formes et paramètres des sources lumineuses sont tous destinés , faits pour contourner les limitations d'OpenGL ou les restrictions de Godot.




3. Shaders utilisés


Panorama de l'environnement:


Ce jeu utilise un panorama statique, l'image est obtenue à partir de ce shader (couleurs c1 c2, position ldir)


 vec3 sky(vec3 d, vec3 c1, vec3 c2) { vec3 ldir = normalize(vec3(0.,0.,-1.)); vec3 col = mix(c1*100., c2*100., min(abs(dy)*2. + .5, 1.)) / 255.*.5; col *= (1. + vec3(1., .7, .3) / sqrt(length(d - ldir))*2.); //sun return clamp(col,vec3(0.),vec3(1.)); } 

pour obtenir un panorama, supprimez le commentaire de la ligne 57 panorama_uv(fragCoord,ro,rd); et mettez un commentaire à la ligne 58


Panoramas dynamiques pour Godot dans les démos précédentes (YouTube et il y a des liens vers le code) panorama des nuages .
Et le panorama du cycle jour / nuit avec le mouvement des nuages ​​a été utilisé dans cette démo:



un autre panorama jour / nuit par exemple, sur shadertoy je ne l'ai utilisé nulle part


Si vous avez besoin de convertir CubeMap en un panorama de l'environnement pour Godot , j'ai fait un simple convertisseur web .


Shaders très simples:


Les shaders de particules déterminent statiquement leur position pour l'animation ou non. Par exemple, spawn.shader)



Pour une lueur supplémentaire autour des objets , pas seulement des balles, il s'agit d'une ligne de gglow.shader (les nombres peuvent être modifiés au besoin)


 float intensity = pow(0.122 + max(dot(NORMAL, normalize(VIEW)),0.), 010.85); 


Affichage de chiffres de texte en 3D , si je comprends bien dans Godot, il n'y a pas de moyen pour cela (sans créer un FBO supplémentaire (fenêtre d'affichage)) donc un simple shader imprimant les numéros à partir d'une texture (pour qu'il soit en mipmapping ), le code du shader


Éléments de l'interface utilisateur:


Faire la forme personnalisée des panneaux d'interface utilisateur le plus facile pour moi est sur les shaders, peut - être que ce n'est pas du tout correct . La méthode correcte est présentée ici à titre d'exemple (dans la section sur l'interface utilisateur).
Dans ce jeu, l' animation la plus simple est l'arrière-plan du menu et l' indicateur est HP . Ci-dessus, dans le lien vers la vidéo du panorama jour / nuit, c'est aussi fait, il y a des rayures sur les côtés et toute l'animation sur le shader.


À propos du module futari-addon:


Il fonctionne presque de la même manière que ce shader pour les particules 2D en vidéo (voir à partir de 1:41).


Une carte 2D-SDF de tous les polygones est construite sur la vidéo une fois au début et la texture résultante est simplement envoyée aux particules, les particules elles-mêmes se construisent normalement dans la position actuelle et changent le mouvement.


futari-addon fait presque la même chose, mais au lieu d'une carte de texture 2D, les coordonnées des sphères et des plans 3D sont transmises, qui sont traitées en fonction de la condition dans le shader de particules, de sorte que vous pouvez modifier librement leur position et d'autres paramètres.


De plus, le vent (dans mon exemple 2D, l'ajout de vent est très simple, car une autre texture avec des valeurs + - à la vitesse, et les particules ajoutent simplement la valeur de vitesse de cette carte à sa position).


Le module futari-addon est très bon , l'a utilisé au lieu de créer son propre système de particules.


Effet de bouclier:


Particules auxquelles les coordonnées de l'impact sur la sphère et la position du joueur, et l'extinction sont transmises à l'aide du tampon de rétroaction de transformation . Code de shader dans le fichier en_m.shader



Bouclier des bots:



Shader comme un sheild de bruit tridimensionnel.shader essentiellement tout fonctionne grâce à la fonction de flow originale ici
L'arrière-plan est déterminé par gl_FrontFacing et est peint plus sombre et plus vert, pas bleu.
Réponse à un coup de poing - la minuterie d'événement de choc est simplement transmise.





Shaders lisant leur dernière image, ou shaders Feedback / Multipass:


Presque tous les effets sont réalisés en utilisant cette logique.
L'un des shaders du jeu .
En tant que source, j'ai défini une caméra orthogonale qui prend des objets dans un certain groupe à une courte distance (sans traiter la scène entière)
.


Effet de champ de glace:


Le shader est indiqué ci-dessus, dans le fichier de projet est ice_feedback.shader , et un fragment shader pour le plan qui crée l'illusion de la profondeur du sol à l'aide d'une simple boucle de profondeur:


 while(current_depth < depth){ ofs -= delta; depth = textureLod(texture_depth, ofs,0.0).r; current_depth += layer_depth; } 


Effet de champ de particules:


Le shader est le même , la coordonnée y (hauteur) des particules en fonction de la luminosité de la couleur du tampon de cadre du shader, la couleur également en fonction de la luminosité de la couleur ( je n'ai pas enregistré le shader de particules séparément, il est dans le projet dans l'objet floor/visible_/floor3/grass/grass ).



Animation de drapeau dynamique:


Godot a SoftBody pour animer le tissu, mais c'est un CPU, donc je ne l'ai pas utilisé. J'ai utilisé un lien de code prêt à l'emploi vers l'original . Ce drapeau est poussé de trois balles sur le côté et la tête du personnage est la quatrième balle.
La logique du shader multipasse , comme dans l'exemple ci-dessus, avec seulement trois axes, le code multipasse du shader (1) flag.shader , le shader qui dessine le flag montre juste la texture et change la géométrie de l'avion (2) flag.shader .



Apparence des chiffres:


Les formes n'ont pas d'UV, donc tri-texture-texture-mapping pour texture mapping et triangling ( vertex ), tous les codes dans cchess.shader



Animation d'une hitbox (cadre rouge) qui endommage le personnage du joueur, et une trace du cadre (les particules sont évidentes):



Il utilise uniquement le shader gglow.shader déjà spécifié.
PS fait la même animation dans un shader , lien vers shadertoy


Pour les particules, seules deux textures sont utilisées, un cercle et un carré.




4. À propos de Godot et ses caractéristiques


Godot est très bon et simple (pas pour un débutant). J'ai vraiment aimé Godot pour ses fonctionnalités.


Il y a beaucoup de bugs, la documentation Godot est incomplète et parfois trompeuse à cause d'erreurs et n'indiquant pas de points critiques (pas évident pour moi), afin de comprendre quel code source Godot a dû être relu plusieurs fois (le code n'est pas volumineux et bien écrit).
C'est juste mon impression, cela peut être erroné, je ne veux induire personne en erreur.


Je souligne que même les bogues très critiques de Godot peuvent être contournés dans Godot lui-même via GDScript, avec un minimum d'effort. Ce qui est sans aucun doute un gros plus


Je note également que Godot n'est en aucun cas protégé contre les particularités de facteurs externes, tels que WASM dans les navigateurs, restrictions ANGLE, fortes limitations des navigateurs eux-mêmes, et bien sûr, des dizaines de bogues dans les pilotes de carte vidéo, tout cela doit être contourné manuellement.


Retards - il y a un gros problème de gestion, c'est 100% côté Godot, je ne l'ai pas réglé. (contrôle des coins lors de la compilation des shaders et décalages FPS (par exemple, dans le navigateur)), ainsi que d'autres décalages liés aux fonctionnalités de rendu 3D dans Godot, j'ai fait un détour de certains d'entre eux, mais ils existent toujours / peuvent être.




5. WebGL2 fonctionne Linux uniquement


Ne démarrez pas le jeu à partir du lien si vous avez Windows. Lien vers la version WebGL2 / WASM.


Mise à jour des informations : la version WebGL a été lancée dans Windows10 (uniquement dans Firefox, avec ANGLE désactivé) sur un PC super puissant (i9 / 16gb ram / 8gb vidéo), bien que le plancher ne soit plus rendu (pour une raison quelconque), et le firefox fuit la mémoire (> 16 Go ) en cinq minutes ... il vaut mieux ne pas courir, à vos risques et périls


Fonctionne uniquement sur Chrome 76+ et Firefox (Linux).


Un rapport de bug (lien) a été envoyé à propos de Windows, s'il s'agit d'un bug de navigateur, alors Google réagit après 2 mois. Mais apparemment, c'est un bug dans ANGLE, et ce n'est certainement pas correct.
Le rapport de bogue est déjà fermé et ANGLE ne sera pas modifié non plus. Donc, sous Windows, le navigateur ne fonctionnera pas.


Au cours de ce projet, un bogue dans Chrome a été corrigé en raison de quoi Transform-Feedback et ma dernière démo (ci-dessus la vidéo avec un panorama jour / nuit) , qui n'avait pas fonctionné auparavant, ont commencé à fonctionner.




6. Multijoueur


Multijoueur ajouté, exclusivement à des fins de test (et exemple multijoueur dans Godot). Code source et versions binaires à côté de la version principale sur github et itch (liens au début).



À la sortie de Godot 3.2, j'ajouterai également WebRTC pour le test.

Source: https://habr.com/ru/post/fr467779/


All Articles