Pixelgenaue Kollision per Shader und GPU möglich?

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Pixelgenaue Kollision per Shader und GPU möglich?

      Ich habe im englischen Forum einen Thread damit eröffnet, aber er weckte kein Interesse:

      forum.yoyogames.com/index.php?…lision-with-shader.59678/

      Das PDF mit der Erklärung(Englisch)


      Vielleicht befinde ich mich auf dem sprichwörtlichen Holzweg, aber in 3D Engines werden Kollisionen
      mittels GPU gelöst, da werden schon mal 1 Million Dreiecke in 35 Millisekunden geprüft.
      Ein PDF, das etwas Licht in die Sache bringt, fand ich, aber mein Englisch und meine Programmierkünste
      sind zu schlecht, um das auch nur annähernd umzusetzen.

      Frage ist also, ist das in GMS umsetzbar, sinnvoll oder einfach nur Quatsch?

      Denn für mich wäre diese Technik die Verbindung, zwischen Tiles und Instanzen, was Kollisionen anbelangt.
      Man könnte doch alle Objekte eines Layers, als Maske auf ein Surface zeichnen(in Schwarz?) und dann diese
      Maske gegen ein beliebiges Objekt(Player oder Feind) prüfen, ob eine Überlappung vorliegt.
      Damit könnte man einen ganzen Bildschirm auf einmal prüfen(z.B.: auf Wände) und das Ganze wäre super
      schnell und Pixelgenau, da man es mit der GPU machen würde.

      Vielleicht kann ja jemand etwas dazu sagen, der sich mit der Materie etwas auskennt :)


      Miradur
    • Miradur schrieb:

      aber in 3D Engines werden Kollisionen
      mittels GPU gelöst
      Mir wäre dies neu. In welcher Engine ist dass denn so gelöst bzw. wo hast du das gehört?

      Es stimmt zwar dass durch die einführung von GPU compute fähigkeiten in modernen GPUs die Anwendungsmöglichkeiten dieser auch in andere Bereiche übergehen können (simple Physik simulation für z.B: Partikeleffekte),
      für normale Kollissionserkennung verwendet man aber weiterhin die CPU. (u.a. weil die Kollissionserkennung viele Branches in der Logik haben kann die GPUs garnicht mögen, es limitationen bei der Art wie Informationen an die GPU gesendet/wie diese gelesen werden gibt, etc... Zudem hast du weitere Probleme wie die verringerte GPU leistung durch weitere nicht-grafische kalkulationen und erhöhte Speicherbandbreite.)

      Miradur schrieb:

      Frage ist also, ist das in GMS umsetzbar, sinnvoll oder einfach nur Quatsch?
      Jein. Wenn du GMS2 verwendest wirst du DX11 als Render backend verwenden. Wenn du geschickt bist und dich mit DX11/GPU compute/C++/DLLs auskennst wirst du evtl irgendetwas lauffähiges auf die Beine stellen können. (Ob die implementierung überhaupt praktisch ohne größere hürden/probleme verwendbar wäre sei mal dahingestellt.)

      Nativ ist dies aber im GM (meines Wissens nach) nicht möglich.


      Miradur schrieb:

      Denn für mich wäre diese Technik die Verbindung, zwischen Tiles und Instanzen, was Kollisionen anbelangt.
      Man könnte doch alle Objekte eines Layers, als Maske auf ein Surface zeichnen(in Schwarz?) und dann diese
      Maske gegen ein beliebiges Objekt(Player oder Feind) prüfen, ob eine Überlappung vorliegt.
      Damit könnte man einen ganzen Bildschirm auf einmal prüfen(z.B.: auf Wände) und das Ganze wäre super
      schnell und Pixelgenau, da man es mit der GPU machen würde.
      Ja, du kannst sowas zwar machen (verwende einen Shader der 2 Masken als Input annimmt und dir den output in eine weitere Textur schreibt), das Problem allerdings hier ist dass du die Informationen aus der Textur auf CPU seite auslesen musst. Du wirst also konstant den GPU memory bus mit zusätzlicher Speicherbandbreite beanspruchen was sich negativ auf deine GPU performance ausüben wird.

      Zudem bist du im Falle eines normalen Shaders im bezug die Ausgabemöglichkeit solcher informationen im GM limitiert. Im Falle eines Shaders der die überlappung 2er masken ausgibt würdest du z.B: eine Textur rausbekommen wo jeder Pixel bei dem eine Überlappung stattfinden würde schwarz eingefärbt wäre und der Rest weiß.

      Die CPU müsste nun die Textur von der GPU über den Bus auslesen und durch jeden Pixel durchiterieren um zu schauen ob einer von denen schwarz eingefärbt ist oder nicht.

      Das ist verdammt ineffizient und zahlt sich wirklich nicht aus.

      /Edit: Es wäre erwehnenswert dass die oben beschriebene Methode zwar kein GPU compute benötigt, aber eben verdammt ineffizient ist.

      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von LEWA ()

    • Hmm also in 3d wird (immer) öfters raytracing verwendet. Das was du da meinst mit der Maske klingt zwar ganz toll, da sehe ich aber auch ein Problem, was ist wenn da was dynamisch ist, dann musst du dein surface order was auch immer neu malen. Ich sehe auch definitiv keinen Grund warum du sowas suchst, bist du schon an die Grenzen der Engine gestoßen? Wenns dir um sowas wie tile collisions geht, wieso erstellst du nicht einfach ein Grid und füllst es mit 1 für Wand und 0 für Luft?
      Wenns wirklich die GPU sein muss dann kannst du wohl Vertexkoordinaten als collision mesh benutzen, sowas hab ich schonmal gemacht und war recht vielversprechend, allerdings ohne GPU pille palle.
      Soll jetzt nicht böse aufgefasst werden aber anstatt seit Wochen rumzujammern über collisions wieso setzt du dich nicht einfach dran und probierst dich mal aus. Man kann quasi alles machen mit dem GM, und vieles sogar effizient. Ich hab einfach das Gefühl du zerbrichst dir den Kopf über Probleme die eigentlich keine sein sollten. Auch ich als langjähriger GM user lerne jeden Tag noch was dazu, manchmal sieht man die einfache bessere Lösung neben der komplizierten nicht.
      132 little bugs in the code. 132 little bugs. Fix a few, set the compiler to stew, 172 little bugs in the code... :vogel:
    • Danke für die schnelle Antwort :)
      GPU Kollision wird immer öfter in 3D eingesetzt und das hat begonnen, als es darum ging,
      Stoffe zu simulieren, die natürlich fallen sollten.
      Hier nochmal ein PDF dazu, wo ein Kollisionssystem auf GPU Basis bereits 2003 thematisiert
      wurde und damals war es schon sagenhaft schnell.

      gamma.cs.unc.edu/CULLIDE/cullide.pdf


      Genau der Vergleich bei Shadern brachte mich eben darauf, denn so wie Du sagst, gibt der
      Shader die Überlappenden Teile zurück und da dachte ich, wenn es möglich ist, einfach zu
      erkennen, dass eine Überlappung vorhanden ist(k.A. ob es dafür einen Befehl geben würde),
      dann wäre das doch irre schnell. Also so quasi eine false, wenn keine Übereinstimmung gefunden
      wurde und ein true, wenn doch, was dann ja eine Kollision wäre.
      In alten Spielen wurden ja bereits solche s/w Masken eingesetzt und ein ganzes Level auf einmal
      geprüft, aber eben Binär.
      Dazu habe ich leider nie etwas in Deutsch gefunden, aber ich denke, das lief alles in ASM ab
      und es ist fraglich, ob das heute noch in akzeptabler Geschwindigkeit anzuwenden wäre.
      Ich habe jedenfalls schon länger nichts mehr dazu gefunden. Vielleicht fehlen mir aber auch
      die passenden englischen Wörter, um danach zu suchen, denn das ist ja schon sehr speziell und
      technisch.


      Miradur
    • @Rhazul, danke auch Dir, für Deine schnelle Antwort :)

      Danke für den Tipp, aber das mit 0 und 1 mittels Grid, habe ich schon durch, funktioniert
      ja auch, aber noch schöner wäre es eben, wenn es Pixelgenau und mit jeder beliebigen
      Form funktionieren würde. Ich finde es eben ein wenig merkwürdig, dass GMS zwar ein
      Flag für Solid anbietet, ich es aber trotzdem noch abfragen muss.
      Wäre doch viel einfacher, dass es bei Solid Objekten einfach nicht weiter geht und dann
      würde auch die pixelgenaue Kollisionsmaske mehr Sinn ergeben und das Leben vieler
      wäre viel einfacher und wenn man das Solid Flag nicht setzt, dann macht man sich die
      Abfrage eben selbst.
      Letztendlich ist ja GMS eine Game-Engine und da dürfen schon ein paar grundlegende
      Erleichterungen enthalten sein und seien wir uns doch mal ehrlich, eine korrekte Kollision
      (die noch dazu Pixelgenau ist), gehört eben nicht zu den einfachen Dingen, also warum
      sie den großteils unbedarften Usern zumuten.
      Aber es ist schon richtig, wenn ich ein Haar in der Suppe finde, dann dreht sich nur noch
      alles um dieses Haar, wenn Andere eins finden, nehmen sie es raus und haben noch immer
      eine leckere Suppe.


      Miradur
    • Miradur schrieb:

      GPU Kollision wird immer öfter in 3D eingesetzt und das hat begonnen, als es darum ging,
      Stoffe zu simulieren, die natürlich fallen sollten.
      Da würde ich wie zu beginn gesagt gerne irgendein Beispiel haben.
      Physik basierte simulationen wurden überwiegend auf der CPU berechnet. Natürlich stimmt es dass durch die moderneren GPUs solche simulationen in bestimmten Fällen auf den Grafikprozessor ausgelagert werden können (mit Restriktionen), aber dies sind eher Ausnahmen als die Regel.


      Miradur schrieb:

      Hier nochmal ein PDF dazu, wo ein Kollisionssystem auf GPU Basis bereits 2003 thematisiert
      wurde und damals war es schon sagenhaft schnell.
      Ich bin das Paper mal schnell durchgeflogen. Die scheinen da einfache Rasterization mit einem Stencil buffer zu verwenden weshalb dies selbst auf einer Geforce 5 zu laufen scheint.
      (Allerdings k.a. wie die die Ergebnisse zur CPU senden.)

      Aber selbst da gleich zu beginn auf der ersten Seite unter "Introduction" zeigen die die Limitationen ihrer technick auf:

      - Erhöhte Speicherbandbreite (degradation der GPU performance)
      - Nur "abgeschlossene" Objekte ohne lücken. (Ein Rechteck wo eine Seite fehlt funktioniert hingegen nicht. Ein singler Triangle-Triangle check geht auch nicht)
      - Pro Kollissionscheck können nur 2 Objekte überprüft werden. (es können keine riesigen Welten auf einmal überprüft werden.)

      Dies in kombination mit der Tatsache dass deine GPU ressourcen für die eigentliche Grafische berechnungen reduziert werden, macht es schwer diese Methode zu empfehlen.


      Miradur schrieb:

      wenn es möglich ist, einfach zu
      erkennen, dass eine Überlappung vorhanden ist(k.A. ob es dafür einen Befehl geben würde),
      dann wäre das doch irre schnell. Also so quasi eine false, wenn keine Übereinstimmung gefunden
      wurde und ein true, wenn doch, was dann ja eine Kollision wäre.
      Das ist eben aber nicht "einfach so" möglich. Die GPU spuckt dir mit traditioneller Rasterisierung nicht einfach einen true/false wert zurück ob was überlappt oder nicht.
      Im GM wirst du an die traditionellen Rendering methoden gebunden sein. Sprich: Render eine differenzmaske aus 2 input texturen mit einem Shader die dann von der CPU pixel für Pixel ausgelesen wird.

      Mit Compute Shadern wird man mehr möglichkeiten was dies anbelangt haben, aber selbst da hat man limitationen die man beachten muss. (die CPU ist da wesentlich flexibler.)

      Miradur schrieb:

      In alten Spielen wurden ja bereits solche s/w Masken eingesetzt und ein ganzes Level auf einmal
      geprüft, aber eben Binär.
      Kommt darauf an was du unter "alt" verstehst. Wenn du richtig alte Spiele (Amiga z.B) meinst, musst du bedenken dass damals die Hardware doch anders funktionierte als heute. Es gab z.B: keine dedizierte GPU/GPUram.
      Du konntest mit der CPU direkt in den Speicher schreiben welcher dann direkt vom Bildschirm gelesen und angezeigt wurde.
      Bei sowas wirst du natürlich spezifische Tricks anwenden können die aber mit der heutiger Hardware inkompatibel sind.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von LEWA ()

    • meine "two cents" - passend zum Thema, aber andere herangehensweise (Surfaces statt Shader):



      ancient-pixel.com
      youtube.com/user/SebastianMerkl <<< ich freu mich über einen Besuch ;)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Aku_Ryou ()

    • @Aku_Ryou, gar nicht dumm 8o , auf das wäre ich nie gekommen, weil mich die Beschreibung,
      bei den Surface Befehlen schon immer damit abgeschreckt hat, dass man zwar einzelne Pixel
      prüfen kann, aber die Funktion sehr langsam und rechenintensiv sei. Das würde es schon fast
      rechtfertigen, Dich mit Genie anzusprechen :)

      Ich fasse mal zusammen, wie Du das wahrscheinlich machst, nur für den Fall, dass ich Dich unter
      Umständen missverstanden habe.

      Du erstellst ein Surface, wo Du alle festen Objekte(von Layern) in Schwarz noch mal drauf malst
      und fragst dann den Hotspot des Players mittels surface_getpixel(surface_id, x, y) au dem Surface
      ab, ob an der Stelle dort ein schwarzer Pixel ist. Falls ja, wäre es eine Kollision.
      Diese Art der Kollisionsprüfung würde ja auch für Tiles gelten, daher finde ich Genie gar nicht so
      abstrus, als Anrede, für Dich.

      Sollte ich damit falsch liegen, würdest Du dann bitte ein wenig genauer auf Deine Herangehensweise
      eingehen?


      Miradur