Physik-Browser-Simulation



In diesem Artikel möchte ich vorhandene Lösungen zum Erstellen von Anwendungen mit Physiksimulationen beschreiben, deren Leistung und die bereitgestellten Tools vergleichen.

Einführung


Die folgenden Motoren werden im Artikel berücksichtigt:

Ammo.js
Cannon.js
Oimo.js
box2dweb
Unity3D WebGL

Das Hauptziel war die Auswahl der produktivsten, bequemsten und leichtesten Engine für die Entwicklung von Spielen und Anwendungen mithilfe von Physiksimulationen.

Ammo.js


Es ist eine Portierung der Bullet-Physik-Engine in Javascript, die den Emscripten-Compiler verwendet, und hat laut den Entwicklern nahezu identische Funktionen. Die Funktionalität von Ammo.js ist wirklich umfangreich. Um damit arbeiten zu können, benötigen Sie eine separate Bibliothek zur Visualisierung. Am häufigsten wird Three.js verwendet. Darüber hinaus muss jeder Neuzeichnungszyklus die Position und Drehung jedes Objekts in der Szene manuell mit seinem physischen Modell synchronisieren. Die Engine führt dies nicht automatisch durch.

Die Leistung ist nicht zu hoch, aber in den meisten Projekten sind keine fps-Drawdowns zu verzeichnen.

Die API kann manchmal ziemlich verwirrend sein und die Dokumentation hilft nicht wirklich.
Im Allgemeinen ein sehr gutes Werkzeug, das sich weiterentwickelt und weiterentwickelt.

Cannon.js


Cannon.js ist eine Open-Source-Physik-Engine. Im Gegensatz zum vorherigen wurde es ursprünglich in Javascript geschrieben und ermöglicht es Ihnen, alle seine Funktionen und Optimierungen zu nutzen. In der Tat ist es schwierig zu sagen, ob dies ein Plus oder ein Minus ist, da kompilierter Code viel effizienter sein kann als von Grund auf neu geschrieben. Trotzdem gilt cannon.js als kompakter, produktiver und im Vergleich zu ammo.js auch leichter zu verstehen, hat aber nicht so viele Funktionen. In der Praxis ist ihre Leistung oft ungefähr gleich.

Die Arbeit mit dem Motor ist ganz einfach:

//   var world = new CANNON.World(); world.gravity.set(0, 0, -9.82); //   (   ) //        var radius = 1; var sphereBody = new CANNON.Body({ mass: 5, position: new CANNON.Vec3(0, 0, 10), shape: new CANNON.Sphere(radius) }); world.addBody(sphereBody); var fixedTimeStep = 1.0 / 60.0; var maxSubSteps = 3; //    var lastTime; (function simloop(time){ requestAnimationFrame(simloop); if(lastTime !== undefined){ var dt = (time - lastTime) / 1000; world.step(fixedTimeStep, dt, maxSubSteps); } lastTime = time; })(); 

Für die Arbeit ist auch eine Grafikbibliothek eines Drittanbieters erforderlich, und jeder Renderzyklus muss das entsprechende Objekt in der Szene manuell an den Ort des physischen Objekts verschieben.

 mesh.position.x = body.position.x; mesh.position.y = body.position.y; mesh.position.z = body.position.z; mesh.quaternion.x = body.quaternion.x; mesh.quaternion.y = body.quaternion.y; mesh.quaternion.z = body.quaternion.z; mesh.quaternion.w = body.quaternion.w; 

Im Moment entwickelt sich die Engine praktisch nicht, die letzte Aktivität im Projekt-Repository vor mehr als 2 Jahren, und zu diesem Zeitpunkt begann die Engine gerade erst mit der Entwicklung, sodass sie an einigen Stellen möglicherweise nicht funktioniert.

Oimo.js


Oimo.js ist eine Version der OimoPhysics- Engine, die in reinem Javascript umgeschrieben wurde. Im Vergleich zu anderen Lösungen weist es eine sehr gute Leistung und Genauigkeit auf, unterstützt jedoch nur primitive Geometrie (Würfel und Kugeln). Es ist in Babylon.js enthalten, einem Framework zum Rendern von 2D- und 3D-Grafiken, sodass keine zusätzlichen Bibliotheken erforderlich sind.

 //   world = new OIMO.World({ timestep: 1/60, iterations: 8, broadphase: 2, worldscale: 1, random: true, info: false, gravity: [0,-9.8,0] }); //    var body = world.add({ type:'sphere', size:[1,1,1], pos:[0,0,0], rot:[0,0,90], move:true, density: 1, friction: 0.2, restitution: 0.2, belongsTo: 1, collidesWith: 0xffffffff; }); var body = world.add({ type:'jointHinge', body1: "b1", body2: "b1", }); world.step(); //           myMesh.position.copy( body.getPosition() ); myMesh.quaternion.copy( body.getQuaternion() ); 

