Three.js: SkinnedMesh-Fehler, wenn weit vom Szenenstamm entfernt (0,0,0)

Erstellt am 9. Feb. 2018  ·  113Kommentare  ·  Quelle: mrdoob/three.js

Ich glaube, ich habe einen Fehler in Bezug auf Ihr SkinnedMesh gefunden (getestet auf iPhone 6 und 8).

Wenn dies bereits gemeldet wurde, habe ich es leider nicht in der Problemliste gefunden :(

Es scheint, dass das GPU-Skinning nicht richtig funktioniert und auf dem Handy verrückt wird.
Wenn sich ein SkinnedMesh bewegt oder an Positionen mit hohem Wert bewegt wird (z. B. x: 0, y: 0, z: 1000), ist das Skinning nicht mehr genau und beginnt mit dem Spinnentanz.

Die Größe des Netzes wirkt sich auf den Fehler aus.

Es scheint, dass die Skelettknochenwerte nicht bei jedem Frame korrekt berechnet werden und die BonesTexture / BonesMatrix auf dem Skinning-Shader die Scheitelpunkte an die falsche Stelle drückt.
Das ist natürlich nur mein Gefühl.

Ich habe viele Tests durchgeführt, bevor ich dies gepostet habe ... nach einem Hinweis in meinen animierten Exporten gesucht, aber ich habe festgestellt, dass der Fehler bei allen Formaten (GLTF, FBX, Collada, JSON, ...) und Modellen von ThreeJS Repo auftritt.

Das ist sehr ärgerlich, denn das bedeutet, dass wir kein einfaches Runner-Spiel mit einem laufenden Avatar entwickeln können (avatar.position.z steigt dann), ohne dieses Problem zu haben: ((
Ich weiß immer noch nicht, wie ich es verwalten soll, da morphTargets keine Option ist :(

Hoffe ihr könnt hier helfen.

Ich habe klare Beispiele mit sauberer Quelle gemacht, um das Problem aufzudecken. Es ist ganz einfach, es auf einem Smartphone zu überprüfen:

Erscheint nur auf Mobilgeräten (z = 10000):
http://cornflex.org/webgl/skinning-bug.html

Wenn floatVertexTextures auf false gesetzt ist (z = 10000):
http://cornflex.org/webgl/skinning-bug2.html

Mit zunehmender Entfernung schlechter werden (z zunimmt):
http://cornflex.org/webgl/skinning-bug3.html

Sehr, sehr weit vom Zentrum entfernt (z = 70000000)> Fehler, der auch auf dem Desktop auftritt, aber sicherlich aufgrund eines Problems mit der Float-Genauigkeit:
http://cornflex.org/webgl/skinning-bug4.html

Videovorschau in meiner Spielumgebung:
Dies ist eine realistische Skalenwelt (1,0 m = 1,0 drei js Einheit).
Der Fehler tritt erst 50-60 m von der Szenenwurzel entfernt auf und wird mit der Entfernung immer schlimmer:
http://cornflex.org/webgl/skin-bug.mp4

SEHR WICHTIG
Das vom ThreeJS-Repo verwendete Netz ist viel zu groß. Es ist wie 20 m groß.
Deshalb muss der z-Wert größer sein, um den Fehler zu erkennen.
Wenn dieses Netz auf eine realistische Größe verkleinert wird, tritt der Fehler bereits bei 100 m auf.

Three.js Version
  • [x] Dev
  • [x] r89
  • [x] ...
Browser
  • [ ] Alle von ihnen
  • [ ] Chrom
  • [ ] Feuerfuchs
  • [ ] Internet Explorer
  • [x] Safari
Betriebssystem
  • [ ] Alle von ihnen
  • [] Windows
  • [ ] Mac OS
  • [] Linux
  • [ ] Android
  • [x] iOS
Hardwareanforderungen (Grafikkarte, VR-Gerät, ...)

iPhone 6, 8

Bug

Hilfreichster Kommentar

Ich möchte diesen Abschnitt des Benutzers zeoverlord hervorheben :

Das Jittering ist nur für Floats natürlich. Variablen verlieren an Genauigkeit, je höher die Zahl ist. Je näher sie an 1,0 liegt, desto besser ist die Genauigkeit. Nun, das ist nicht wirklich ein Problem, aber es bedeutet, dass wenn Sie viele Matrixberechnungen mit großen Zahlen durchführen, Sie eine große Präzisionsverschlechterung (auch bekannt als Jittering) haben werden. Sie müssen also alle Ihre Berechnungen rund um den Ursprung mit vernünftigen Zahlen durchführen und diese dann wegübersetzen

Alle 113 Kommentare

Ähm, deine Demo sieht auf meinem Pixel gut aus.

Bestätigte Probleme auf meinem iPhone SE -

img_6324

Probleme mit der WebGL-Genauigkeit in iOS möglicherweise

Aber die iOS-Geräte verwenden tatsächlich den Float-Textur-basierten Codepfad der Skinning-Implementierung, oder? Können Sie dies mit dem folgenden Konformitätstest überprüfen?

https://www.khronos.org/registry/webgl/conformance-suites/1.0.3/conformance/extensions/oes-texture-float.html

Das iPhone SE weist auf dieser Seite fünf Fehler auf. 😕

Ich habe einen kleinen Screencast gemacht, um Sie in meinem Projekt zu zeigen:
http://cornflex.org/webgl/skin-bug.mp4

Wenn der Avatar zu weit von 0,0,0 entfernt ist, wird die Haut wirklich fehlerhaft, wie Sie sehen können.
Ich machte eine tiefe Profilierung des Skeletts und der Knochen. Alles scheint in Ordnung zu sein, außer dass die Geometrie in irgendeiner Weise "zurückgezogen" ist ... Ich dachte über schlechte Animationswurzel nach, aber auch hier scheint in Threejs alles in Ordnung zu sein ...

Das Problem ist eindeutig mit dem Skelett und der BonesTexture des Skinning-Shaders verbunden.
Ich habe auch über Präzision nachgedacht, aber wie Mugen sagte, sollte das iOS-Gerät dies problemlos unterstützen.

... warum dann nur auf dem iPhone: /

Ich stecke ziemlich fest ... Ich orientiere mich neu an PNG-Sequenzen als Backup-Plan ... :(

Dies ist höchstwahrscheinlich darauf zurückzuführen, dass das iPhone 6 nicht genügend Knochen unterstützt.

Ich hatte genau das gleiche Problem.

Überprüfen Sie hier Ihr Knochenlimit: https://virtulo.us/2/vr/test

Das glaube ich nicht.
Wenn das enthäutete Netz bei 0,0,0 bleibt, gibt es überhaupt kein Problem: /
Ich denke sogar darüber nach, alle Assets anstelle des Avatars zu verschieben ... (dies ist meine Problemumgehung Nr. 2), aber ich würde es sicherlich vorziehen, wenn das Skelett so gut wie der Desktop funktioniert.

Ein Freund hat gerade den gleichen Fehler auf dem iPhone 8 gemeldet

Nachdem ich mir 2 Tage lang die ThreeJS-Quellen angesehen habe ... Ich denke, es gibt ein Problem, wenn die BonesTexture aktualisiert wird.
Es sieht so aus, als würde diese Textur nicht richtig udpieren und dann die Scheitelpunkte an die ursprünglichen Positionen zurückschieben ... aber ich könnte mich natürlich irren.

img_1411

Hmmm ... hier habe ich einige gescheitert, schau:

img_1412

Möglicherweise hängt das Problem mit diesen Fehlern zusammen. Mein Pixel besteht zum Beispiel alle Tests.

Probieren wir etwas aus: Gehen Sie zu WebGLCapabilities und setzen Sie den Wert von floatVertexTextures auf false (dies verhindert die Verwendung der Float-Textur). Erstellen Sie einen Build und verwenden Sie diese three.js -Version in Ihrer App. Ich bin gespannt was passiert 😊.

https://github.com/mrdoob/three.js/blob/099e4364541502fdf22fc7b1c0f54239d2ba1708/src/renderers/webgl/WebGLCapabilities.js#L105

Bereits versucht floatVertexTextures = false auf dem Renderer.
Die Haut hört auf verrückt zu werden, aber es gibt keine Animation mehr: /
Ich werde eine Probe schieben.

Hier sind Sie ja:
http://cornflex.org/webgl/skinning-bug2.html

renderer.capabilities.floatVertexTextures = false;

=> Es läuft keine Animation mehr

img_1413

Ja, das gleiche gilt für mein Pixel (Desktop funktioniert). Ich denke, wir stoßen an ein einheitliches Limit.

Ich habe ein letztes Beispiel gemacht, wobei der Fehler nach und nach auftrat:
http://cornflex.org/webgl/skinning-bug3.html

Beginnt bei 0,0,0 und geht vorwärts ... warte ein paar Sekunden ... die Haut wird verrückt.

Es ist ziemlich seltsam, dass bei 0,0,0 alles in Ordnung ist. ist es nicht?

z: 1255> immer noch OK
z: 18870> verrückte Haut

img_1415

img_1414

Wie gesagt, ich habe das gesamte Skelett und die Knochenpositionen auf der CPU-Seite tief profiliert. Alle Werte scheinen ganz in Ordnung zu sein. Der einzige Hinweis, den ich habe, sind die BonesTextures und BonesMatrixes, die unter iOS nicht richtig funktionieren, wenn das Netz weit von 0,0,0 entfernt ist.

Ich habe die Knochenpositionen überprüft, weil es ein typisches Verhalten von stabilen Knochen des Wurzelknotens oder ähnlichen Dingen ist ... aber nein ...

Ich habe die Float-Präzision auf der GPU-Seite in Ihren Skin-Shadern überprüft, aber auch hier scheint nichts einen Einfluss zu haben.

Sehr seltsam, dass niemand ein SkinnedMesh innerhalb einer Szene bewegt hat und dies nie gemeldet hat: /

Noch eine Frage: Haben Sie das gleiche Problem mit Chrome?

Gleiches Problem ja.

img_1416

Klingt nach einem Präzisionsproblem. Haben Sie versucht, die Szene zu verkleinern? (11195 ist 11 Kilometer).

Eine andere Möglichkeit wäre, die Szene anstelle des Charakters zu verschieben. Neigt dazu, eine übliche Lösung für große Szenen zu sein.

Ich denke auch, dass sich der Skinning-Code im Weltraum befindet. Wir könnten das untersuchen.

Ich sehe, dass Ihre Knochenzahl 67 beträgt.

Mein (Frau) iPhone 6 hat ein maximales Hardware-Knochen-Limit von 27.

Die Deformationen, die ich sehe, sind identisch mit denen, die ich in meinem Spiel auf ihrem Handy gesehen habe (und das gleiche Problem, das ich hatte, bevor mein Animator die Maschen-Armituren reparieren ließ). Es würde mich wundern, wenn dies nicht zumindest Teil Ihres Problems wäre.

Warum wird es mit der Zeit schlimmer? Keine Ahnung. Jemand anderes erwähnte etwas Ähnliches, nicht sicher, ob es verwandt ist: https://discourse.threejs.org/t/updated-with-fiddle-as-animations-go-faster-there-is-increasing-error-in-accuracy/ 1707/6

Eine weitere nervige Sache, die ich auf iPhones gefunden habe (mindestens auf iPhone 6): Ich MUSS Highp-Shader-Präzision verwenden. Mediump und Lowp verzerren das Netz nicht auf dieselbe beängstigend aussehende Weise (wie mein Knochenproblem auf dem Telefon), aber die Texturen sehen aus seltsam und verstümmelt / pixelig beim Animieren.

Was ist Ihre Hardware-Knochengrenze für das Gerät, das Sie testen?

@mrdoob Ich habe bereits versucht, zu verkleinern, aber das Enthäuten wird tatsächlich viel schneller verrückt: /
Wenn Sie auf 0,1 verkleinern, tritt der Fehler zehnmal schneller auf.

Die Demo, die ich hier zur Erklärung verwendet habe, stammt aus den drei Beispielen.
In meinem Spiel ist die Skala nicht so groß, aber der Fehler ist der gleiche und erscheint nur schneller.

In der Tat scheint das Enthäuten im Weltraum oder im lokalen Raum durchgeführt zu werden, aber es wird gestreckt, wenn es weit vom Zentrum entfernt ist. Deshalb läuft es mit 0,0,0 recht gut

Die ganze Welt anstelle des Avatars zu bewegen, ist meine Workaroung # 2.
Sie müssen zugeben, dass es eine schlechte Wahl ist, wenn Sie die gesamte Routine eines Runner-Spiels im Weltraum bereits mit Physik und allem entwickelt haben. Und z = 11000 ist nicht so weit für ein Läuferspiel: / ... und es ist nur ein rennender Mann, kein Schiff.

Ich habe viele Spiele mit ThreeJS gemacht, aber es ist das erste Mal, dass ich ein Skinnedmesh benutze. Dieser iOS-Fehler ist wirklich ärgerlich.

Workaroung # 1: Ich mache 6 PNG-Sequenzen als Spritesheet-Animationen. Dann kann ich eine Weltraumlogik beibehalten. Frist ist nicht weit :(

@titansoftime Das Problem wird auch auf dem iPhone 8 meiner Frau angezeigt. Dies bezieht sich nicht nur auf das iPhone 6.
Wenn Sie ein Problem mit den maximalen Knochen haben, ist es von Anfang an fehlerhaft. Hier können Sie sehen, dass es bei 0,0,0 nicht fehlerhaft ist. Dann ist die Knochengrenze nicht das Problem. Die Weltraumberechnung der Knochen und der Knochenmatrix in Skinning-Shadern ist IMO.

Was sind die Max Hardware Bones des iPhone 8?

Ich weiß es nicht. Und ich bin mir nicht sicher, ob es geräteabhängig ist.

Aber nochmal ... IMO, es hängt überhaupt nicht mit dem Maxbones-Wert zusammen.

Das Beispiel funktioniert auf dem iPhone 6,8, X ... sogar 5 ... nur dann korrekt, wenn das SkinnedMesh bei 0,0,0 bleibt
https://threejs.org/examples/webgl_loader_fbx.html

Wenn maxbones ein Problem wäre, hätten wir auch bei 0,0,0 keine gute Haut.

Ich möchte diesen Abschnitt des Benutzers zeoverlord hervorheben :

Das Jittering ist nur für Floats natürlich. Variablen verlieren an Genauigkeit, je höher die Zahl ist. Je näher sie an 1,0 liegt, desto besser ist die Genauigkeit. Nun, das ist nicht wirklich ein Problem, aber es bedeutet, dass wenn Sie viele Matrixberechnungen mit großen Zahlen durchführen, Sie eine große Präzisionsverschlechterung (auch bekannt als Jittering) haben werden. Sie müssen also alle Ihre Berechnungen rund um den Ursprung mit vernünftigen Zahlen durchführen und diese dann wegübersetzen

Mmmh, sehr interessant @ Mugen87! Es hört sich so an, als hätten Sie das Leck entdeckt.

z: 1255> immer noch OK
z: 18870> verrückte Haut

Der Fehler könnte auf Ihrer Seite liegen.
Ein häufiger Fehler: Der Hautmodifikator wurde nicht richtig angewendet.
Fehler 1: Eckpunkte, die von zu vielen Knochen kontrolliert werden
Fehler 2: Eckpunkte ohne Gewicht (oder mit sehr geringem Gewicht).

Wenn sich das SkinnedMesh dem Ursprung (0,0,0) nähert, werden Sie diese Fehler nicht bemerken.
Aber wenn es weit weg ist ... werden Sie die Präzision des Mobilgeräts verantwortlich machen.
Das erste, was Sie tun müssen, ist, den Skin-Modifikator (diesmal richtig) neu zu gestalten.

@RemusMar Hast du dir die Quelle der Seite angesehen?
Das Beispiel, das ich ausgesetzt habe, stammt direkt aus den ThreeJS-Quellen.

Ganz gut erwähnt in meiner Beschreibung;)

Ich habe viele Tests durchgeführt, bevor ich dies gepostet habe ... nach einem Hinweis in meinen animierten Exporten gesucht, aber ich habe festgestellt, dass der Fehler bei allen Formaten auftritt (GLTF, FBX, Collada, JSON, ...)

Ich habe ein klares Beispiel mit sauberer Quelle gemacht, um das Problem aufzudecken. Es ist ganz einfach, es auf einem Smartphone zu überprüfen:

http://cornflex.org/webgl/skinning-bug.html

Das Beispiel, das ich ausgesetzt habe, stammt direkt aus den ThreeJS-Quellen.

Na und?

Wie der Fehler auf meiner Seite sein kann, wenn dies mit all den Skinnedmesh-Beispielen von ThreeJS passiert :)

Du sagtest:

Der Fehler könnte auf Ihrer Seite liegen.
Ein häufiger Fehler: Der Hautmodifikator wurde nicht richtig angewendet.
Fehler 1: Eckpunkte, die von zu vielen Knochen kontrolliert werden
Fehler 2: Eckpunkte ohne Gewicht (oder mit sehr geringem Gewicht).

FBX ist von ThreeJS ... und Sie können es mit GLTF oder einem anderen Format versuchen. Das Problem ist das gleiche.

var loader = new THREE.FBXLoader ();
loader.load ('https://threejs.org/examples/models/fbx/xsi_man_skinning.fbx', OnFBXLoaded);

@ Mugen87 hat einen Hinweis gefunden. Hoffen wir, dass der Typ, der das GPU-enthäutete Netz hergestellt hat, es reparieren kann.

Wie der Fehler auf meiner Seite sein kann, wenn dies bei allen Skinnedmesh-Beispielen von ThreeJS passiert

Ich sagte: "Der Fehler könnte auf Ihrer Seite sein."
Das Fazit:
Verwenden Sie ein einfaches SkinnedMesh mit richtig angewendetem Skin-Modifikator:

  • max 4 Knochen pro Scheitelpunkt
  • alle Gewichte = 1,0000

Überprüfen Sie, ob Sie den Fehler reproduzieren können.

Bist du böse? :) :)
Dieser Fehler kann nicht auf meiner Seite sein ... die Modelle (fbx, gltf, dae, was auch immer) und die Codequelle stammen von ThreeJS.

Bitte lesen Sie die @ Mugen87 Beiträge.

Verwenden Sie ein einfaches SkinnedMesh mit richtig angewendetem Skin-Modifikator:

  • max 4 Knochen pro Scheitelpunkt
  • alle Gewichte = 1,0000

Überprüfen Sie, ob Sie den Fehler reproduzieren können.

Ich muss jetzt gehen.
Prost

Hmmm. Weißt du was Jungs? Dies geschieht auch auf dem Desktop :(

Da das ThreeJS-Beispielnetz riesig ist (100 m hoch), habe ich es sehr weit platziert: z = 10000000
Und schau, gleiches Problem:
http://cornflex.org/webgl/skinning-bug4.html

Es ist definitiv etwas, das mit den Positionen der Weltraumknochen und den Knochenmatrix-Berechnungen zusammenhängt, wie von @ Mugen87 enthüllt :

https://www.opengl.org/discussion_boards/archive/index.php/t-159613.html
https://www.opengl.org/discussion_boards/archive/index.php/t-159364.html

Wie zuvor @mrdoob erklärt , habe ich bereits versucht, das Netz zu verkleinern, aber das Problem ist noch schlimmer ... sogar auf dem Desktop, und Sie stoßen dann auf den Fehler, der nicht weit von 0,0,0 entfernt ist.

In meinem eigenen Spiel (mit realistischen Maßstäben 1: 1) tritt der Fehler bereits bei z: 100 auf.

Sie verwenden weiterhin schlecht gestaltete Hautnetze ...
Um dieses Thema abzuschließen, hier die Fallstudie von 1 bis 1.000.000 (eine Million !!!):
http://necromanthus.com/Test/html5/Lara_1000000.html
Klicken Sie auf die Bühne, um zwischen Y = 0 und Y = 1000000 zu wechseln
Pro Schalter ist eine geringfügige globale Beleuchtungsänderung verfügbar.
Wenn das enthäutete Netz also richtig gestaltet ist, ist das Ergebnis (nahezu) perfekt.
Prost

Wir werden uns nach der Veröffentlichung dieses Monats darum kümmern.

@mrdoob Danke.

@RemusMar Sie ignorieren weiterhin, was hier gesagt wurde. Bitte lies den gesamten Thread nochmal :)

Ich habe Ihnen nur ein funktionierendes Beispiel gegeben, aber Sie verstehen es immer noch nicht.
http://necromanthus.com/Test/html5/Lara_1000000.html

Und Sie sprechen weiterhin über schlechte Praktiken .
Bitte beachten Sie Folgendes:
Die Gleitkommazahl der Ziffern mit einfacher Genauigkeit beträgt 7.
Das umfasst 1234.567 und 123456.7
Die meisten Gewichtskarten werden mit 4 Dezimalstellen geliefert, aber selbst eine einzige liefert anständige Ergebnisse.
Aus diesem Grund haben alle 3D-Engines einen Maximalwert von 10.000 für die Weltgröße empfohlen.
Von 0000.001 bis 9999.999
Wir alle wollen "unendliche" oder riesige 3D-Welten, aber das ist nicht möglich.
Was Sie tun, ist aus vielen Blickwinkeln völlig falsch:
Spieldesign, Performances, Animationen und Kollisionen.
Ich hoffe du hast jetzt das Hauptbild.

@ RemusMar
Ich habe ganz gut verstanden, was Sie gesagt haben, aber leider hat Ihr Modell das gleiche Problem ... in geringerem Maße, aber immer noch da:
http://cornflex.org/webgl/skin-bug2.mp4

Quelle:
http://cornflex.org/webgl/skinning-bug5.html

Und wenn ich eine Position höher als z = 60000 gebe, wird es schlimmer ... und bis zu 100000 ist es völlig unsichtbar.

Wir alle wollen "unendliche" oder riesige 3D-Welten, aber das ist nicht möglich.

LOL, ich will keine unendliche riesige Welt ... Ich möchte nur ein Runner-Spiel machen, wie ich es schon oft mit ThreeJS getan habe ... aber dieses Mal brauche ich ein Skinnedmesh als Avatar.

Meine Szene: http://cornflex.org/webgl/skin-bug.mp4

Wenn wir einen Avatar, der über mehrere Meter läuft, nicht animieren können ... worum geht es dann? (Im realistischen Maßstab 1m = 1 Drei-Einheiten-Einheit tritt der Fehler bereits bei 100 auf).

Übrigens, Ihr Modell ist ungefähr 150 m groß ... das ist kein realistischer Maßstab.
BEARBEITEN:
Hier die gleiche Szene mit Skalierung (0,01, 0,01, 0,01) auf Ihrem Modell, um eine realistische Größe zu erhalten (dann ca. 1,5 m). Wie Sie sehen können, ist es bereits bei z = 300 auf dem Handy fehlerhaft:
http://cornflex.org/webgl/skin-bug3.mp4

Was Sie tun, ist aus vielen Blickwinkeln völlig falsch:
Spieldesign, Performances, Animationen und Kollisionen.

LOL LOL ... Ich schlage vor, meine Websites und meinen Blog über das Erstellen von Spielen zu besuchen (http://quentinlengele.com, http://cornflex.org, http://www.ddrsa.com, http://br9732.com) )

BEARBEITEN: Ihre Szene ist unter iOS nicht sichtbar, leerer Bildschirm (http://necromanthus.com/Test/html5/Lara_1000000.html).
img_1418

Das Enthäuten scheint im Weltraum oder im lokalen Raum zu erfolgen, wird jedoch gedehnt, wenn es weit vom Zentrum entfernt ist. Deshalb läuft es mit 0,0,0 recht gut

Wir werden sehen:

vec3 transformed = vec3( position );
...
#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += boneMatX * skinVertex * skinWeight.x;
    skinned += boneMatY * skinVertex * skinWeight.y;
    skinned += boneMatZ * skinVertex * skinWeight.z;
    skinned += boneMatW * skinVertex * skinWeight.w;
    transformed = ( bindMatrixInverse * skinned ).xyz;
#endif

sieht für mich nicht nach Weltraum aus? Im regulären Netz wird transformed position Attribut

Was auch immer passiert, passiert auf js Seite, wo Bindungs- und Knochenmatrizen berechnet werden. Vielleicht macht die Bindematrix viel Dehnung, und Knochenmatrizen könnten so behandelt werden, dass sie in anderen Koordinaten arbeiten, die nicht so viel Dehnung in der Bindematrix erfordern ... oder so ähnlich

(edit: nvm, ich glaube ich habe das falsch verstanden)

me

@makc Leider werden in Ihrem Kopieren / Einfügen des Skinning-Shaders nicht genügend revalante Daten

Wie gesagt, mit der Berechnung der Knochenmatrizen stimmt sicherlich etwas nicht, oder die Reihenfolge dieser Matrizenberechnung stimmt möglicherweise nicht. Wie Sie im OpenGL-Forum sehen können und wie @ Mugen87 erwähnt hat, ist dies zumindest für mich der revalanteste Hinweis:

Das Jittering ist nur für Floats natürlich. Variablen verlieren an Genauigkeit, je höher die Zahl ist. Je näher sie an 1,0 liegt, desto besser ist die Genauigkeit. Nun, das ist nicht wirklich ein Problem, aber es bedeutet, dass wenn Sie viele Matrixberechnungen mit großen Zahlen durchführen, Sie eine große Präzisionsverschlechterung (auch bekannt als Jittering) haben werden. Sie müssen also alle Ihre Berechnungen rund um den Ursprung mit vernünftigen Zahlen durchführen und diese dann wegübersetzen

Wie bereits erläutert, wirkt sich die Skalierung des Objekts auf den Fehler aus.
Das Beispiel mit ThreeJS-Quellen zeigt diesen Fehler nur bei z = 100000, aber es liegt daran, dass die Größe des Netzes (das auch aus der ThreeJS-Quelle stammt) sehr groß ist. Der rennende Junge ist 150 m groß.

Wenn Sie ein Spiel machen, verwenden Sie diese Art von Skala natürlich nicht. Sie versuchen immer, Ihre Welt mit 1m = 1 Einheit zu halten. Dies ist sogar obligatorisch, um eine gute Physik und ein gutes Verhalten zu erreichen.

Das Problem hier ist, wenn Sie ein SkinnedMesh mit realistischer Größe verwenden: Der Fehler tritt bereits bei z = 300 auf.

In jeder Engine können Sie ein SkinnedMesh ablegen, indem Sie es auf x: 30000, y: 60000, z: 140000000 setzen, und es gibt kein Problem mit Knochen und Skinning. Kein Zittern.

Sicher verstehe ich ganz gut, dass wir hier an einem Javascript-Kern arbeiten ... aber immer noch.

Trolle, die hier so tun, als ob "wir alle unendliche Welten wollen, aber es ist unmöglich", müssen wieder zur Schule gehen und Matrixtransformationen lernen. Oder schauen Sie sich besser Open-World-Spiele an und fragen Sie sich selbst, wie ihr Avatar sooo weit von der Szenenwurzel 0,0,0 "gehäutet" werden kann.

Ich muss sagen, dieser Fehler macht Spaß. Hier konnte ich es auf dem Desktop reproduzieren, aber 60 KB reichten nicht aus, um die Präzision zu verringern:
needs more zeroes

ok, also bei z = 1e8 haben wir Folgendes mit dem aktuellen Shader:

screen shot 2018-02-14 at 1 15 56

und hier ist, was wir haben, wenn wir den Shader auf diesen ändern (geringfügige Abweichung von meinem Test, den ich oben herausgeschnitten habe):

#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += ( bindMatrixInverse * boneMatX ) * skinVertex * skinWeight.x;
    skinned += ( bindMatrixInverse * boneMatY ) * skinVertex * skinWeight.y;
    skinned += ( bindMatrixInverse * boneMatZ ) * skinVertex * skinWeight.z;
    skinned += ( bindMatrixInverse * boneMatW ) * skinVertex * skinWeight.w;
    transformed = skinned.xyz;
#endif

screen shot 2018-02-14 at 1 16 54

immer noch wackelig, sieht aber viel besser aus :) Nun, was bedeutet das im Zusammenhang mit dieser Ausgabe?

Erstens können Sie diesen Hack nicht einfach kopieren und in den Shader einfügen. Ich meine, Sie können, aber es ersetzt 1 Matrixmultiplikation durch 4. Was ich stattdessen vorschlage, ist entweder a) die Knochenmatrix mit der Umkehrung der Bindematrix auf js Seite zusammenzuführen und als einzelne Uniform zu übergeben, oder b) nur dafür eine andere Uniform zu erstellen Stück Shader. Es würde dann sowohl dieses Problem (etwas) lösen als auch die Anzahl der Matrixmultiplikationen im Shader (um 1) verringern.

