Three.js: CubeTextur-Ausrichtung

Erstellt am 25. Apr. 2019  ·  31Kommentare  ·  Quelle: mrdoob/three.js

In meiner App möchte ich die CubeTexture, die den Szenenhintergrund und die Umgebungskartenreflexionen definiert, um 180° entlang der vertikalen y-Achse drehen.
Meine Rotation wird durch die VRML- und X3D-Spezifikationen zu den Hintergrundfeldern definiert.

Ich habe versucht, verschiedene Parameter wie die Felder mapping , flipY und rotation Textur zu ändern. Ich habe jedoch keine gute Möglichkeit gefunden, dies zu tun.

  • Gibt es eine offensichtliche Möglichkeit, dies zu tun, die ich verpasst habe?
  • Gibt es eine Chance, dies in three.js ?
  • Wenn ich es implementieren möchte, welche Parameter möchten Sie sehen (zum Beispiel Texture.flipX und CubeTexture.flipZ )? Hätten Sie Interesse an dieser Funktion?
Enhancement

Hilfreichster Kommentar

Sie meinen, scene.background drehen zu können? Wenn ja... ja, auf jeden Fall interessiert.

Wir brauchen aber wahrscheinlich eine neue API...

scene.background = new THREE.Background( cubeTexture );`
scene.background.rotation.y = Math.PI / 2;

Alle 31 Kommentare

Sie meinen, scene.background drehen zu können? Wenn ja... ja, auf jeden Fall interessiert.

Wir brauchen aber wahrscheinlich eine neue API...

scene.background = new THREE.Background( cubeTexture );`
scene.background.rotation.y = Math.PI / 2;

Genau damit kämpfe ich gerade. Der Versuch, gebackene Bodenschatten zu erhalten, die der Sonnenrichtung von einer Cubemap entsprechen.
Es scheint, als ob meine Cubemap irgendwo auf dem Weg um 180 Grad gedreht wird. Es wäre großartig, wenn ich das hier einfach beheben könnte, anstatt meine Cubemap mehrmals neu zu rendern und herauszufinden, wo das passiert.

@fabienrohrer Versuch

scene.rotation.y = Math.PI;

Wenn dies nicht funktioniert, geben Sie bitte ein Live-Beispiel an, um genau zu demonstrieren, was Sie tun.

Ach, das funktioniert? 😮 Die Kamera muss aber ein Kind der Szene sein?

Die Kamera muss aber ein Kind der Szene sein?

Ich glaube nicht, dass das wichtig ist.

@mrdoob genau das brauche ich auch :-)

@WestLangley :

Das Drehen der Gesamtszene ist übertrieben und kann viele Nebenwirkungen in meiner App verursachen.

Ich möchte nur den Hintergrund drehen können, und die Umgebungskarten sollten auf die gleiche Weise funktionieren.

Eine Live-Demo ist nicht möglich, da die API fehlt. Es ist wichtig, jedes Beispiel mit einer Hintergrund-Cubemap (wie https://threejs.org/examples/#webgl_materials_cubemap) zu nehmen und nur den Hintergrund um die y-Achse drehen zu können. Oder allgemeiner, um eine beliebige Drehung auf den Hintergrund anzuwenden.

Die Möglichkeit, eine benutzerdefinierte Rotationsmatrix / Quaternion auf jede Cubemap anwenden zu können, scheint für mich die generischste Lösung zu sein.

Three.js achtet sorgfältig darauf, dass die Materialreflexionen mit dem Material envMap übereinstimmen, das im Weltraumkoordinatensystem definiert ist. Wenn Benutzer den Szenenhintergrund drehen könnten, würde dies zu einem Hintergrund führen, der nicht mit Materialreflexionen übereinstimmt.

Warum erstellen Sie nicht die richtige Weltraum-Würfelkarte in Ihrer App?

Die Kamera muss aber ein Kind der Szene sein?

Ich glaube nicht, dass das wichtig ist.

Ich habe versucht, scene.rotation.y ++ in der Konsole in webgl_materials_standard auszuführen und die Waffe dreht sich. Dann habe ich versucht, scene.add( camera ) und wenn ich dann scene.rotation.y ++ mache, tut es, was wir wollen, aber dann vermasselt die Kamerasteuerung 😁

Wenn wir ein THREE.Background Objekt einführen, könnten wir eine API hinzufügen, um dies zu handhaben, und im Renderer können wir auch die Idee einführen:

var envMap = material.envMap;
if ( scene.background && scene.background.isBackground && envMap === null ) {
    envMap = scene.background.texture;
}

Ich sagte

Versuchen Sie scene.rotation.y = Math.PI; Wenn das nicht funktioniert,...

Das bedeutet, dass es möglicherweise nicht funktioniert. :-)

Es hängt vom Anwendungsfall ab. Ich habe es mit OrbitControls versucht und es hat gut geklappt.

nicht verwandt: Das webgl_materials_standard Beispiel sollte sowieso Orbit-Steuerungen verwenden.

Du meinst, dass man scene.background drehen kann? Wenn ja... ja, auf jeden Fall interessiert.

