Der Artikel handelt hauptsächlich von GLSL-Shadern und wie ich sie in diesem Mini-Demo-Spiel verwendet habe.
Der Artikel ist in folgende Reihenfolge unterteilt:
- Links und eine kurze Beschreibung.
- Eine sehr kurze Beschreibung der verwendeten Spielelogik und Godot-Funktionen.
- Über die verwendeten Shader.
- Ein bisschen mehr über Godot und seine Eigenschaften.
- WebGL2 funktioniert
- Multiplayer
1. Links und Beschreibung
Sie können die Win / Linux-Version über den Link zu itch.io herunterladen
Der Quellcode für das gesamte Spiel ist auf Github oder Gitlab verfügbar .
Gameplay:
Minimal, dies ist kein vollständiges Spiel. (kein Ton im Spiel)
Das Ziel des Spiels ist es, die maximale Anzahl von Runden zu halten. Runden beginnen, wenn die HP-Kugeln Null sind und keine Roboter im Spiel sind.
Wenn Teile zerstört werden, erscheinen einmal pro Runde Boni, die die Geschwindigkeit der Schussanimation, den Schaden (nur in der Hauptsphäre) und die Sprunghöhe in den Farben Blau, Rot / Grün und Gelb angeben. Bots geben auch einen Bonus, aber zufällig. Der Spielercharakter stellt in jeder neuen Runde + 1 PS wieder her.
2. Die Logik des Spiels und die verwendeten Ressourcen
Verwendete Ressourcen:
Blender wurde nur verwendet, um die Anzahl der Polygone auf Modellen zu reduzieren und um gebrochene Modellteile zu erstellen.
Das Futari-Addon- Modul wird verwendet . (Ich werde unten darüber schreiben)
Im Spiel haben zwei Modelle Animationen.
Bewegungen von Spielercharakteren, die ich in Godot, dem Originalmodell, gemacht habe
Das zweite Modell ist Sphere-Bot mit hochwertigen Animationen.
Hier werden alle gebrauchsfertigen Modelle von Objekten von Drittanbietern aufgelistet .
Spielelogik und Godot-Funktionen:
Die Spielelogik ist nicht optimal, ich werde die Punkte auflisten, die normalerweise gemacht werden.
Für eine 3D-Szene wird nur ein Ansichtsfenster verwendet, und mehrere Ansichtsfenster (niedrige Auflösung), in denen orthogonale Kameras für 2D-Ansichtsfenster (ebenfalls niedrige Auflösung) vorhanden sind, in denen Multipass- / Feedback-Shader verarbeitet werden. Weitere Informationen hierzu finden Sie weiter unten.
Alle Texturen haben eine Mipmap und funktionieren sogar im Browser. Es gibt zusätzliche Grafikeinstellungen (Esc - Einstellungen) . Sie können beispielsweise eine beliebige Auflösung für das Spiel festlegen, bis zu 32x32
320x240
32x32
Pixel. Ich habe beispielsweise die Auflösung in den Einstellungen auf 320x240
, das Spiel in einem Browser ausgeführt und die maximale Anti-Aliasing- MSAA 320x240

Alle Lichtquellen arbeiten in Echtzeit , insgesamt gibt es 16.
Der Boden und der Zaun sind die einfachsten Partikel, die dasselbe Modell viele Male duplizieren. Der Code ist trivial .
Die Partikelrotationsmatrix (Bodenstücke) in meinen Shadern ist nur ein kurzer Eintrag aus dieser Formel:
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 ); }
Zum Beispiel ist v=vec3(0.0,0.0,1.0)
die Drehung entlang der z
Achse und der angle=PI/2.
Ersetzen Sie sie und erhalten Sie die gewünschte Runde.
Die Animation zerstörbarer Blöcke wird als Echtzeit-Physik-Engine betrachtet
Die Physik in Godot ist ziemlich begrenzt und verringert die FPS sogar bei einem Dutzend aktiver Objekte erheblich. Daher werden alle Kollisionen zwischen zerstörten Teilen deaktiviert, andere festgelegt, Ebenen für die Physik festgelegt, die Anzahl der gleichzeitigen Zerstörungen und die maximale Anzahl von Bots gleichzeitig begrenzt (sechs).
Die Trägheitsphysik und die Interaktion des Spielercharakters mit dynamischen Objekten. Es ist standardmäßig in Godot deaktiviert, ich habe eine minimale Interaktion geschrieben, den Code in den Dateien:
Die Funktion bot_hit.gd _integrate_forces und alles, was dazu aufgerufen wird, sind Bewegungen des Gegners
player_l.gd Erstens move_and_slide
Funktion move_and_slide
die unendliche Trägheit und die Funktion process_collision
stößt Objekte ab.
Das Vorladen (Preload) zu Beginn des Spiels wird verwendet, um Verzögerungen beim ersten Erscheinen des Objekts zu vermeiden. Dies hilft jedoch, wenn Sie die Schatten (und einige andere Optionen) aktivieren, werden die Verzögerungen beim ersten Erscheinen des Objekts erneut angezeigt. Auch im Browser hilft dies aufgrund der Besonderheiten von Browsern, die mit Shadern arbeiten, nicht.
Mehrere doppelte Objekte in einem und mehrere GIProbe, die Formen und Parameter von Lichtquellen sollen die Einschränkungen von OpenGL oder die Einschränkungen in Godot umgehen.
3. Gebrauchte Shader
Umweltpanorama:
Dieses Spiel verwendet ein statisches Panorama, das Bild wird von diesem Shader erhalten (c1 c2 Farben, ldir Position)
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.)); }
Um ein Panorama zu erhalten, entfernen Sie den Kommentar aus Zeile 57 panorama_uv(fragCoord,ro,rd);
und schreibe einen Kommentar in Zeile 58
Dynamische Panoramen für Godot in früheren Demos (YouTube und es gibt Links zum Code) Panorama der Wolken .
In dieser Demo wurde das Panorama des Tag / Nacht-Zyklus mit der Bewegung der Wolken verwendet:
Ein weiteres Tag / Nacht-Panorama zum Beispiel, auf Shadertoy habe ich es nirgendwo benutzt
Wenn Sie CubeMap für Godot in ein Panorama der Umgebung konvertieren müssen , habe ich einen einfachen Webkonverter erstellt .
Sehr einfache Shader:
Partikel-Shader bestimmen statisch ihre Position für die Animation oder nicht. Zum Beispiel spawn.shader)
Für ein zusätzliches Leuchten um Objekte , nicht nur Bälle, ist dies eine Zeile von gglow.shader (Zahlen können nach Bedarf geändert werden)
float intensity = pow(0.122 + max(dot(NORMAL, normalize(VIEW)),0.), 010.85);