Oh und

Trolle hier tun so, als ob "wir alle unendliche Welten wollen, aber es ist unmöglich"

Ich denke, sie wollten sagen, dass Sie das Problem umgehen können, ohne die Bibliothek auf Ihrer Seite zu reparieren. Nicht notwendig sollte, könnte aber.

@makc Vielen Dank für Ihre Zeit.
Leider ist es ziemlich zu spät. Ich muss Freitag liefern. Ich habe PNG-Sequenzen als Workaround verwendet.

Wenn Sie dies tief genug debuggen möchten. Könnten Sie versuchen, eine realistische Maschengröße zu verwenden?
Auch dieses Lara-Modell ist ungefähr 60 m groß, wenn ich mich gut erinnere.

Ich bin ziemlich gespannt, ob Ihr Patch natürlich auch im realistischen Maßstab funktioniert :)

Oh und ... machst du deinen Test unter iOS?
Wie in diesem Thread erläutert, geschieht dies hauptsächlich auf iOS-Geräten (6, 8).
Auf dem Desktop bringen nur sehr sehr große Werte das Problem.

Danke noch einmal

@OrtOfOn können Sie den @ makc- Patch ausprobieren, indem Sie ihn oben in Ihren Code einfügen:

THREE.ShaderChunk.skinning_vertex = `
#ifdef USE_SKINNING
    vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
    vec4 skinned = vec4( 0.0 );
    skinned += ( bindMatrixInverse * boneMatX ) * skinVertex * skinWeight.x;
    skinned += ( bindMatrixInverse * boneMatY ) * skinVertex * skinWeight.y;
    skinned += ( bindMatrixInverse * boneMatZ ) * skinVertex * skinWeight.z;
    skinned += ( bindMatrixInverse * boneMatW ) * skinVertex * skinWeight.w;
    transformed = skinned.xyz;
#endif
`;