Es ist sinnvoller, dies auf Texturebene zu tun, da sonst jede IBL-Beleuchtung nicht zum Hintergrund passt, nehme ich an.

Wir erlauben die Rotation von normalen Texturen, gibt es einen Grund, warum wir das nicht auch für Würfeltexturen tun möchten? Ist die Umsetzung zu komplex?

Warum erstellen Sie nicht die richtige Weltraum-Würfelkarte in Ihrer App?

Dies ist sehr zeitaufwendig. Ich habe in den letzten Tagen daran gearbeitet, Cube-Maps zu generieren, und das Vornehmen von Änderungen und das erneute Rendern der Cube-Map dauern für jede Änderung ungefähr 15-20 Minuten.

Ein weiterer potenziell interessanter Anwendungsfall hierfür ist, dass Sie die Richtung der Umgebungsbeleuchtung in Echtzeit ändern können. Ich kombiniere derzeit eine PMREM-Umgebungskarte mit einem gerichteten Licht für Echtzeitschatten und verwende die Karte als Skybox, was einen ziemlich anständigen Tageslichteffekt ergibt.
Natürlich gibt es eine Grenze für das, was Sie tun können, ohne die Farbe der Umgebungskarte zu ändern, aber Sie könnten mindestens ein paar Stunden Tageslicht simulieren, indem Sie die Karte synchron mit dem gerichteten Licht drehen, während Sie die .envMapIntensity anpassen .

Mein Anliegen ist auch die Leistung. Derzeit habe ich einen Hack implementiert, um die obere und untere Textur zu drehen und die anderen zu tauschen. Es dauert etwa 10 ms, um eine 1024 x 1024-Textur in JS zu drehen.

Alternativ könnte es möglich sein, nur zwei Optionen für die CubeTexture-Ausrichtung zu haben, diejenige, die Sie derzeit haben, und eine andere (mit der 180-Grad-Drehung), die mit dem anderen Standard, der hauptsächlich in 3D-Formaten (X3D, VRML usw.) verwendet wird, kompatibel wäre .). Wir könnten die Konsistenz mit Materialreflexionen wahrscheinlich leicht anpassen, um beide Formate zu handhaben?

Das kommt mir bekannt vor #11103

Wenn ich CubeMap.rotation = matrix3 implementieren würde, würden Sie r105 zusammenführen?

Mein Anliegen ist auch die Leistung. Derzeit habe ich einen Hack implementiert, um die obere und untere Textur zu drehen und die anderen zu tauschen. Es dauert etwa 10 ms, um eine 1024 x 1024-Textur in JS zu drehen.

Und wie oft machst du das in deiner App?

@WestLangley Ich gebe dir hier einfach eine ausführliche Antwort: https://github.com/mrdoob/three.js/pull/16507#discussion_r286337864

Und wie oft machst du das in deiner App?

Wenig. Einmal beim Laden pro Mandant und einmal bei jedem Hintergrundwechsel (sehr selten). Ein DEFINE würde auch die Arbeit erledigen.

Mir geht es auch um die Performance... Es dauert ca. 10ms.

Und wie oft machst du das in deiner App?

Wenig. Einmal beim Laden pro Mandant und einmal bei jedem Hintergrundwechsel (sehr selten).

Entschuldigung, ich folge der Logik nicht.

Leider möchte @WestLangley meine Modifikation über die CubeTexture.rotation wegen des Laufzeit-Overheads (eine zusätzliche mat3-Multiplikation) nicht zusammenführen. In diesem Fall gehen mir die Ideen aus, das sauber in Threejs zu lösen.
Wenn Threejs-Mitwirkende das Problem nicht lösen, schließen Sie dieses Problem.

Ich warte auf die Implementierung dieser Funktion.

@FishOrBear Leider haben sich die threejs Betreuer entschieden, dies nicht zu implementieren. Sie können diesen nicht zusammengeführten Patch in einem Fork anwenden, wenn Sie dies in Ihrem Projekt haben möchten:

https://github.com/mrdoob/three.js/pull/16507

@mrdoob Vielleicht können wir diese Funktionsanfragen in #18157 überdenken?

Ich verwende Threejs, um eine AutoCAD-ähnliche Anwendung zu erstellen, also verwenden wir xy, um als Flugzeug zu sitzen.

Die aktuelle CubeTexture widerspricht unserer etwas.

Übrigens: Mit Babylon.js ist es zumindest möglich, eine Skybox um die y-Achse zu drehen:

https://www.babylonjs-playground.com/#UU7RQ #447

Die Engine unterstützt dies, indem sie den Reflexionsvektor im Fragment-Shader transformiert. Also genau der Ansatz, der in #16507 nicht akzeptiert wurde. Code aus dem Babylon.js-Fragment-Shader:

https://github.com/BabylonJS/Babylon.js/blob/1c4627141f83c08fe4a7e30e2621c916b4e6c9c9/src/Shaders/ShadersInclude/reflectionFunction.fx#L114 -L117

@mrdoob Ich denke, wir sollten diese Funktion implementieren. Im Forum gibt es noch eine Anfrage:

https://discourse.threejs.org/t/rotate-a-scenes-background-skybox-texture/12199

Ich bezweifle, dass eine einzelne zusätzliche Matrix- / Vektormultiplikation pro Fragment die Leistung merklich beeinträchtigt.

Ich habe immer noch das gleiche Problem in meiner App, und der Hack, um es zu lösen, ist hässlich und so teuer ... Ich empfehle auch, diese Verbesserung zu akzeptieren.

Ich würde mich auch freuen, wenn diese Funktion hinzugefügt würde.

Es scheint, als ob der Blocker eine potenzielle Leistungsminderung darstellt, aber das sollte leicht zu testen sein. Wir können versuchen, es hinzuzufügen, und wenn es einen inakzeptablen Leistungsabfall gibt, können wir es wieder entfernen.

Das gleiche hier, könnte diese Funktion verwenden, anstatt mein Hintergrund-Rendering neu zu implementieren :)

Ich bin mir nicht sicher, ob ich dem Leistungsproblem folgen kann. Nichts hindert uns daran, die Strahlrichtung direkt im Vertex-Shader zu generieren? Dann würde es so viel kosten wie jede andere modelMatrix Transformation.

In meinem Fall könnte ich diese Funktion verwenden, weil ich Cubemaps rendere, die von Kameras aufgenommen und von Benutzern hochgeladen wurden. Die Fotos sind nicht immer korrekt nach Norden ausgerichtet, daher müssen sie nach dem Hochladen manuell korrigiert werden.

Eine Möglichkeit, dies zu tun, besteht darin, die Drehung als Variable zu speichern, sie kurz vor dem Rendern auf die Szene anzuwenden und dann die Drehung der Szenen direkt nach dem Rendern auf den Identitätsquat zurückzusetzen.

Dies führt zu zwei unnötigen Aktualisierungen der Weltmatrizen aller meiner Szenenobjekte. Es bedeutet auch, dass ich in onBeforeRender keine Positionsaktualisierungen durchführen kann. Aber es hält die Szene ansonsten in einem normalen Zustand.

Übrigens (da es niemand erwähnt hat), scheint es möglich zu sein, eine "klassische" Skybox zu erstellen, die sich mit einem Array von 6 Materialien dreht.

etwas wie das :

const urls = [
  '/assets/skybox/right.png',
  '/assets/skybox/left.png',
  '/assets/skybox/top.png',
  '/assets/skybox/bottom.png',
  '/assets/skybox/front.png',
  '/assets/skybox/back.png',
];

const materials = urls.map((url) => {
  const texture = new THREE.TextureLoader().load(url);

  return new THREE.MeshBasicMaterial({
    map: texture,
    side: THREE.BackSide,
    fog: false,
    depthWrite: false,
  });
});

const skybox = new THREE.Mesh( new THREE.BoxBufferGeometry(10000, 10000, 10000), materials );
scene.add(skybox);

skybox.rotation.y = Math.PI / 2;

Wie hier gezeigt: https://woodenraft.games/demos/skybox-rotation-threejs.html

@wmcmurray Sie müssen diese Skybox mit der Kamera bewegen, damit sie richtig funktioniert, und Sie müssen sicherstellen, dass Ihre Boxdimension X < Math.sqrt (0,75 * camera.far * camera.far) ist, also die Ecken passen immer in die Ansicht, aber das scheint einfacher zu sein als mein Hack, die Szene zu drehen/zu entdrehen.

Sollten wir dafür wieder eine PR eröffnen? Es gibt zwei Anwendungsfälle und wenn wir die Leistung nicht beeinträchtigen möchten, können wir eine Shader-Definition verwenden:

  • Anwendungsfall 1: Die Umgebung wird einmal vorberechnet und sollte nicht im Shader gedreht werden müssen. Dies kann der Benutzer entweder auf der CPU oder sogar auf der GPU tun, wenn er möchte
  • Anwendungsfall 2: Bei der Arbeit an einem Viewer ist es durchaus üblich, den Hintergrund in Echtzeit zum Beispiel mit der Maus zu drehen.

Um zu verhindern, dass der Benutzer mit Anwendungsfall 1 von der Matrixmultiplikation betroffen ist, können wir vielleicht einfach ein Flag hinzufügen wie:

renderer.dynamicBackground = true;

und den Hintergrundshader entsprechend kompilieren?

In der Zwischenzeit

Wie @wmcmurray und @capnmidnight zeigten, können Sie im Grunde Ihr eigenes Hintergrund-Rendering neu codieren und es ist nicht so schwierig. Seien Sie nur besonders vorsichtig mit der Betrachtungsebene (nahe und ferne Werte).

Anstatt MeshBasicMaterial , können Sie auch direkt Ihren eigenen Shader erstellen, der ShaderMaterial und die Cubemap proben.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

jack-jun picture jack-jun  ·  3Kommentare

clawconduce picture clawconduce  ·  3Kommentare

zsitro picture zsitro  ·  3Kommentare

ghost picture ghost  ·  3Kommentare

fuzihaofzh picture fuzihaofzh  ·  3Kommentare