Ein großes Minus der Engine ist keine sehr hochwertige Dokumentation, aber die Entwickler arbeiten weiter daran.

Im Moment entwickelt sich der Motor weiter.

box2dweb


box2dweb ist der Javascript-Box2d-Port. Wie der Name schon sagt, ist es auf die Simulation der 2D-Physik spezialisiert. Trotzdem ist box2dweb ein ziemlich leistungsfähiges Tool, das nicht hinter seinen dreidimensionalen Gegenstücken zurückbleibt. Zum Beispiel enthält der Motor äußerst bequeme Systeme zum Erkennen von Kollisionen und zum Simulieren von Verbindungen (Einschränkung).

Was die Leistung betrifft, müssen Sie wirklich versuchen, nicht den optimalen Code zu schreiben, damit fps-Drawdowns angezeigt werden.

Von den Vorteilen ist auch die Einfachheit der API und die praktische Dokumentation zu erwähnen.

Unity3d


Unity3D ist eine beliebte plattformübergreifende Spiel-Engine. Enthält einen einfachen, praktischen Drag & Drop-Editor und ein umfangreiches Toolkit zum Erstellen von 3D-Inhalten. Die neueste Version der Engine zum Schreiben von Spielelogik unterstützt C #.

Unity verfügt über eine integrierte Physiksimulation, für die die integrierte PhysX- Engine von NVIDIA verwendet wird. PhysX bietet umfangreiche Funktionen zur Simulation der Physik von Festkörpern, Flüssigkeiten und Geweben und weist eine sehr gute Leistung auf, obwohl viele Vorteile bei der Arbeit mit anderen Grafikbeschleunigern als NVIDIA aufgehoben werden. Eine äußerst erfreuliche Tatsache ist, dass ab dem 3. Dezember 2018 der Quellcode der Engine unter der offenen BSD-3-Lizenz verfügbar ist. Die Engine ist jedoch zu komplex, um sie selbst neu zu schreiben oder das Gerät zu verstehen. Daher hilft die Dokumentation hier besser.

Unity landete auf dieser Liste, da es möglich ist, unter WebGL ein Projekt darauf zu erstellen. Wählen Sie dazu einfach das entsprechende Element in den Build-Einstellungen aus.



Trotzdem weist die WebGL-Version von Unity aufgrund der Besonderheiten ihrer Architektur (Übersetzung von Code von C # nach C ++ und weiter nach JavaScript) eine Reihe von Problemen mit der Leistung, dem Speicherverbrauch und der Arbeitskapazität auf Mobilgeräten auf, und es scheint nicht, dass Entwickler dies tun werden bald etwas zu tun. Daher ist diese Option nicht beliebt und ich werde sie nicht im Detail betrachten.

Leistungsvergleich


Vergleichen wir die Leistung der Engines anhand der Art und Weise, wie sie mit der Verarbeitung von Kollisionen einer großen Anzahl von Objekten umgehen. Der verwendete Browser ist Firefox 64.0.2 x64.
Motorfps bei der Verarbeitung von 100 Objektenfps bei der Verarbeitung von 500 Objektenfps bei der Verarbeitung von 1000 Objekten
ammo.js40-5025-2715-25
cannon.js30-4020-2515-20
oimo.js45-5535-4035-40

Laut den Testergebnissen zeigt Oimo.js die beste Leistung.

Natürlich bieten diese Ergebnisse keine angemessene Einschätzung der Produktivität, da sie von vielen Faktoren Dritter abhängen, aber eine vollständige Studie würde viel mehr Zeit in Anspruch nehmen, und ich habe mir kein solches Ziel gesetzt. Darüber hinaus fällt auf, dass die Leistung aller verglichenen Engines eher gering ist, sodass diese Lösungen nicht zum Schreiben weit entfernt von jedem Spiel geeignet sind, sondern sich gut zum Erstellen kleiner Demos eignen.

Fazit


Im Allgemeinen hängt die Wahl eines bestimmten Motors von der Aufgabe ab. Wenn Sie eine leicht verständliche und leicht zu erlernende Engine benötigen, ist Cannon.js oder Oimo.js. gut geeignet. Wenn mehr Funktionen erforderlich sind, ist es besser, Ammo.js zu verwenden. In bestimmten Situationen können Sie Unity verwenden, wenn keine hervorragende Leistung erforderlich ist.

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


All Articles