THREE.WebGLShader: Shader konnte nicht kompiliert werden. : /

patch

Oh Mann. Sie haben falsche Anführungszeichen und einzeilige Formatierungen erhalten. Wie kopierst du so?

Außerdem habe ich es irgendwie getan, um diese verrückten Bilder zu sehen, die meine Neugier befriedigen. Ich vertraue darauf, dass jemand anderes es von hier übernimmt :)

@makc STRG + C / STRG + V ... nur von hier ...: /

Leider ist der Bug weniger stark als zuvor, aber immer noch da :(

Getestet auf iOS (Patch angewendet):

Netz im Maßstab 1.0 (Avatar genau ca. 20 m hoch), Position z = 10000
http://cornflex.org/webgl/skin-patch1.mp4

Netz im Maßstab 0,1 (Avatar ca. 2 m hoch), Position z = 3000
http://cornflex.org/webgl/skin-patch2.mp4

@mrdoob Ich werde versuchen zu reproduzieren :) Es erschien in einer einzigen Zeile. Ich habe auf der Seite geschrieben, als ich sah, dass Ihre Antwort platzte und es nicht so aussah, als würde es normal erscheinen. Ich verspreche: p ... Ich werde diese Bonuspunkte bekommen, Sie werden sehen :)

EDIT: Übrigens hast du deinen Beitrag bearbeitet? :) :)