Das Anzeigen von Textziffern in 3D , wie ich es in Godot verstehe, gibt es keine Möglichkeit dafür (ohne ein zusätzliches FBO (Ansichtsfenster) zu erstellen ), so dass ein einfacher Shader Zahlen aus einer Textur druckt (so dass es sich um Mipmapping handelt ), den Shader-Code
UI-Elemente:
Die benutzerdefinierte Form von UI-Panels für mich am einfachsten zu gestalten, liegt bei Shadern. Vielleicht stimmt das überhaupt nicht . Die richtige Methode wird hier als Beispiel gezeigt (im Abschnitt über die Benutzeroberfläche).
In diesem Spiel ist die einfachste Animation der Hintergrund des Menüs und die Anzeige ist HP . Oben, im Link zum Video des Tag / Nacht-Panoramas, wird es auch gemacht, es gibt Streifen an den Seiten und alle Animationen auf dem Shader.
Über das Futari-Addon-Modul:
Es funktioniert fast genauso wie dieser Shader für 2D-Partikel in Videos (siehe ab 1:41).
Eine 2D-SDF-Karte aller Polygone wird zu Beginn einmal auf dem Video erstellt und die resultierende Textur wird einfach an die Partikel gesendet. Die Partikel selbst bauen sich an der aktuellen Position normal auf und ändern die Bewegung.
futari-addon macht fast das gleiche, nur dass anstelle einer 2D- Texturkarte die Koordinaten von 3D-Kugeln und -Ebenen übertragen werden, die entsprechend den Bedingungen im Partikel-Shader verarbeitet werden, sodass Sie ihre Position und andere Parameter frei ändern können.
Plus, der Wind (in meinem 2D-Beispiel ist das Hinzufügen von Wind sehr einfach, da eine andere Textur mit + - Werten zur Geschwindigkeit beiträgt und die Partikel einfach den Geschwindigkeitswert dieser Karte an ihrer Position hinzufügen).
Das Futari-Addon-Modul ist sehr gut , es wird verwendet, anstatt ein eigenes Partikelsystem zu erstellen.
Schildeffekt:
Partikel, an die die Koordinaten des Aufpralls auf die Kugel und die Position des Spielers sowie die Auslöschung über den Transformations-Rückkopplungspuffer übertragen werden. Shader- Code in der Datei en_m.shader
Bots Shield:

Shader als dreidimensionales Geräusch sheild.shader funktioniert dank der hier originalen flow
Funktion im Wesentlichen alles
Der Hintergrund wird durch gl_FrontFacing
und dunkler und grüner gemalt, nicht blau.
Reaktion auf einen Schlag - der Schockereignis-Timer wird einfach übertragen.
Shader, die ihren letzten Frame lesen, oder Feedback / Multipass-Shader:
Fast alle Effekte werden mit dieser Logik erzielt.
Einer der Shader aus dem Spiel .
Als Quelle habe ich eine orthogonale Kamera eingestellt , die Objekte in einer bestimmten Gruppe aus kurzer Entfernung aufnimmt (ohne die gesamte Szene zu verarbeiten).
.
Eisfeldeffekt:
Der Shader ist oben angegeben. In der Projektdatei befindet sich ice_feedback.shader und ein Fragment- Shader für die Ebene, der mithilfe einer einfachen Tiefenschleife die Illusion der Tiefe des Bodens erzeugt:
while(current_depth < depth){ ofs -= delta; depth = textureLod(texture_depth, ofs,0.0).r; current_depth += layer_depth; }
Partikelfeldeffekt:
Der Shader ist der gleiche , die y
Koordinate (Höhe) der Partikel entsprechend der Helligkeit der Farbe des Rahmenpuffers vom Shader, die Farbe auch entsprechend der Farbhelligkeit ( ich habe den Partikel-Shader nicht separat floor/visible_/floor3/grass/grass
, er befindet sich im Projekt im Objekt floor/visible_/floor3/grass/grass
).
Dynamische Flaggenanimation:
Godot hat SoftBody zum Animieren der Fabric, aber es ist eine CPU, also habe ich sie nicht verwendet. Ich habe einen vorgefertigten Code- Link zum Original verwendet . Diese Flagge wird von drei Bällen an der Seite gedrückt und der Kopf des Charakters ist der vierte Ball.
Die Logik des Multipass- Shaders, wie im obigen Beispiel, mit nur drei Achsen, dem Multipass- Code des Shader (1) flag.shader , der Shader, der das Flag zeichnet, zeigt nur die Textur und ändert die Geometrie des plane (2) flag.shader .
Aussehen der Figuren:
Formen haben kein UV, daher triplanares Textur-Mapping für das Textur-Mapping und Dreieck ( Vertex ), alles Code in cchess.shader
Animation einer Hitbox (roter Rahmen), die dem Charakter des Spielers Schaden zufügt, und einer Spur aus dem Rahmen (Partikel sind offensichtlich):
Es wird nur der bereits angegebene Shader gglow.shader verwendet .
PS Die gleiche Animation in einem Shader erstellt , Link zu Shadertoy
Für Partikel werden nur zwei Texturen verwendet, ein Kreis und ein Quadrat.
4. Über Godot und seine Merkmale
Godot ist sehr gut und einfach (nicht für Anfänger). Ich mochte Godot wirklich wegen seiner Eigenschaften.
Es gibt viele Fehler, die Godot-Dokumentation ist unvollständig und manchmal aufgrund von Fehlern irreführend und zeigt keine kritischen Punkte an (für mich nicht offensichtlich), um zu verstehen, welche Godot den gesamten Quellcode viele Male neu lesen musste (der Code ist nicht groß und gut geschrieben).
Dies ist nur mein Eindruck, es kann falsch sein, ich möchte niemanden irreführen.
Ich betone, dass selbst sehr kritische Fehler in Godot mit minimalem Aufwand durch GDScript in Godot selbst umgangen werden können. Was ist zweifellos ein großes Plus
Ich stelle auch fest, dass Godot in keiner Weise vor den Besonderheiten externer Faktoren wie WASM in Browsern, ANGLE-Einschränkungen, starken Einschränkungen der Browser selbst und natürlich Dutzenden von Fehlern in Grafikkartentreibern geschützt ist. All dies muss manuell umgangen werden.
Verzögerungen - es gibt ein großes Problem mit dem Management, es ist 100% auf der Godot-Seite, ich habe es nicht behoben. (Kontrollkeile während der Kompilierung von FPS-Shadern und Verzögerungen (z. B. in einem Browser)), es gibt auch andere Protokolle, die sich auf die Funktionen des 3D-Renderings in Godot beziehen. Einige davon habe ich umgeleitet, aber sie existieren noch / können es sein.
5. WebGL2 funktioniert Nur Linux
Starten Sie das Spiel nicht über den Link, wenn Sie Windows haben. Link zur WebGL2 / WASM-Version.
Informationsupdate : Die WebGL-Version wurde in Windows 10 (nur in Firefox mit deaktiviertem ANGLE) auf einem superstarken PC (i9 / 16-GB-RAM / 8-GB-Video) gestartet, obwohl der Boden (aus irgendeinem Grund) nicht mehr gerendert wurde und der Firefox Speicher verliert (> 16 GB) ) in fünf Minuten ... es ist besser, nicht auf eigene Gefahr und Gefahr zu rennen
Funktioniert nur unter Chrome 76+ und Firefox (Linux).
Ein Fehlerbericht (Link) wurde über Windows gesendet . Wenn dies ein Browserfehler ist, reagiert Google nach 2 Monaten. Aber anscheinend ist dies ein Fehler in ANGLE, und dies wird mit ziemlicher Sicherheit nicht behoben.
Der Bugreport ist bereits geschlossen und ANGLE wird ebenfalls nicht bearbeitet. Unter Windows funktioniert der Browser also nicht.
Im Verlauf dieses Projekts wurde ein Fehler in Chrome behoben, aufgrund dessen Transformations-Feedback und meine letzte Demo (über dem Video mit einem Tag / Nacht-Panorama) , die zuvor nicht funktioniert hatte, zu funktionieren begannen.
6. Multiplayer
Multiplayer hinzugefügt, ausschließlich zu Testzwecken (und Beispiel-Multiplayer in Godot). Quellcode und Binärversionen neben der Hauptversion auf dem Github und Juckreiz (Links am Anfang).
Wenn Godot 3.2 herauskommt, werde ich auch WebRTC für den Test hinzufügen.