Ich glaube, der verbleibende Effekt hängt möglicherweise nicht mit dem Enthäuten zusammen und wirkt sich tatsächlich auf alles aus, aber Sie bemerken es nicht, weil es keine Animation gibt.

@OrtOfOn an Ihrer Stelle würde ich versuchen, Ihre gesamte Szene (mit einer Kamera) in zusätzliches Object3D zu verpacken und diese Objektkoordinaten auf -1 * Avatar-Koordinaten für jedes Bild zu setzen. Dies würde es für immer in 0,0,0 Weltkoordinaten halten.

@markc Ich

Auch ... nicht mein Fall, aber stellen Sie sich das mit mehreren Feinden in SkinnedMesh vor, die von überall her kommen ...

Ich hatte keine Wahl, weil die Frist abgelaufen war und ich das SkinnedMesh durch Spritesheet-Animationen ersetzt habe (Client ist in Ordnung). Ansonsten habe ich nichts anderes erlebt, als auf so etwas zu stoßen. Ich benutze ThreeJS in fast jedem Webprojekt und bin sehr, sehr zufrieden damit.

Wir wollen keine "unendlichen Welten", aber wir wollen diese netten SkinnedMesh- und Animationsfunktionen in Weltraumkoordinaten verwenden können, wie wir es in berühmten Engines tun :)

Ich bin ein bisschen enttäuscht ... weil ich ein sehr cooles Animator-Skript erstellt habe, das auf Überblendungsfunktionen basiert und von Mecanim inspiriert ist ... Für das nächste Projekt sicherlich: /

@markc Ich

Ich glaube nicht, dass das überhaupt schummelt. So funktionieren alle Weltraumsimulationen. Tatsächlich versetzt das Echtzeit-3D-Rendering im Grunde die gesamte Szene, sodass sich in der Mitte die Kamera befindet.

@mrdoob Ja, ich weiß, dass es nicht einmal eine Kamera gibt. Potenz von Matrizen :) (Ich mache selbst einige native WebGL / OpenGL-Entwickler).

Wie auch immer, das Einfügen der gesamten Szene in ein Spielobjekt scheint mir ein bisschen barbarisch zu sein ... vor allem, um eine enthäutete Animation zum Laufen zu bringen.

@OrtOfOn tatsächlich können Sie die Szene selbst verwenden. Beispiel: In einem Lara-Beispiel:

scene.add(camera);
scene.position.z = -60000;

und es ist in Ordnung (bearbeiten: jedoch stimmt etwas mit dem Licht nicht, wenn Sie dies tun .... @mrdoob ?)

@makc Nochmals vielen Dank, Patches vorzuschlagen.

Ich möchte überhaupt nicht pessimistisch sein, aber irgendetwas sagt mir, dass Beleuchtung nicht das einzige Problem sein wird, wenn ich diese Art von Manipulationen mache. Deshalb nenne ich diese Tricks und Cheats wegen der Unsicherheit des Ergebnisses und der Konsequenzen für andere Teile der Pipeline.

Leider haben Leute, die Spiele machen, Physik, Raycaster, Partikel, ... viele Dinge, die entworfen wurden und entworfen werden müssen, um im Weltraum mit realistischen Maßstäben zu sein.

Außerdem bin ich ziemlich neugierig, diese Patches mit mehr als einem SkinnedMesh in Aktion zu sehen, wie Feinde, die sich an einigen Stellen in der Szene verstecken oder laichen. Denn was bringt es dann, sich auf einen einzigen Skinnedmesh-Avatar bei 0,0,0 zu beschränken?

Ich werde so schnell wie möglich tief in die Quelle eintauchen, aber ich muss in 2 Tagen etwas liefern ... also sind meine Spritesheet-Animationen hoffentlich vorerst ganz in Ordnung.

Denn was bringt es dann, sich auf einen einzigen Skinnedmesh-Avatar bei 0,0,0 zu beschränken?

Der Punkt ist, dass es höchst unwahrscheinlich ist, dass Sie gleichzeitig den Skin bei 0,0,0 und einen anderen Skin bei z = 60000 rendern. Nur wenige Skins um 0,0,0 schaffen es auf den Bildschirm, und sie sind nicht weit genug, um den Fehler auszulösen.

@makc Auch hier ist Ihr Patch unter dem Desktop gültig, aber Sie testen den Fall nicht auf iOS-Geräten, auf denen der Fehler bereits in einigen Metern Entfernung von 0,0,0 mit realistisch skalierten Netzen auftritt. Ich habe genug Videos dazu gemacht. Dieser zeigt zum Beispiel den Fehler nur bei z = 100: /
http://cornflex.org/webgl/skin-bug.mp4

Verwenden Sie in Ihren Spielen immer einen Avatar, der 20 m groß ist? :) :)
Weil die Zahl, auf die Sie sich konzentriert haben (60000), nur verwendet wird, um den Fehler auf dem Desktop aufzudecken (mit dieser sehr großen Lara oder dem riesigen ThreeJS-FBX-Beispiel) ... nicht auf dem Handy. Und mein Avatar geht natürlich nicht so weit ...

Ich würde bestätigen, dass dies ein iOS-Problem ist. Seit mindestens der Generation 6S / 6S + hat iOS ein Problem mit floatVertexTextures. Das Update, das wir verwendet haben, besteht darin, diese Funktion unter iOS zu deaktivieren. Dies schränkt die Knochen ein, die wir verwenden können, aber wir müssen sie trotzdem einschränken, um schlechtere Telefone zu unterstützen.

Da iOS-Geräte den von @ Mugen87 veröffentlichten

@ Daniel-nth Ich denke, es macht Sinn. Allerdings ... @OrtOfOn sagte, z = 60K reproduziert das Problem auf dem Desktop ... Ich habe keine Probleme bei 60K auf dem Desktop, nur 1e8 war ausreichend für mich, um "zu reproduzieren". Vielleicht handelt es sich bei diesem Problem also wirklich um mindestens drei separate Probleme:

  • Float-Texturen auf iOS,
  • etwas bei 60K auf @OrtOfOns Desktop,
  • Die Genauigkeit bei 1e8 geht aufgrund einer schlechten Matrixmultiplikationsreihenfolge im Bones-Shader-Bit (dem, mit dem ich oben herumgespielt habe) zu Ende.
  • Vielleicht noch etwas im Vertex-Shader, da das Mädchen nach dem Patch noch etwas wackelig war.

Hallo Leute,
Zunächst einmal danke ich Ihnen, dass Sie zu diesem Fehler zurückgekehrt sind. Ich habe immer noch keine Zeit gefunden, darin zu graben :(

@ daniel-nth Die Größe des Objekts wirkt sich auf den Fehler aus:

Unter iOS mit diesem sehr großen "Lara" -Objekt (Höhe = 120, Maßstab = 1) tritt der Fehler tatsächlich bei z = 60000 auf. Wenn Sie jedoch ein Netz mit realistischer Größe (Höhe = 1,8, Maßstab = 1) verwenden, wird es bereits nur bei z = 100 angezeigt.

Je größer das enthäutete Netz ist, desto weiter muss die Übersetzung sein, um den Fehler zu erkennen.

Wie bereits in diesem Thread getestet und berichtet, führt das Deaktivieren von floatTextures unter iOS dazu, dass überhaupt kein Skinning erfolgt.

Ich vermute auch eine schlechte Matrixmultiplikation oder Balkenreihenfolge der Multiplikation der Knochenmatrix.

Unter iOS mit diesem sehr großen "Lara" -Objekt (Höhe = 120, Maßstab = 1) tritt der Fehler bei z = 60000 auf

@OrtOfOn warten, also auf ios? aber du hast auch gesagt:

Die Zahl, auf die Sie sich konzentriert haben (60000), wird nur verwendet, um den Fehler auf dem Desktop aufzudecken (mit dieser sehr großen Lara oder dem riesigen ThreeJS-FBX-Beispiel) ... nicht auf Mobilgeräten.

Unter iOS mit diesem sehr großen "Lara" -Objekt (Höhe = 120, Maßstab = 1) tritt der Fehler tatsächlich bei z = 60000 auf.

Es ist überhaupt nicht riesig.
Und Sie verstehen immer noch nicht die Beziehung zwischen Modellgröße und Weltmaßstab.
Zum letzten Mal:
http://necromanthus.com/Test/html5/Lara_1000000.html
Modeil Höhe ca. = 75 und Weltskala = 9.999.999.
Von Z = 0 bis Z = 1.000.000 (eine Million !!!)
Da die Gleitkommazahl mit einfacher Genauigkeit 7 beträgt, sind überhaupt keine Dezimalstellen mehr vorhanden !!!
Es läuft perfekt auf allen Laptops und Desktops, die ich habe.
Sogar mehr:
Es läuft perfekt auf Android 6 & 7 und verschiedenen Samsung-Handys.

lara_1000000

@RemusMar Geben Sie in Ihrem Beispiel

camera.position.z += 1e8;
scene.children[2].position.z += 1e8;

Sie werden so etwas sehen:
screen shot 2018-03-03 at 15 48 53

screen shot 2018-03-03 at 15 51 41
es ist trippy

Ich gebe dir, dass z = 1e6 auch nicht schlecht aussieht. um 1e7 fällt es schon auf und 1e8 ist einfach verrückt

@OrtOfOn Das Setzen von

Ich gebe dir, dass z = 1e6 auch nicht schlecht aussieht. um 1e7 fällt es schon auf und 1e8 ist einfach verrückt

Ich weiß, aber für diese Werte sind Sie nicht präzise.
Für die präzise Gewichtsgenauigkeit des enthäuteten Netzscheitelpunkts beträgt die maximale Weltgröße 9.999.999
Das bedeutet maximale Entfernungen von ein paar Millionen, nicht mehr.
Prost

@makc In der Tat habe ich die falschen Nummern für den Desktop. Es muss sehr groß sein, du hast Recht und ich habe es im Thread bereits erwähnt: / https://github.com/mrdoob/three.js/issues/13288#issuecomment -364650679

@ daniel-nth Gut zu wissen, aber bist du sicher? Hier ist der Test, den ich hier in diesem Thread mit einem 3D-Modell aus drei Quellen durchgeführt habe. Sie können sich den Code noch ansehen. @ Mugen87 machte das gleiche Feedback auch, keine Animation mit diesem Modell. https://github.com/mrdoob/three.js/issues/13288#issuecomment -364572653

Oh, ich sehe, das Modell ist nicht mehr vorhanden. 404 unter https://threejs.org/examples/models/fbx/xsi_man_skinning.fbx

@ daniel-nth Wenn du ein neues Modell mit weniger Knochen verwendest, dann glaube ich dir;)

@RemusMar Ganz einverstanden mit Ihnen über Entfernungen, die in den letzten Beiträgen erwähnt wurden. Die Zahlen (1e6, 1e8, 1e9, ...) werden sicherlich mit schlechter Genauigkeit resultieren. Daran gibt es keinen Zweifel. Aber bitte hör auf mich zu trollen. Hör auf so zu tun, als würde ich nichts verstehen und frag dich, ob ein Avatar-Netz mit einer Höhe von 120 nicht riesig ist. Für mich ist es sehr groß und in einem Gamedev mit anderen realistisch skalierten Objekten, die von Künstlern, Raycasts, Physik, Beleuchtung ... erstellt wurden, nicht sehr brauchbar und wird in 3 Wochen geliefert.

Ich bestehe darauf: Es ist unerlässlich, Assets mit metrischen Einheiten auf einem realistischen Maßstab zu halten, um ein physikbasiertes Spiel korrekt zu erstellen :)

Schade, dass ich unter iOS meinen Avatar unter diesen realistischen Skalierungsbedingungen nicht über 100 m laufen lassen kann: /

UPDATE: Wie auch immer, @ daniel-nth scheint uns zu sagen, dass es jetzt mit ausgeschalteten floatTextures und einer sehr begrenzten Anzahl von Knochen funktioniert.

Aber bitte hör auf mich zu trollen
Ich bestehe darauf: Es ist unerlässlich, Assets mit metrischen Einheiten auf einem realistischen Maßstab zu halten, um ein physikbasiertes Spiel korrekt zu erstellen :)

Ich trolle dich nicht.
1,5 Einheiten bedeuten jedoch nicht 1,5 Meter
Prost

@OrtOfOn

Ich bestehe darauf: Es ist unerlässlich, Assets mit metrischen Einheiten auf einem realistischen Maßstab zu halten, um ein physikbasiertes Spiel korrekt zu erstellen :)

aber diese Skala ist ein willkürlicher selbst auferlegter Wert. Sie könnten sich genauso gut für die Verwendung von Zentimetern entscheiden, und dann ist "ein Avatar-Netz mit einer Höhe von 120" tatsächlich kleiner als der Durchschnitt.

@makc Sicher, aber die Physik-Engine / libs erwarten, dass Sie metrische Werte verwenden. Haben Sie bereits versucht, Physik an skalierten Objekten oder mit nicht metrischen Werten durchzuführen? Es wird schnell schrecklich, sich zu entwickeln, und Sie erhalten unerwartete und unrealistische Ergebnisse. Alle Ihre Streitkräfte müssen ebenfalls überprüft und skaliert werden. Es wird funktionieren, aber nicht genau.

Natürlich hängt es von der Genauigkeit ab, die Sie erreichen müssen, und Werte wie 1e6, 1e7, ... sind viel zu groß und führen zu Präzisionsproblemen. Und Sie müssen niemals ein Hautnetz so weit bewegen. Da waren wir uns einig. Unter iOS sollten wir jedoch in der Lage sein, ein GPU-Skin-Netz (1,5 Einheiten hoch) in einem Bereich von mindestens mehreren hundert Einheiten zu bewegen.

Die Physik-Engine / libs erwarten jedoch, dass Sie metrische Werte verwenden.

Das ist nicht wahr.
Meter, Zentimeter, Zoll usw. sind irrelevant.
Wie ich bereits (mehrmals) sagte, ist alles, was zählt, die Weltgröße (Skala) und die Genauigkeit.
Beachten Sie Folgendes:
Wenn Sie ein enthäutetes Netz mit einer Höhe von 1,5 Einheiten haben, werden Sie von der Scheitelpunktgewichtskarte gezwungen, mindestens 2-3 Dezimalstellen zu verwenden.
Für die Physik-Engine (falls vorhanden) benötigen Sie möglicherweise 3-4 Dezimalstellen, um akzeptable Ergebnisse zu erzielen.
Wenn die globale Genauigkeit 4 Dezimalstellen erfordert, beträgt Ihre maximale Weltgröße 999 (da die Gleitkommazahl mit einfacher Genauigkeit 7 beträgt).
Mit anderen Worten, Sie können Entfernungen von einigen Hundert verwenden, wenn Sie anständige Animationen und anständige Physik wünschen.
Ich hoffe du hast diesmal das ganze Bild.
Prost

@ RemusMar Ich werde hier aufhören. Anscheinend wollten oder wollten Sie Ihren Fall nicht auf einem iOS-Gerät testen. Sie können auf diesen Geräten mit GPU-Skin-Maschen keine "Entfernung von einigen Hundert" verwenden. Das Netz wird sehr schnell verrückt. Das ist der Punkt dieses Threads und ich wollte das nur zu Beginn melden. So, das wars.

Ich hoffe, Sie haben die Tatsache erhalten, dass alle Ihre Vorschläge und Beispiele auf iOS-Geräten nicht funktionieren, wie von anderen Personen hier und von meinen Screenshots berichtet: /

Sie können auf diesen Geräten mit GPU-Skin-Maschen keine "Entfernung von einigen Hundert" verwenden.

Du liegst wieder falsch.
Siehe den obigen Screenshot (Android 7 - Samsung-Handy).
Modellhöhe = 75 (Grenzkugelradius ca. 38) und Abstand 1.000.000 (eine Million !!!)
Oder Modellhöhe = 1,5 und Entfernung 20.000.

ps
Ist nicht mein Problem, dass iOS immer eine Sammlung von Fehlern war.

@ RemusMar Ich

Nicht mein Problem, wenn Sie Apple so sehr hassen. Wenn einer meiner Kunden ein 3D-Web-basiertes Spiel mit ThreeJS möchte, sage ich ihm nicht "Fick dich mit deinen iPhones" ... Wenn du es tust, tut es mir leid für dich.

Ende der Übertragung hier ... Ich kann dem nicht mehr folgen.

@OrtOfOn Ja, das Modell, das ich verwendet habe, hat 19 Knochen, der 404 fbx hat 67.

https://github.com/mrdoob/three.js/issues/13288#issuecomment -364550036 hatte einen Link zu einer Seite, die die einheitliche Knochengrenze anzeigt. Die Formel, die auf dieser Seite verwendet wird, lautet Math.floor((data.webgl.params.MAX_VERTEX_UNIFORM_VECTORS - 20) / 4); nicht sicher, ob dies für three.js 100% genau ist, aber sie meldet 27 sogar auf dem iPhone X, was leider weniger als die Hälfte eines Galaxy S3 ist, aber immer noch ausreichend für ein mobiles WebGL-Spiel. Ich habe meinen Arbeitsordner schnell durchgesehen und in den 26 WebGL-Projekten hat nur eines ein Modell mit mehr Knochen, und dieses Modell bleibt bei 0,0,0.

@OrtOfOn : Ich habe ähnliche Probleme mit einer festen Szene und bewege einen enthäuteten Charakter in der Szene. der charakter zittert furchtbar auf ios. Die Knochenzahl beträgt 22. Die Abmessungen der Szene sind angemessen. Ich glaube, das Problem ist, dass die Verwendung von Vertex-Texturen Sie auf 32-Bit-Floats beschränkt, zusammen mit der obigen Behauptung, dass Threejs das Skinning im Weltraum berechnet!

Ich beschäftige mich jetzt mit der Behauptung des Weltraums und werde hoffentlich den richtigen Weg implementieren, um Vert-Positionen im lokalen Raum zu berechnen und dann das Objekt zu übersetzen - wie es sein sollte. Ich habe noch nie von jemandem gehört, der Skinning verwendet, um das Objekt im Weltraum zu platzieren, daher bin ich mir nicht sicher, warum der Implementierer so etwas getan hätte.

Ich werde zurück posten, wenn ich eine Lösung habe.

Nur zu Ihrer Information, Float-Texturen auf iOS werden nicht nur mit Vertex-Shadern gebrochen. Ich habe kürzlich Float-Texturen in ganzzahlige Texturen geändert, um Farbstreifen auf ios zu korrigieren, daher ist dies ein universelles ios-Problem. Sie könnten wahrscheinlich auch ganzzahlige Texturen verwenden, um die Knochen auf ios zu reparieren, wenn Sie es wirklich wollten - hier ist ein relevanter Ausschnitt aus dem Shader eines anderen:

vec2 encodeFloatRG( float v )
{
    vec2 kEncodeMul = vec2(1.0, 255.0);
    float kEncodeBit = 1.0/255.0;
    vec2 enc = kEncodeMul * v;
    enc = fract (enc);
    enc.x -= enc.y * kEncodeBit;
    return enc;
}

float decodeRGFloat( vec2 enc )
{
    vec2 kDecodeDot = vec2(1.0, 1.0/255.0);
    return dot( enc, kDecodeDot );
}

... in der Tat könnten Sie wahrscheinlich (ich nehme an, ich habe so etwas nicht wirklich versucht) auch Float-Bone-Texturen zum Laufen bringen, wenn Sie ios-Genauigkeit als globale Genauigkeitsgrenze akzeptieren und zwei Floats anstelle von einem in der Textur speichern

Ich habe das Problem vollständig gelöst, indem drei Personen die Skinning-Berechnung im lokalen Raum durchführen lassen - wo es hingehört - und das Modell auf die Standardmethode über die Weltraummatrix in reale Weltkoordinaten übersetzt.

Die oben genannten Probleme sind beim Skinnen unter iOS vollständig behoben. Ich sollte auch darauf hinweisen, dass diese Lösung universell ist - funktioniert einwandfrei auf allen Desktop-Browsern sowie auf den von mir getesteten Android-Geräten. IMHO Local Space Skinning ist in fast allen Fällen der richtige Weg, und diese Methode sollte die Standardeinstellung für ThreeJS sein. @mrdoob : Wie sehen Sie das?

mesh = new THREE.SkinnedMesh(geo.geometry, mat);
mesh.bindMode = 'detached';
var skel = new THREE.Skeleton(bones, boneInvs);
var bsm = new THREE.Matrix4().fromArray(geoPrims.bsm);
mesh.bind(skel, bsm);

// make bsmInv identity for models that have multiple skins
mesh.bindMatrixInverse = new THREE.Matrix4();

// patch SkinnedMesh's updateMtxWorld:
// we're using local skinning, so don't keep resetting binMatrixInverse (leave identity)
// the reason we're using .bind here is for models that have more than one skin
mesh.updateMatrixWorld = PatchSkinnedMeshUpdateMW.bind(mesh);

// re-normalize since input data has been compressed
mesh.normalizeSkinWeights();

// remove bone roots and add to bone root list
for (var bi = 0, bl = bones.length ; bi < bl ; bi++) {
    if (bones[bi].parent && !bones[bi].parent.isBone) {
        bones[bi].parent.remove(bones[bi]);
        boneRoots.push(bones[bi]);
    }
}

Wobei 'BoneRoots' zum Stammszenenobjekt hinzugefügt werden sollte (damit sie Matrixaktualisierungen erhalten, aber nicht alle Matrizen in der Hierarchie erben, die zum eigentlichen Skinnedmesh führen). Fügen Sie diese BoneRoots zu Ihrem Szenenstamm hinzu (Code nicht gezeigt).

Und hier ist der Patch, der die SkinnedMesh-Implementierung von threeJS ersetzen soll (beachten Sie, dass dies nur erforderlich ist, da die updatematrixworld von threejs die bindMatrixInverse blockiert, die wir als Identität behalten möchten). Alternativ können Sie direkt an THREE.Mesh..prototype.UpdateMatrixWorld binden, anstatt eine Patch-Funktion zu verwenden.

function PatchSkinnedMeshUpdateMW( force ) {
    THREE.Mesh.prototype.updateMatrixWorld.call( this, force );
}

@ denbo-ft Ich denke, das klingt gut für mich. Möchten Sie eine PR dafür erstellen?

@ denbo-ft Vielen Dank für Ihre Bemühungen. Entschuldigung für die späte Antwort, ich bin diesem Thread nicht mehr gefolgt.

Wir haben dieses Problem auch in unserem Produkt - in jedem Browser (wenn Sie weit genug von 0,0,0 entfernt sind), der sich jedoch unter iOS besser bemerkbar macht, sobald Sie ungefähr 2-3 Einheiten entfernt sind. Kritisch für uns, aber zumindest haben wir ein gutes Lachen, wenn wir das sehen
image

Ok, es sieht so aus, als gäbe es mehr Leute, die das brauchen. Ich habe noch nie zu einem Github Open Source Projekt beigetragen, aber ich bin mit Git vertraut und werde versuchen, eine PR zu erstellen. :) :)

Hier gilt das gleiche. Mein SkinnedMesh sieht aus wie eine Episode von Dr. Katz, professioneller Therapeut auf iPhones.

Zu Ihrer Information, mein Beitrag vom 21. Mai hat die gesamte Lösung. Nicht viele Korrekturen für die ThreeJS-Quellen - der größte Teil der Korrekturen befindet sich in Ihrem Loader- und / oder Szenen-Setup-Code für Ihre einzelnen Projekte.

Die grundlegende Lösung besteht darin, den Modus "getrennt" (übrigens nicht dokumentiert) zu verwenden und die Knochenhierarchie in Ihrer Szene auf der Ebene der Stammszene zu platzieren - nicht an der Stelle der tatsächlichen renderbaren Zeichenhierarchie. Dann flicken Sie eine einfache Sache aus der Engine (SkinnedMesh.update), und Sie sollten bereit sein, loszulegen.

Bearbeiten:
Wir haben ein vollständig benutzerdefiniertes Dateiformat und einen Loader für TJS. Um eine vollständige PR mit einer Beispiellösung zu erstellen, müsste ich leider einen der mitgelieferten Dosenlader (wie Collada) reparieren. Ich werde mich jetzt darum kümmern

danke, ich wollte etwas Zeit einplanen, um zu versuchen, Ihre Lösung allgemeiner zu verstehen und anzuwenden (Ihre schien ein bisschen spezifisch für Ihr Projekt zu sein). Könnten Sie etwas mehr Kontext für Ihren Code teilen?

Dr. Katz, professioneller Therapeut

Ich bin nicht süchtig oder so, aber verdammt .

BEARBEITEN:

Ich habe erfolgreich eine Pull-Anfrage erstellt. Lassen Sie mich wissen, ob ich noch etwas tun kann.

Ursprünglicher Beitrag:

Ich habe eine lokale Niederlassung mit den Änderungen, aber ich kann nicht auf den Ursprung drängen. Selbst wenn ich meine Github-Creds zur Verfügung stelle, erhalte ich den folgenden Fehler:

Pushing zu https://github.com/mrdoob/three.js.git
remote: Berechtigung für mrdoob / three.js.git für denbo-ft verweigert.
Schwerwiegend: Zugriff auf ' https://github.com/mrdoob/three.js.git/ ' nicht möglich: Die angeforderte URL hat den folgenden Fehler zurückgegeben: 403

Würde mich über Ratschläge freuen, da dies mein erster Beitrag zu Github ist. Vielen Dank!

Zu Ihrer Information: Wenn der PR für mrdoob funktioniert und integriert ist, gibt es einen neuen Bindungsmodus "local", der diese Änderung unterstützt. Ich wollte den undokumentierten "getrennten" Bindemodus nicht patchen oder ändern, da es keinen Hinweis darauf gibt, wer oder was ihn verwendet, und ich wollte nichts brechen, von dem ich nichts wusste. Aber es scheint mir, dass es für diesen Zweck bestimmt gewesen sein könnte.

Alles, was binMode = "local" tut, ist, die bindMatrixInverse während der Aktualisierung nicht zu ändern, im Gegensatz zu "losgelöst", die sie auf die Umkehrung von bindMatrix zurücksetzt, anstatt die Identität beizubehalten.

Sehen Sie sich das Beispiel webgl_loader_collada_skinning.html in dieser PR an, um die wenigen Änderungen zu sehen, die auf Szenenebene erforderlich sind, um eine ordnungsgemäße lokale Skinning-Funktion für Zeichen zu erhalten, die sich in der Szene bewegen.

Die Stormtrooper DAE Loader-Demo wurde verwendet, um dieses Update zu testen. Der Charakter wurde für diese Tests um 2000 Einheiten vom Ursprung entfernt. Screenshots unten.

Die folgenden Aufnahmen stammen vom iPhone X / Safari 11

Vor dieser Änderung (bei 2000, 2000, 2000):
img_0658

Nach dieser Änderung:
img_0659

Glaubst du, es gibt einen Weg, dies zu erreichen, ohne die Knochen in der Wurzelszenenebene und (0,0,0) zu haben? Ich benutze die Knochen, um Dinge an den Avatar anzuhängen, ihn auf Punkte zu richten usw. usw. Und ich denke, ich bin nicht der einzige

Sie haben zwei Möglichkeiten:

1) Halten Sie die Knochen im Weltraum an der Wurzel, um von der lokalen Hautbildung zu profitieren, wie sie in drei Js implementiert ist. Führen Sie dann zusätzliche Transformationen durch, wenn Sie unbedingt eine Waffe an einem Knochen befestigen müssen, um sie beispielsweise in den Avatar-Bereich zu bringen.

2) Lass Bones im Avatar-Raum wie er ist und verziehe dich auf ios.

Ich würde definitiv # 1 machen. Sie können jederzeit rechnen, um herauszufinden, wo sich das anhängbare Objekt an einem bestimmten Frame befinden sollte, wenn Sie bereits die Knochenposition und die Position des Charakters haben. Es gibt jedoch keine Problemumgehung für Nummer 2, da das Warping durch das Packen auf HAL-Ebene der iOS-Geräte verursacht wird und Sie nichts dagegen tun können. Natürlich können Sie zusätzliche Hacks hinzufügen, indem Sie versuchen, die verschiedenen oben genannten HalfWord-Verpackungen usw. zu verwenden, aber alle reduzieren das Problem und lassen es nicht verschwinden. Das Skinning-Problem auf ios verschwindet vollständig, wenn Sie das Skinning im lokalen Raum durchführen (genauer gesagt, halten Sie die Knochen um den Ursprung der Welt zentriert, um die Zahlen so klein wie möglich zu halten). Dann xform in Zeichenraum für Anhänge.

Mehr Info:

Das Problem bei der Implementierung in TJS ist nicht TJS-spezifisch. Um das Problem der Knochenbegrenzung aufgrund der begrenzten Anzahl von Uniformen pro Shader-Programm zu lösen, werden BoneTextures verwendet. Dies ist eine ziemlich normale Lösung. Unter iOS werden Floats in Texturen jedoch in etwas kleiner als 32-Bit quantisiert - gepackt / komprimiert. Dies verursacht die "Gottesanbeterin" oder andere verrückte Effekte von Charakteren, wenn die Größe / Größe der Zahl "groß" ist, dh über einige hundert.

Ok toll, was machen wir jetzt? Nun, jedes große Feature Ihres Spiels (eigentlich die Game Engine) erfordert normalerweise einen Standard of Practice. Beispiel: Sagen Sie den Künstlern, dass sie den Charakter um den Ursprung zentrieren sollen. Platzieren Sie den Wurzelknoten des Charakters auf den Füßen / Boden, erstellen Sie die Knochen und die Haut auf eine bestimmte Weise. Schreiben Sie dann einen Exporteur (oder Importeur im Fall von TJS) und einen Importeur, die Ihre Prozessregeln kennen. Unterstützen Sie dann die letzte Funktion in der Engine, wenn Sie die Assets mit dieser Konfiguration laden. So machen wir es in der Spielebranche.

Es ist unüberschaubar und unbestimmt (beides schreckliche Dinge für die Spieleentwicklung), zu erwarten, dass JEDE Authoring-Methode, JEDES Dateiformat und JEDER generische Loader alle Funktionen Ihres Spiels perfekt handhaben. Es müssen einige Standards und Prozesse auf dem Weg sein.

Wenn Ihr Charakter Skinning verwendet und auch Geo für Waffen oder was auch immer anbringen muss, überlegen Sie, was erforderlich ist, damit der Motor überhaupt häutet, und arbeiten Sie damit. Ich habe eine solche Lösung als Beispiel angeboten. Leider wurde die PR nicht akzeptiert, weil sie aus irgendeinem Grund die Lader nicht wechseln wollen. Trotzdem hoffe ich, dass ich das Problem und die Lösung im obigen Thread sowie die von mir eingereichte PR erklärt habe.

Ich kann nicht viel mehr dazu beitragen, als ich bereits habe. Ich hoffe ich habe einigen Leuten geholfen ...

Viel Glück!

Das Skinning-Problem auf ios verschwindet vollständig, wenn Sie das Skinning im lokalen Bereich durchführen

Wie ich von Anfang an sagte, ist dies eine Problemumgehung für eine iOS-Einschränkung (Fehler), und Sie müssen dafür Rechenleistung verschwenden.
Das ist keine Lösung!
Die eigentliche Lösung besteht darin, die Gleitkomma-Genauigkeit unter iOS auf den Normalwert von 7 Ziffern zu erhöhen.
http://davenewson.com/posts/2013/unity-coordinates-and-scales.html

@ denbo-ft Ich habe Ihre PR tatsächlich implementiert (wir haben unseren eigenen Loader). Vielen Dank für Ihren Beitrag. Es wurde geschätzt. Ich hatte auf einen anderen Ansatz gehofft, da wir mehrere Avatare in unseren Szenen haben, sie sich bewegen, Gegenstände greifen, miteinander interagieren usw. und das Skelett in 0,0,0 uns zwingen würde, eine Menge Dinge in unseren zu ändern Code, riskieren neue Probleme usw.

Ich habe viel Zeit damit verbracht, über das Problem nachzudenken, aber keine bessere Lösung gefunden. (Versuche immer noch)

@ RemusMar

Die eigentliche Lösung besteht darin, die Gleitkomma-Genauigkeit unter iOS zu erhöhen

Vielleicht sollte jemand zuerst @grorg und Co fragen, was mit schwebenden Texturen dort los ist und wie kommt es, dass das so ist? weil ich das Gefühl habe, dass es nicht nur ein Fehler ist, sondern die "Lösung" von Apple für ein anderes Problem

Ich habe das Gefühl, dass es nicht nur ein Fehler ist, sondern die "Lösung" von Apple für ein anderes Problem

Möglicherweise wahr.
Ähnlich wie beim Problem mit Firefox Android: Fehler gemeldet, von Entwicklern überprüft, aber in den letzten 5 Monaten nicht behoben (2 Releases)!?!

So funktioniert die Softwareentwicklung heutzutage:
Anstelle von Korrekturen am richtigen Ort gibt es Problemumgehungen bei Drittanbietern.
Endergebnis: Sammlungen von Fehlern, verschwendeten Ressourcen und Bloatware !!!

@jfcampos
Ich würde empfehlen, die Knochenhierarchie in der Wurzel zu belassen und einfach eine Funktion hinzuzufügen, um die endgültige WS-Position eines Knochens zu ermitteln, indem Sie sie mit der martixWorld der tatsächlichen Positionsmatrix des Avatars multiplizieren. Es ist super einfach und gibt Ihnen zurück, was Sie vor dem Fix hatten.

Wenn Sie die Chops haben, können Sie alternativ zur ursprünglichen Methode (mit dem Fehler) zurückkehren, die lokalen Matrizen in die Knochentextur aufnehmen, die Texturverwendung verdoppeln und dann die Shader-Fragmente ändern, um die zusätzliche Berechnung auf der GPU während des Skinnens durchzuführen . Beachten Sie, dass diese Lösung, obwohl sie aus Code-Sicht "sauberer" ist, die Menge an Textur, die in jedem Frame auf die GPU hochgeladen wird, verdoppelt (möglicherweise vervierfacht) und daher viel weniger effizient ist als der obige Vorschlag. Aber aus welchen Gründen auch immer, die mir nicht bekannt sind, kann es für Sie vorteilhafter sein, dies auf die letztere Weise zu tun.

Nach dem, was bisher keine Lösung war, gibt es jetzt mehrere Optionen, um mit ALLEN Geräten kompatibel zu sein, was für die meisten Projekte eine offensichtliche Voraussetzung ist.

Scheint, als müsste ich mit Knochen bei 0,0,0 gehen und ein paar zusätzliche Matrixberechnungen für die anderen Sachen machen. Vielen Dank!

@ denbo-ft ist korrekt. Dies ist ein Problem, das durch das Enthäuten im Weltraum verursacht wird.

Als Referenz wurde hier die Umstellung auf World-Space-Skinning vorgenommen: https://github.com/mrdoob/three.js/pull/4812.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen