Three.js: UV-Offset/Repeat sollte eher Teil von Materialien als von Texturen sein

Erstellt am 10. Jan. 2015  ·  73Kommentare  ·  Quelle: mrdoob/three.js

UV-Offset und Wiederholung (und wahrscheinlich einige der anderen Textureigenschaften) sind Uniformen, die seltsamerweise von der Textur an das Material weitergegeben werden, was zu Problemen führt, bei denen Sie Texturen pro Material klonen müssen (was eine Menge Speicher verschwendet), wenn Sie möchten -Material Offsets/Repeats, oder rollen Sie Ihren eigenen benutzerdefinierten Shader. Es ist sehr ineffizient, Leute dazu zu zwingen. Der beste Fall ist, wenn jemand eine Textur basierend auf der Größe des Objekts, auf das sie angewendet wird, über eine Oberfläche kacheln oder eine Textur als Spritesheet für Animationen verwenden möchte. Ich kann das aktuelle System nur als Hindernis ohne wirkliche Vorteile sehen, da die Wahrscheinlichkeit, gemeinsame UV-Offsets / Wiederholungen auf einer "gemeinsamen" Textur zu benötigen, gering ist und normalerweise besser durch die gemeinsame Nutzung eines Materials gedient wäre. Auf jeden Fall ist das Aktualisieren der Uniformen von der Textur seltsam, da es wirklich nichts zu bedeuten hat, Teil der Textur zu sein und für den Endbenutzer verwirrend ist. Wenn Sie beispielsweise den Offset/Repeat ändern, wenn mehr als ein Map auf das Material angewendet wird, z , wenn es wirklich darauf hindeutet, dass es den Offset/Repeat der normalen Karte beeinflussen sollte. Es ist rundum verwirrend.

Ich bin mir ziemlich sicher, dass die Änderung in der Funktion "refreshUniformsCommon" erforderlich ist, aber wahrscheinlich steckt mehr dahinter. Auch im Sprite-Plugin sind einige Änderungen erforderlich. Dies würde wahrscheinlich viele Projekte zerstören, aber es ist eine ziemlich große Inkonsistenz in der Textur- / Material-API. Es könnte eine bessere Idee sein, es zu einer Überschreibung zu machen, die normalerweise für Materialien null ist, und wenn sie die Werte in den Texturen ignoriert, nur damit nicht alle Sachen kaputt gehen.

Suggestion

Hilfreichster Kommentar

Dieser Thread ist für mich TL;DR. aber ich habe gerade diesen Code in r68 entdeckt (altes Projekt, ja):

        // uv repeat and offset setting priorities
        //  1. color map
        //  2. specular map
        //  3. normal map
        //  4. bump map
        //  5. alpha map

        var uvScaleMap;

        if ( material.map ) {

            uvScaleMap = material.map;

        } else if ( material.specularMap ) {

            uvScaleMap = material.specularMap;

        } else if ( material.normalMap ) {

            uvScaleMap = material.normalMap;

        } else if ( material.bumpMap ) {

            uvScaleMap = material.bumpMap;

        } else if ( material.alphaMap ) {

            uvScaleMap = material.alphaMap;

        }

        if ( uvScaleMap !== undefined ) {

            var offset = uvScaleMap.offset;
            var repeat = uvScaleMap.repeat;

            uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );

        }

also ja...

Wenn Sie eine grundlegende Änderung der Bibliothek vorschlagen, wie Sie sie hier vorgeschlagen haben, müssen Sie diese Änderung klar und überzeugend begründen

Ich habe versucht, auf diffusen und normalen Maps unterschiedliche Wiederholungen einzustellen und mir die Haare auszureißen, weil es nicht funktionierte. da API diese Einstellung in Textur platziert, dachte ich, ich könnte das tun. Also ja, wie wäre es, wenn ich meine Haare für überzeugende Argumente aufbewahre? dieses Ticket ist noch offen, 3js hat immer noch diese Einstellung für Texturen, und sie wird nur für eine der Texturen respektiert = dies ist tatsächlich bereits eine Einstellung pro Material.

Wenn Sie dies nicht dorthin verschieben, wo es hingehört, sagen Sie zumindest, dass es keine Auswirkungen auf die Dokumente hat?

Alle 73 Kommentare

Verwandter Beitrag: https://github.com/mrdoob/three.js/issues/3549

Sie müssen Texturen pro Material klonen (was eine Menge Speicher verschwendet)

Inwiefern werden Tonnen von Speicher verschwendet?

die Wahrscheinlichkeit, gemeinsame UV-Offsets/Wiederholungen auf einer "gemeinsamen" Textur zu benötigen, ist gering

Was meinst du damit?

Wenn wir den aktuellen Ansatz beibehalten, muss eine Sache geändert werden, wenn eine Textur geklont wird, sollte das freigegebene Image nur einmal an die GPU übergeben werden.

Wenn Sie ein Objekt mit einer großen Anzahl von Frames/Blättern haben, werden viele nutzlose Objekte erstellt, und wie bereits erwähnt, wird das Bild mehrmals auf die GPU kopiert, was äußerst verschwenderisch ist. Noch verschwenderischer ist es, wenn Sie mehrere Objekte haben, die sich an verschiedenen Stellen in verschiedenen Animationen befinden müssen, müssen Sie für jedes einzelne Material / Objekt einen einzigartigen Satz von Texturen erstellen, sodass es schnell nervig wird, wenn eine Materialuniform sein könnte viel einfacher manipuliert werden, ohne dass diese zusätzlichen Textur-Offset/Repeat-Datenstrukturen um eine schlecht durchdachte API herum gebaut werden, nur um sie zum Laufen zu bringen. Ich habe eine große Verlangsamung in einem bestimmten Anwendungsfall meiner Anwendung, bei dem ich diese einzigartigen Texturgruppen überall erstellen muss, und denke, dass die einzige Lösung darin besteht, alle von mir verwendeten Standardmaterialien durch Shadermaterialien zu ersetzen, um dieses einzelne Problem zu umgehen. oder meine THREE.js-Version forken und die notwendigen Änderungen vornehmen.

Zur zweiten Aussage:

Ich meinte, dass das aktuelle Paradigma die Arbeit nur in Fällen erleichtert, in denen Sie dieselbe Textur mit demselben UV-Offset/Wiederholung anwenden möchten, aber das ist im Allgemeinen ein seltener Fall, da es viel wahrscheinlicher ist, dass Sie dies wie andere definieren möchten Uniformen pro Material und teilen sich ein Material und nicht nur die Textur.

Der wichtigste Vorbehalt mit der aktuellen sys. ist, dass der Offset/Repeat wirklich nur als eine einzige Uniform existiert, die sich auf alle Texturen im Shader auswirkt, aber die Tatsache, dass er an THREE angehängt ist. Textur bedeutet, dass er nicht richtig als Uniform verwendet werden kann und die Leute dazu bringt, zu denken, dass Offsets/Wiederholungen kann für die verschiedenen Texturen, die auf Standardmaterialien angewendet werden können, unterschiedlich gewählt werden (dh Sie können einen anderen Diffus-Offset und Normal-Map-Offset definieren, aber dies ist tatsächlich nicht möglich, obwohl sie auf die verschiedenen Texturen eindeutig eingestellt werden können). Ich kann sehen, dass es möglicherweise ein Überbleibsel des Canvas-Renderers war, aber es macht einfach keinen Sinn mit dem webGLrender / GLSL-Materialsystem, das es weitgehend an sich gerissen hat.

mrdoob gab an, dass es die folgende Form haben müsste, um es nicht pro Material zu haben:

material.karte
material.mapOffset
material.mapRepeat
material.env
material.envOffset
material.envWiederholen
... etc.

Aber auch hier funktionieren Offset / Repeat auch jetzt nicht pro Kartentyp, daher ist dies kein wirklich gültiges Argument. Es würde sowieso zu viele Uniformen verschwenden, es pro Kartentyp zu haben (ganz zu schweigen davon, dass Sie normalerweise nur einen Satz UVs verwenden, damit Sie nicht wirklich mehrere Offsets für eine Normalmap / Bumpmap / Diffusemap / Specularmap haben). Ich denke, wenn Sie alle Optionen vernünftig abwägen, sollte es wirklich eher eine Materialeigenschaft als eine Textureigenschaft sein. Ich glaube nicht, dass das aktuelle System Vorteile bringt. Ich glaube, dass das Animieren von Materialien durch den UV-Offset ein Hauptgrund ist, die Eigenschaft überhaupt zu haben, und kann dafür nicht einmal richtig verwendet werden. Ganz zu schweigen davon, dass, wenn Sie diese Uniformen nicht benötigen, sie aus der Shader-Zusammenstellung weggelassen werden können, während sie jetzt so lange vorhanden sind, wie es eine Karte gibt.

@QuaziKb Bei allem Respekt, wenn Sie eine grundlegende Änderung der Bibliothek vorschlagen, wie Sie sie hier vorgeschlagen haben, müssen Sie diese Änderung klar und überzeugend begründen. Das Argumentieren aus dem Bezugsrahmen Ihrer speziellen Anwendung wird es nicht bringen.

Davon abgesehen würde ich auch gerne sehen, dass Offset/Wiederholung von Texture auf die Materialien verschoben wird.

Ich glaube, es ist vernünftig anzunehmen, dass die folgenden Karten die gleichen Offset-/Wiederholungswerte haben:

specularMap
normalMap
bumpMap
alphaMap
aoMap (future)
glossMap (future)
displacementMap (future)

Die einzige Ausnahme ist


So wird es jetzt implementiert; Obwohl jede Karte ihre eigenen Offset-/Wiederholungswerte hat, werden diese nicht berücksichtigt.

Wir könnten also zu MeshPhongMaterial , MeshLambertMaterial , MeshBasicMaterial und SpriteMaterial addieren

mapOffset // or mapTranslate
mapRepeat // or mapScale

Wir würden offset und repeat aus Texture entfernen.

Auf diese Weise ist die Implementierung eines Sprite-Sheets einfach. Jedes Sprite hat ein Material, und diese Materialien teilen sich eine einzige Textur. Die Textur hat ein Bild. Die Textur muss nicht mehr geklont werden. Auf der GPU-Seite würden sich die Materialien ein einziges Shader-Programm teilen.

IMHO, dies ist eine natürlichere API.

Ich versuche mich daran zu erinnern, warum die API so implementiert wurde, wie sie war. Ich gehe davon aus, dass es einen guten Grund gab.

Entschuldigung wollte nicht andeuten, dass es speziell für mein Beispiel war, einfach dass die aktuelle API zu einer erheblichen Aufblähung führt, wenn sie zum Animieren von Sprite-Sheets / Offsets pro einzigartigem Objekt / Material verwendet wird, ohne dass es eine wirkliche Lösung gibt. Natürlich ist der Hauptzweck, dies als Uniform zu haben, anstatt einfach den Offset / die Wiederholung in die Scheitelpunkt-UVs des Modells zu backen, den Offset zu animieren, und ich schlug vor, dass dies nicht möglich ist, ohne die API zu umgehen und die Uniform zu erstellen an Texturen viel weniger nützlich als an dem Material.

Ich glaube, es ist vernünftig anzunehmen, dass die folgenden Karten die gleichen Offset-/Wiederholungswerte haben:
Karte
...
alphaMap

FWIW, dieses Verhalten (die aktuelle Implementierung) verursacht bei mir im Moment erhebliche Frustration. Ich versuche, die Enthüllung eines Netzes zu animieren, indem ich den alphaMap-Versatz des Netzmaterials unabhängig von seiner Diffus-Map (die fest bleibt) tweene. Nach einiger Frustration entdeckte ich über https://github.com/mrdoob/three.js/pull/4987 und diesen Bug, dass dies nicht möglich ist.

@jcarpenter Was ist der "Fehler", auf den Sie sich beziehen? Was ist Ihr Verbesserungsvorschlag?

Korrektur: Mit "Fehler" meinte ich dieses Problem. Eine Verwechslung aufgrund zu langer Zeit in einer Bugzilla-Kultur. :p Ich verstehe, dass dies kein Fehler ist, sondern eher das beabsichtigte Verhalten.

WRT zu einer Verbesserung, basierend auf meiner Erfahrung mit traditionellen 3D-Inhaltserstellungs-Apps wie Cinema 4D, kann ich mir vorstellen, dass der Benutzer beides kann:

  • Definiere Offset/Skalierung/Wiederholung für jede Textur innerhalb eines Materials, unabhängig von den anderen Texturen, _und_
  • Definieren Sie Offset/Skalierung/Wiederholung des Ausgangsmaterials

Alternativ für den Anwendungsfall, an dem ich arbeite ("Versuch, die Enthüllung eines Netzes zu animieren") wäre es fantastisch, eine Option für WrapS und WrapT zu haben, die überhaupt nicht umhüllt. Gemäß dem angehängten GIF von Cinema4D, das eine Option zum Deaktivieren der Kachelung für das UVW-Mapping bietet. Basierend auf ziemlich umfangreichen Tests mit den bestehenden WrapS- und WrapT-Methoden ist nichts dergleichen möglich. Das heißt, meine Optionen zum Animieren der Enthüllung von Elementen in Three.js scheinen auf die Tweening-Position und die Deckkraft des gesamten Meshs beschränkt zu sein ... Es sei denn, ich vermisse etwas.

c4d-tile-2

Einverstanden. Der Plan ist, all dies zu vereinfachen (mit einer einzigen Matrix3 im Shader) und einen Offset/Repeat (oder Translate/Skalierung) pro Textur zu haben.

Jeder, der dabei helfen möchte, wäre sehr dankbar!

@jcarpenter

Leider ist dies derzeit nur mit mehreren Meshes mit unterschiedlichen Materialien oder einem benutzerdefinierten Shadermaterial möglich. Beides ist für einen Benutzer, der gerade erst in den Three.js-Workflow einsteigt, involviert.

Es gibt einen ständigen Kompromiss zwischen Benutzerfreundlichkeit, Leistung und Erweiterbarkeit. Mein Vorschlag wäre, die Art und Weise, wie Texturen und Materialien derzeit in der API funktionieren, neu zu schreiben, sodass Texturen ausschließlich Parameter sind, die Sie einstecken, und die Werte, die im Shader tatsächlich Uniformen sind, wie der Offset-/Wiederholungs-/Wrap-Modus, sind speziell mit dem verknüpft Material. In einigen Fällen möchten Sie nicht, dass eine Uniform für die Kontrolle von UVs für Texturen verschwendet wird, die nie geändert werden müssen (es wäre eine große Verschwendung, 4 * 5 zusätzliche Uniformen in einem Phong-Material zu haben, wenn Sie es nur für Diffus benötigen). Es wäre also cool, wenn hinter den Kulissen etwas Magie steckt, die erkennt, ob bestimmte UVs benötigt werden und die Textur neu aufgebaut wird, um diese Anforderungen zu erfüllen, oder wenn optional ein Parameter übergeben werden könnte, um die Anzahl der erforderlichen einstellbaren UVs anzugeben und was? Karten, die sie ausgleichen und wie, aber es ist ein schwieriges Problem zu lösen.

Der Plan ist, all dies zu vereinfachen (mit einer einzigen Matrix3 im Shader) und einen Offset/Repeat (oder Translate/Skalierung) pro Textur zu haben.

@mrdoob

  1. Meinst du _per material.map_, also ist die Texturtransformation im Material? Leider gibt es viele Materialkarten. Wir könnten weiterhin davon ausgehen, dass alle Texturtransformationen mit Ausnahme der Lightmap gleich sind.
  2. Möchten Sie auch die Rotation unterstützen? Wenn dies der Fall ist, müssen Sie auch das Rotationszentrum hinzufügen – es sei denn, Sie möchten das Rotationszentrum fest mit dem Zentrum der Textur verdrahten.

Dies wäre eine sehr willkommene Abwechslung. Texturen klonen zu müssen, nur um sie auf einzigartige Wiederholungswerte zu setzen, fühlt sich schrecklich umständlich an. Machen das andere Bibliotheken so?

  1. Meinst du _per material.map_, also ist die Texturtransformation im Material? Leider gibt es viele Materialkarten. Wir könnten weiterhin davon ausgehen, dass alle Texturtransformationen mit Ausnahme der Lightmap gleich sind.

Ich denke, wir sollten ein mat3 pro Karte haben und aus den Texture Eigenschaften bestehen.

  1. Möchten Sie auch die Rotation unterstützen? Wenn dies der Fall ist, müssen Sie auch das Rotationszentrum hinzufügen – es sei denn, Sie möchten das Rotationszentrum fest mit dem Zentrum der Textur verdrahten.

Drehung ja. Zentrieren oder nicht... Ich bin mir nicht sicher, aber soweit ich das verstanden habe, kann all dies in einem einzigen mat3 für den Shader (pro Karte) codiert werden.

Hier ist ein Prototyp, der zeigt, wie ein Matrix3 an einen Shader übergeben werden kann und eine Transformation darstellt, die durch offsetX , offsetY , repeatX , repeatY , rotation , rotationCenterX und rotationCenterY .

Wenn center als Option nicht erlaubt ist, dann sollte es mit ( 0.5, 0.5 ) verdrahtet werden.

Kommentare willkommen.

EDIT: Demo aktualisiert

rotateuvs

DAS IST TOLL! :+1: :+1:

Ich denke, ich würde mit translation und scale (statt offset und repeat ) gehen.

Was genau sollen die neuen Materialeigenschaften sein? Es gibt viele Materialkarten.

Was soll aus den Textureigenschaften entfernt werden?

Ich gehe davon aus, dass wrapS/T auf der Textur bleiben soll.

Ich denke, texture.offset und texture.repeat sollten entfernt werden.

Ich denke, die neuen Eigenschaften sollten sein... texture.translation , texture.rotation , texture.scale , texture.center und texture.matrix . Wir werden wahrscheinlich auch eine Methode texture.updateMatrix() benötigen, die zur Renderzeit aufgerufen wird. Dies hat natürlich die Herausforderung, sicherzustellen, dass wir dies nur einmal tun, auch wenn die Textur wiederverwendet wird.

In Bezug auf den Titel dieses Beitrags und die Argumente in https://github.com/mrdoob/three.js/issues/5876#issuecomment -69483293 dachte ich, es geht darum, diese Eigenschaften in das Material zu verschieben.

/ping @bhouston für Kommentare.

Meine Gedanken sind, dass der Textur-Offset / -Repeat so weit wie möglich in die UVs eingebrannt werden sollte. Es ist leichter. So machen es UE4/Unity 5 zum größten Teil.

Die Ausnahme besteht darin, dass Unity 5 die Möglichkeit hat, einen globalen Offset/Repeat pro Material anzugeben, der von allen Texturen gemeinsam genutzt wird – aber dies hat keinen Einfluss auf die als gebackene Maps angesehenen Maps wie LightMap oder AmbientOcclusion Maps (diese Es macht keinen Sinn, angepasst zu werden.)

Der Grund, warum ich hier nicht für viel Flexibilität plädiere, ist, dass professionell erstellte Modelle über geeignete UVs verfügen, die dies im Allgemeinen nicht erforderlich machen – Tools zur Inhaltserstellung haben Möglichkeiten, dies zu backen. Das andere Problem ist, dass WebGL eine lächerlich niedrige Untergrenze für Fragment-Uniformen hat – 16 Vec4. Wenn Sie eine Wiederholung/Versatz pro Karte haben müssen und wir bald viele Karten bekommen, verschwenden wir Fragment-Uniformen für sehr wenig Wert.

Ich habe kürzlich in Clara.io tatsächlich eine Wiederholungs- / Offset- und dann Helligkeits- / Verstärkungssteuerung pro Textur hinzugefügt und ich werde diese Änderungen rückgängig machen, da dies dazu führt, dass die Fragment Uniforms auf Low-End-Geräten überlaufen - wie bei jedem Apple iOS-Gerät. Obwohl Repeat/Offset und Helligkeit/Gain auf Desktops mit NVIDIA 980s gut funktionieren, müssen wir für alle entwerfen, nicht für die High-End-Maschinen. ;)

Wir müssen Fragmentuniformen mit Respekt behandeln und sie nur verwenden, wenn es notwendig ist. Dies ist, glaube ich, keiner dieser Fälle.

Die Ausnahme ist, dass Unity 5 die Möglichkeit hat, einen globalen Offset/Repeat pro Material anzugeben

Dies ist im Grunde das, was Three.js jetzt tut -- obwohl es den Offset / die Wiederholung von der Diffuse-Map erhält und alle anderen Materialtexturen die Einstellung von dieser Map verwenden.

Der Vorschlag besteht darin, den Offset/Repeat aus der Textur zu entfernen und stattdessen dem Material hinzuzufügen – möglicherweise mit einer Namensänderung. Auch hier würden alle Materialtexturen die gleichen Einstellungen aufweisen (auch wenn einige Benutzer darüber nicht glücklich wären). Dies würde die einheitliche Nutzung gering halten.

Leider sind wir uns diesbezüglich nicht sehr einig.

Es ist eine gute Idee, das zu tun, was Unity 5 tut. Ich würde es auch auf das Material statt auf die Textur legen. Du hast meine Unterstützung.

Pro Map ist nicht wirklich ideal, aber es könnte gelöst werden, indem man es irgendwie mit Flags / Keys spezifiziert, wenn die Materialien gebaut werden, falls es benötigt wird.

Im Allgemeinen besteht der einzige Grund, UVs im Shader zu ändern, darin, dass sie animiert werden sollen. Wenn Sie die UVs nur statisch transformieren möchten, sollten wir den Shader nicht ändern, um diese Funktionalität hinzuzufügen.

Die einzige vorgeschlagene Änderung des Shaders ist die Ersetzung

vUv = uv * offsetRepeat.zw + offsetRepeat.xy;

mit

vUv = ( uvTransform * vec3( uv, 1 ) ).xy;

Okay. Wie wäre es damit... Wir fügen texture.dynamic (standardmäßig false ) hinzu, was Folgendes ergibt:

vUV = uv;

Wenn der Benutzer texture.dynamic auf true , berechnen wir texture.matrix aus texture.translation , texture.rotation , texture.scale und texture.center , wir geben das an die Programme weiter und produzieren:

vUv = ( uvTransform * vec3( uv, 1 ) ).xy;

Wenn sich texture.dynamic ändert, müssen wir das Programm natürlich neu kompilieren.

So bekommen wir das Beste aus beiden Welten?

@mrdoob

  1. Ist scale Ihrer Meinung nach eine Eigenschaft der Textur oder ist texture.scale eine Eigenschaft des Materials? Ich hoffe, es ist letzteres, denn darum geht es in diesem Thread.
  2. Wir brauchen keine .matrix Eigenschaft. Das neue Matrix3 ist eine Uniform, die die Materialuniform offsetRepeat . Es wird aus den anderen Parametern im Renderer berechnet und wie jede andere Uniform an die GPU übergeben.
  1. Ist scale Ihrer Meinung nach eine Eigenschaft der Textur oder ist texture.scale eine Eigenschaft des Materials? Ich hoffe, es ist letzteres, denn darum geht es in diesem Thread.

Ich bin mit diesem Thread nicht einverstanden. Ich denke nicht, dass wir die Materialien mit mapMatrix , envMapMatrix , ... oder mapTranslation , mapRotation , mapScale verschmutzen sollten. Ich denke, es ist sauberer, wenn THREE.Texture translation , rotation , scale und vielleicht center .

  1. Wir brauchen keine .matrix Eigenschaft. Das neue Matrix3 ist eine Uniform, die die Materialuniform offsetRepeat . Es wird aus den anderen Parametern im Renderer berechnet und wie jede andere Uniform an die GPU übergeben.

So etwas brauchen wir irgendwie. Angenommen, man verwendet dieselbe Textur in verschiedenen Maps. Wir möchten nicht die Matrix3 für jede Instanz berechnen.

Ich bin mit diesem Thread nicht einverstanden. Ich denke nicht, dass wir die Materialien mit mapMatrix, envMapMatrix, ... verschmutzen sollten, noch mit mapTranslation, mapRotation, mapScale. Ich denke, es ist sauberer, wenn THREE.Texture Translation, Rotation, Scale und vielleicht Center hat.

Müsste eine Textur noch geklont werden, um unterschiedliche Wiederholungseigenschaften zu haben? In kleinen Szenen ist dies wahrscheinlich keine große Sache, aber in großen, wo es bereits 40+ Texturen gibt, ist dies ein Erinnerungs-Albtraum.

@titansoftime image sollte von THREE.Texture entkoppelt werden. Idealerweise könnte ein einzelnes THREE.Image von verschiedenen THREE.Texture jede mit unterschiedlichen translation , rotation , ... Konfigurationen.

@titansoftime image sollte von THREE.Texture entkoppelt werden. Idealerweise könnte ein einzelnes DREI.Image von verschiedenen DREI.Texturen verwendet werden, jedes mit unterschiedlichen Übersetzungen, Drehungen, ... Konfigurationen.

Das macht Sinn. Funktioniert texture.clone() bereits so oder muss es manuell eingerichtet werden?

texture.clone() funktioniert so, aber WebGLRenderer nicht wissen, dass das Bild gleich ist, also ist das Hochladen der Textur unnötig...

Ich bin mit diesem Thread nicht einverstanden. Ich denke nicht, dass wir die Materialien mit mapMatrix, envMapMatrix, ... verschmutzen sollten, noch mit mapTranslation, mapRotation, mapScale. Ich denke, es ist sauberer, wenn THREE.Texture Translation, Rotation, Scale und vielleicht Center hat.

Das ist im Grunde das, was wir jetzt tun. Jede Textur hat ihre eigene offset Eigenschaft, und die einzelnen Offsets werden nicht berücksichtigt – der Renderer verwendet für jede Map des Materials denselben Offset.

FWIW, ich denke, wir sollten tun, was ich in https://github.com/mrdoob/three.js/issues/5876#issuecomment -69483293 gesagt habe.

Ich verstehe nicht, warum die API nicht zulassen kann, was @jcarpenter tun möchte (den Offset von alphaMap animieren, während map bleibt). Das könnte man in Canvas machen, aber ich denke, das ist stattdessen eine Aufgabe für die GPU.

Es gibt eine Menge Dinge, die man tun könnte, indem man mit Offsets verschiedener Karten spielt... nur die alphaMap ausgleichen, die normalMap skalieren usw.

Nur ein uvTransform pro Material zu haben scheint sehr, sehr einschränkend zu sein.

Oh, Moment mal. Ich glaube, ich verstehe, warum ihr das Material bevorzugt. Auf diese Weise wird eine einzelne vUv im Vertex-Shader berechnet, anstatt die UV pro Pixel im Fragment-Shader zu berechnen. Rechts?

pro Material ist ideal, da die Versätze eigentlich nur mit einer Uniform des Materials implementiert werden und nichts mit der Textur zu tun haben Tonnen von neuen Objekten/Texturen (was in JS ziemlich schlecht ist/schrecklich in WebGL), nur um etwas zu kontrollieren, das wirklich nur ein Merkmal der Materialuniformen ist, die den Benutzern verborgen bleiben. Es ist in keiner Weise vorteilhaft, effizienter oder noch klarer, es als Teil der Textur zu haben, und es bedeutet, dass die einzige echte Anwendung der Angabe von UVs, die sich zur Laufzeit ändern, Animationen, aufgrund der API langsam und ineffizient gerendert werden.

Texturen sollten ein Bild und alles, was zu diesem Bild gehört, angeben. UV-Offsets haben nichts mit den Bild- / Bildeigenschaften zu tun, und alles hat mit dem Material zu tun, das die Textur anzeigt -Instanz und das gleichzeitige Aktualisieren vieler Texturen, wenn man die Funktion in vielen Fällen tatsächlich nutzen möchte.

Stellen Sie sich vor, Sie haben für jeden Frame einer animierten Kachel ein anderes Bild und möchten auch den Versatz/die Wiederholung dieser Kachel steuern. Sie müssten jeden eingehenden Frame mit den Offsets aktualisieren sowie Kopien jedes Frames für jede einzelne Instanz von Material haben, die diese Kachel verwendet ein paar schweben pro Material hinter den Kulissen mit all diesen Objekten ohne triftigen Grund.

Was die Transformationen pro Karte angeht, obwohl es schön wäre, sind die einheitlichen Kosten in den meisten Fällen ohne Grund zu hoch, es sei denn, wir haben eine komplexe API, um zu steuern, wann und wie die Transformationen einzigartig oder gemeinsam oder dynamisch sein sollen, IMO Diese Kontrolle zu haben wäre eine gute Sache, aber es müsste sorgfältig durchdacht werden.

Oh, Moment mal. Ich glaube, ich verstehe, warum ihr das Material bevorzugt. Auf diese Weise wird eine einzelne vUv im Vertex-Shader berechnet, anstatt die UV pro Pixel im Fragment-Shader zu berechnen. Rechts?

Nein. Die UV wird wie immer im Vertex-Shader berechnet.

Stellen Sie sich ein Sprite-Blatt und 20 Sprites vor. Derzeit benötigen wir 20 geklonte Materialien und 20 geklonte Texturen – genau wie in http://threejs.org/examples/misc_ubiquity_test2.html. (Übrigens, beachten Sie, dass wir bereits SpriteMaterial.rotation .)

Verschieben wir den Offset zum Material, benötigen wir 20 geklonte Materialien und eine Textur.

Tatsächlich würden wir beim Verschieben des Offsets zum Sprite 1 Material und 1 Textur benötigen.

Stellen Sie sich ein Sprite-Blatt und 20 Sprites vor. Derzeit benötigen wir 20 geklonte Materialien und 20 geklonte Texturen

Ohm, ich habe diesen Anwendungsfall nicht in Betracht gezogen. Vielen Dank!

ich werde mir das überlegen...

Ich befürworte keine UV-Transformationen in der Textur.

Aus zwei Gründen: (1) es ist verwirrend, (2) es gibt mehr Ereignisse zu verbreiten und (2) es ist verschwenderisch.

Verwirrung: Der Grund dafür ist, dass wir nur eine einzige UV-Variable für die Haupt-Maps haben, aber wenn es eine UV-Transformation auf einer der Texturen gibt, ist es verwirrend, dass diese UV-Transformation auf alle Maps angewendet wird, die das erste UV verwenden Kanal, unabhängig davon, ob die anderen Texturen eine Transformation haben oder nicht. Wenn wir zulassen würden, dass jede Map ihre eigene UV-Transformation im Material hat, wäre ich mit der mit der Textur verbundenen UV-Transformation eher einverstanden - aber das ist aufgrund der einheitlichen Verwendung von Fragmenten schwierig.

Mehr Ereignisausbreitung: Das andere Problem, auf das ich in Clara.io gestoßen bin, ist die Ereignisausbreitung beim Versuch, Texturparameter zu animieren. Man braucht jede Textur, um jedes Material zu verfolgen, das sie verwendet, und dann diesen Materialien mitzuteilen, dass sie schmutzig sind und neu berechnet werden müssen. Es ist nicht unmöglich, dies zu tun, nur mehr Arbeit.

Verschwenderisch: Das andere Problem besteht darin, dass Sie mehrere Instanzen eines 3D-Modells oder Trotz haben und alle die gleiche animierte Textur haben. In diesem Fall müssten Sie verschiedene Kopien der Textur im Speicher haben, nur um sie anders animieren zu lassen – obwohl die Texturdaten selbst dieselben sind. Es ist in diesem Sinne etwas verschwenderisch, verglichen mit dem Aufbringen der UV-Transformationsdaten auf die Materialien.

Wenn wir also nur eine zulässige UV-Transformation pro Material haben, würde ich sie auf das Material selbst legen. Ich würde dem Unity 5-Modell folgen, bei dem sie einen UV-Offset und eine Rotation im Material haben. Spieleentwickler kennen diesen Ansatz bereits.

Ich denke, dass Sprites von UV Transform auch auf den Materialien gut verarbeitet werden - es ist dem obigen 3D-Modellfall sehr ähnlich.

Having only one uvTransform per material seems very very limiting.

Stimme hier voll und ganz zu. Diese Funktionalität nicht zu haben, ist extrem einschränkend. Es gibt fantastische Effekte, die hier bereitgestellt werden könnten, die es aber nicht gibt, weil jeder Offset miteinander verbunden ist.

Aber wie kann diese Funktionalität verfügbar gemacht werden, ohne an Klonen zu ersticken?

Ich denke, dass es sinnvoll ist, die Werte für das Material und nicht die Textur für den allgemeinen Anwendungsfall zu verwenden, bei dem alle Texturen abgeglichen werden.

Stimme hier voll und ganz zu. Diese Funktionalität nicht zu haben, ist extrem einschränkend. Es gibt fantastische Effekte, die hier bereitgestellt werden könnten, die es aber nicht gibt, weil jeder Offset miteinander verbunden ist.

Aber wie kann diese Funktionalität verfügbar gemacht werden, ohne an Klonen zu ersticken?

THREE.ShaderMaterial oder THREE.RawShaderMaterial würde Ihnen diese Fähigkeit geben, und da es derzeit mit normalen Materialien nicht funktioniert, müssen Sie dies sowieso verwenden.

Wenn Sie etwas Funkigeres tun, wird es wahrscheinlich funky sein, als nur Map-Wiederholungen und -Offsets unabhängig voneinander anzupassen, also würden Sie sich wahrscheinlich trotzdem auf diese Weise lehnen.

+1 dafür, Leute.

Es wäre sehr nützlich, wenn Sie ein riesiges Sprite-Sheet (alias Atlas) haben und seine Textur auf mehreren THREE.Sprite Instanzen wiederverwenden möchten.

Gibt es darüber irgendwelche Neuigkeiten? Dieses Problem ist immer noch ein ziemlich eklatanter Fehler in der API. Die meisten Kartentypen haben Offsets/Wiederholungen, die nicht verwendet werden, und die Ereignisausbreitung macht so etwas wie ein animiertes Sprite auf einem Flugzeug viel langsamer/speicherlastiger als es sein muss.

Flexibilität für animierte Karten EXISTIERT im aktuellen System NICHT. Immer wieder taucht das Argument auf, dass wir die Flexibilität reduzieren würden, indem wir die Einstellungen an das Material binden. Dieses Argument ist strittig, da diese Flexibilität im aktuellen System nicht vorhanden ist. Sie können den Offset/Repeat nur global für das Material einstellen und es wird aus der Diffuse Map (?) übernommen. Dies führt zu einem noch schlimmeren Problem, bei dem auf den meisten verwendeten Maps redundante "Offset" / "Repeat"-Einstellungen vorhanden sind und wenn Sie Texturen für Animationen nicht teilen möchten, müssen Sie einen Klon erstellen, sodass die Flexibilität erheblich ist reduziert. Sie erwarten, dass jede Textur / Map eindeutige Offsets hat, aber dies ist nach derzeitigem Stand nicht möglich, und in den meisten Fällen möchten Sie tatsächlich einen Satz UV-Offsets, da es ärgerlich wäre, die Offsets für Normal/Spezifikation auf dasselbe einzustellen /diffuse (eine scrollende Normal-Map über einer festen Diffus-Map ist eine Nischenanwendung, bei der ein Shader-Material verwendet werden könnte).

Wenn Sie sich die eigentlichen Shader ansehen, die gebaut werden, ist der Textur-Offset / -Wiederholung an das Material gebunden, aber seltsamerweise von einer Karte kopiert, die in keiner Weise kontrolliert werden sollte. Das Material MUSS die Kontrolle haben, damit dies schnell und elegant ohne Redundanz ist.

Das Beste aus beiden Welten ist mit Tonnen von zusätzlichen Flags möglich, aber ich glaube nicht, dass dies eine bessere Lösung ist, als die Benutzer anzuweisen, stattdessen das Shader-Material für diese speziellen Randfälle zu verwenden.

Die Lösung hierfür ist übrigens NodeMaterial von @sunag.

Dazu füge ich auch meine +1 hinzu! Würde die Arbeit mit Sprite Sheets viel angenehmer machen.

:+1: Das fand ich überraschend. Ich musste meine Texturen für jedes Sprite im Spiel duplizieren, da sich alle meine wiederholten Sprites gegenseitig animierten. Klingt so, als würde das bedeuten, dass ich redundante Sprite-Daten auf die GPU lade?

Hat jemand einen Workaround für dieses Problem? Könnte es möglich sein, den UV-Offset zu manipulieren, indem man die Uniform direkt am Shader festlegt und die Textur-Schnittstelle umgeht?

Die Lösung hierfür ist übrigens NodeMaterial von @sunag.

@bhouston , könntest du bitte einen Link bereitstellen? Es gibt kein öffentliches Repository unter @sunags Konto mit diesem Namen.

@rhys-vdw Es befindet sich nur hier im Dev-Zweig:

https://github.com/mrdoob/three.js/tree/dev/examples/js/nodes

Es ist neu, daher bin ich mir nicht sicher, ob es für Sprites bereit ist, aber es ist ein vollständig grafikbasiertes Shader-System, sodass Sie die Flexibilität haben, Texturzugriffe beliebig zu ändern.

Es ist neu, daher bin ich mir nicht sicher, ob es für Sprites bereit ist, aber es ist ein vollständig grafikbasiertes Shader-System, sodass Sie die Flexibilität haben, Texturzugriffe beliebig zu ändern.

@bhouston Ich kann ein Beispiel mit Node erstellen, das sieht gut aus.

Über das THREE.SpriteMaterial könnten Sie auf Offset/Scale zugreifen, um das spritesheet zum Beispiel zu erstellen:

var offsetX = frameX / mapWidth;
var scaleX = mapWidth / frameWidth;

sprite.material.map.offset.x = offsetX;
sprite.material.map.repeat.x = scaleX;

https://github.com/mrdoob/three.js/blob/master/src/renderers/webgl/plugins/SpritePlugin.js#L53

Das knotenbasierte System ist kein Fix ... Es behebt immer noch nicht die Probleme mit der API. Es dauert 2 Sekunden, um dem Materialprototyp Offset/Repeat hinzuzufügen und den Renderer statt der Textur davon ablesen zu lassen. Ich habe es bereits für mein Projekt getan, aber die Tatsache bleibt ein offensichtlicher Fehler in der API, der offiziell geändert werden sollte, um Kopfschmerzen für neue Benutzer zu vermeiden, die auf dieses Problem stoßen, wenn sie versuchen, etwas Gemeinsames zu tun.

...damit Sie die Texturzugriffe beliebig ändern können.

tbh ich weiß nicht was das bedeutet. Animieren individueller Set-Shader-Uniformen für "Offset" und "Repeat" auf Materialbasis.

Über das THREE.SpriteMaterial können Sie beispielsweise auf Offset/Scale zugreifen, um das Spritesheet damit zu erstellen...

@sunag , vielleicht ist das Problem nicht klar. Der von Ihnen freigegebene Code verändert die Textur, die von allen Instanzen dieses Materials geteilt wird. Dies bedeutet, dass es unmöglich ist, dass sich zwei Materialien eine Textur teilen, jedoch mit einzigartigen Offsets – zum Beispiel zwei feindliche Sprites, die unterschiedliche Animationsframes zeigen.

Ich habe es bereits für mein Projekt getan, aber die Tatsache bleibt ein offensichtlicher Fehler in der API, der offiziell geändert werden sollte, um Kopfschmerzen für neue Benutzer zu vermeiden, die auf dieses Problem stoßen, wenn sie versuchen, etwas Gemeinsames zu tun.

@QuaziKb Gibt es eine PR, auf die ich für mein Projekt abzielen kann?

Obwohl die ganze Sache kein Problem wäre, wenn, wie @WestLangley sagte, Folgendes wahr wäre:

Wenn wir den aktuellen Ansatz beibehalten, muss eine Sache geändert werden, wenn eine Textur geklont wird, sollte das freigegebene Image nur einmal an die GPU übergeben werden.

Ist das korrekt?

@sunag , vielleicht ist das Problem nicht klar. Der von Ihnen freigegebene Code verändert die Textur, die von allen Instanzen dieses Materials geteilt wird. Dies bedeutet, dass es unmöglich ist, dass sich zwei Materialien eine Textur teilen, jedoch mit einzigartigen Offsets – zum Beispiel zwei feindliche Sprites, die unterschiedliche Animationsframes zeigen.

Hmm, dafür würde NodeMaterial sicherlich lösen, Sie werden in der Lage sein, dieselbe Textur mit verschiedenen Materialien und unabhängigem UV-Offset zu teilen und Vorteile wie benutzerdefinierte Filter und andere Dinge, die ein knotenbasiertes Material bieten kann.

https://github.com/mrdoob/three.js/issues/7522

Aber im Moment hat jemand versucht, die uuid so zu instanziieren:?

THREE.Texture.prototype.createInstance = function() {

    var inst = this.clone();

    inst.uuid = this.uuid;
    inst.version = this.version;

    return inst;

}

Wenn Sie needsUpdate aktualisieren Sie auch alle Instanzen version .

Beispiel:

var uniqueTextureOffset = map.createInstance();
var material = new THREE.SpriteMaterial( { map: uniqueTextureOffset } );

Behalten Sie die gleichen uuid und version teilen sich die texture auf der GPU.

https://github.com/mrdoob/three.js/blob/master/src/renderers/WebGLRenderer.js#L2832
https://github.com/mrdoob/three.js/blob/master/src/renderers/webgl/WebGLProperties.js#L11

Obwohl es für mich eine vorläufige Lösung ist. Ich glaube an NodeMaterial für die Zukunft.

Können wir bitte UV-Transformationen in Material verschieben?

Wie wäre es mit dem Besten aus beiden Welten. Fügen Sie dem Material ein Flag overrideOffsetRepeat mit einem neuen uvOffset und uvRepeat auf dem Material hinzu. Auf diese Weise ist das Flag, wenn es falsch ist, abwärtskompatibel, und das ist die Standardeinstellung. Und wenn es wahr ist, verwendet es das Material Offset/Repeat. Ich würde dies unterstützen, da es den Anschein hat, dass der Bedarf intensiv und weit verbreitet ist. @WestLangley? @mrdoob?

(Obwohl ich die Verwendung von NodeMaterial für alles in der Zukunft wirklich unterstütze, aber es ist mühsam, darauf zu wechseln.)

Ich denke immer noch, dass die Lösung dafür darin besteht, THREE.Image zu erstellen. https://github.com/mrdoob/three.js/issues/5876#issuecomment -81189892

THREE.Image

@mrdoob , würde das bedeuten, dass jedes zugewiesene Texture zusammen mit einem Material geklont wird?

@mrdoob schrieb:

Ich denke immer noch, dass die Lösung dafür darin besteht, THREE.Image zu erstellen

Ja, das würde funktionieren, es wäre zwar etwas weniger abwärtskompatibel (wenn wir jetzt verlangen würden, dass jeder Bilder vor dem Erstellen von Texturen erstellt), aber ein saubereres Gesamtdesign. Vielleicht ist es möglich, ein Image automatisch pro Textur erstellen zu lassen, wenn man es nicht separat spezifiziert, dann würde das Abwärtskompatibilität erreichen? Und Sie müssten das Bild nur direkt bearbeiten, wenn Sie etwas Kniffliges tun wollten.

Ich schätze, diese Lösung würde das Doppelte der neuen Objekte für einen Satz Sprites erfordern - eine Textur für jedes Sprite und ein Material? Wo ist der andere Ansatz, der nur ein neues Material für jedes Sprite erfordern würde?

Ich weiß, dass Unity Repeat/Offset pro Material unterstützt, aber High-End-VFX-Tools wie 3DS Max, Maya, Softimage nicht - sie haben nur einen Bitmap-Knoten und einen Textur-Knoten (der sowohl den Bitmap-Knoten als auch ein UV-Mapping enthält). nod), das dem Design von @mrdoob ähnelt.

UE4 ähnelt auch dem, was @mrdoob vorschlägt, sie haben einen "Texture" -Knoten, der ein Bitmap-Loader ist, und dann haben sie eine Reihe von UV-Mapping-Knoten, um verschiedene Arten von UV-Mappings durchzuführen.

Die erweiterten Werkzeuge teilen Bild/Bitmap aus der Textur auf und teilen auch einen separaten UV-Mapping-Knoten in dieser Form auf:

 -> Bitmap
 -> UVMapping

Wir erlauben derzeit nicht viele UVMapping-Optionen im Haupt-StandardMaterial. Aber verschiedene Arten von UVMappings, die in UE4, Maya, Softimage, 3DS Max verwendet werden, wären der zu verwendende Kanal, eine darauf anzuwendende Transformation, die Verwendung von Weltkoordinaten als Quelle oder eine Kugel-, Würfel-, Planar-Projektion basierend auf den erforderlichen Parametern für diese Projektionen.

UE4 hat eine Sprite-Textur, die Wiederholung/Versatz innerhalb des Materials ermöglicht:

https://docs.unrealengine.com/latest/INT/Engine/Paper2D/Sprites/index.html

Maya, Softimage, 3DS Max und UE4 haben die Trennung von Bitmap/Bild von Textur (und von der UV-Generation), wie @mrdoob vorschlägt, aber sie alle verwenden auch Shader-Graphen, um dies zu erreichen. Unity3D, das keine Shader-Graphen hat, ist das Werkzeug, das den Offset/Repeat in das Material selbst integriert, wahrscheinlich weil es es nicht richtig in einen Shader-Graph-Knoten trennen kann.

Vielleicht ist es möglich, ein Image automatisch pro Textur erstellen zu lassen, wenn man es nicht separat spezifiziert, dann würde das Abwärtskompatibilität erreichen? Und Sie müssten das Bild nur direkt bearbeiten, wenn Sie etwas Kniffliges tun wollten.

Genau

Wahrscheinlich etwas fehl am Platz, um es zu erwähnen, aber ich möchte empfehlen, dass PTEX so schnell wie möglich integriert wird.
http://ptex.us/PtexFile.html
Wenn es eine Möglichkeit gibt, typische Projektionen usw. zu einer NodeTexture (?) ...naja, dann sollte man sich das vielleicht vorher überlegen.
[Weiter zum gleichen Punkt:]
Das Konzept bei ptex ist nicht wirklich ein 2D-Bild, sondern eine UV-Beziehung, sodass Sie auf einer komplexen Oberfläche malen / stempeln / projizieren können, ohne das Konzept / die Herausforderung, 2d in 3d zu übersetzen, was im Vergleich bestenfalls mathematisch ein Hack ist ( immer technisch mit Verzerrung zu kämpfen).
Ich weise nur darauf hin, dass ptex vor mehr als 20 Jahren mehr Sinn und Priorität hätte machen sollen und nicht als Erweiterung oder zweitklassiger Performer angesehen werden sollte, aber für mich ist es genau umgekehrt. Es sollte die alte ursprüngliche Art sein, deklarativ zu sagen, wie ein 2D-Bild in das einzig wahre, immer funktionierende Basissystem von ptex projiziert / gestempelt wird. Wie auch immer, nur um die Idee durchzusetzen, sollte es integriert werden, wenn nicht am besten, eine zentralere Rolle einzunehmen.
Danke für die Gelegenheit, tolle Vorschläge zu machen. Ich war so froh, dass der Ptex nach einer Spezifikation hergestellt wurde. Ich habe vor 10+ Jahren selbst daran gedacht, aber als Kind hatte ich keine Macht, neue Spezifikationen usw. zu definieren. Im Nachhinein hätte ich sehen sollen, dass ich vielleicht hätte versuchen können, einen Unterschied zu machen, anstatt die Rolle des Beobachters, die ich immer noch behaupte. Hier ist also ein Versuch, ein lange bestehendes Unrecht rückgängig zu machen.

Vielleicht kann jemand einen neuen Thread starten, wenn jemand mit einem tieferen Verständnis der aktuellen Methoden, die möglicherweise in Flux verfügbar sind, einen zutreffenderen Vorschlag machen kann, wie das in THREEjs funktionieren würde.
Nochmals vielen Dank für die Gelegenheit, gehört zu werden.

@MasterJames irgendwie off-topic... erstelle bitte einen neuen Thread?

Selbst wenn wir ein Bild hätten, damit "Textur" noch verwendet werden könnte, müssten alle Materialien neu geschrieben werden, da sie nicht mehr als einen UV-Offset / -Wiederholung unterstützen. Dies könnte sich natürlich ändern, würde aber wahrscheinlich die Komplexität erhöhen, da dann redundante Uniformen benötigt werden (wie oft möchten Sie mehr als einen Satz von Offsets / Wiederholungen, damit z Für das Web, wo Leistung an erster Stelle steht, ist der häufigste Anwendungsfall einer, bei dem es einen globalen Offset/Repeat gibt, der sich auf jede Karte auswirkt, und es macht nur Sinn, dass dies auf dem Material liegt, da es schließlich Teil der Materialarchitektur ist. Benutzerdefinierte Shader-Materialien können mit Randfällen gut umgehen.

@QuaziKb Ja . Das ist es, was NodeMaterial anpackt.

Ist es nicht so, dass Texture für jedes .clone() dieselbe OpenGL-Texturinstanz verwendet, oder übersehe ich etwas. Wird es tatsächlich für jeden Klon neu hochgeladen? Wenn das der Fall ist, dann ist dies ein _sehr_ ernstes Problem.

@evrimoztamur , ich glaube, es kopiert jedes Mal die Textur. Sie können mit WebGL Inspector überprüfen, was vor sich geht.

Ich habe versucht , jeden Ansatz habe ich versucht, einschließlich @sunag ‚einfiel s Abhilfe , aber nichts funktionierte. Aufgrund meiner Experimente, die keine Ergebnisse lieferten, und der obigen Diskussion habe ich mich umgesehen, wie andere Bibliotheken mit Sprite-Animationen umgehen. Ich fand Babylon.js der Sprite und SpriteManager API eine Lösung , die Caters auf meine speziellen Bedürfnisse zu sein. Es verarbeitet Sprite-Sheets, Offset und Wiederholung sowie Animationen. Vielleicht ist dies eine höhere Abstraktionsebene, als THREE.js bieten möchte, aber als Referenz könnte es einen Blick wert sein.

@rhys-vdw: Für ein aktuelles Projekt bin ich bei einer bastardisierten Version von MeshBasicMaterial gelandet:
https://gist.github.com/karimbeyrouti/790d2e1a8c0137b16bae

Wenn Sie die Karte einstellen, weist dies automatisch die Versatz- / Wiederholungsuniformen (die sich in verstecktem Material befinden) zu. Sie können sie ganz einfach separat einstellen - so müssen Sie vorerst keine Texturen klonen. (Arbeiten mit r73)

Ich habe gerade eine PR eingereicht, die dieses Problem ansprechen sollte, PR #8278

@WestLangley schrieb:

Ich glaube, es ist vernünftig anzunehmen, dass die folgenden Karten die gleichen Offset-/Wiederholungswerte haben:

Karte
specularMap
normaleKarte
BumpMap
alphaMap
aoMap (zukünftig)
glossMap (zukünftig)
DisplacementMap (Zukunft)

Nicht immer. Ich verwende derzeit unterschiedliche Wiederholungswerte für eine Karte und eine Bumpmap auf demselben Material (Asphalt), um die Tatsache zu verbergen, dass beide mit eher kleinen Kacheln gekachelt sind. Auf diese Weise muss ich keine große Textur generieren/haben. Es ist sehr bequem. :-)

EDIT: Nun, das dachte ich zumindest, ich hätte es getan. Der Trick wurde wahrscheinlich ignoriert. Und ich kann ähnliche Ergebnisse erzielen, indem ich Rauschen im Shader oder so hinzufüge. Die Matrix3-Demo von WestLangley ist cool.

Ich denke, dies löst das Problem von Instanzen mit unterschiedlichem UV in Sprite. Es ist möglich, vertex und pixel shader ändern und die gleiche Textur zu erhalten.

https://threejs.org/examples/#webgl_sprites_nodes

Es verwendet SpriteNodeMaterial und Mesh mit einem gemeinsamen PlaneBufferGeometry . Die Schnittstelle ist nicht für Sprite geeignet, funktioniert aber. Vielleicht kann es zu SpriteMesh , um eine Benutzeroberfläche

Dieser Thread ist für mich TL;DR. aber ich habe gerade diesen Code in r68 entdeckt (altes Projekt, ja):

        // uv repeat and offset setting priorities
        //  1. color map
        //  2. specular map
        //  3. normal map
        //  4. bump map
        //  5. alpha map

        var uvScaleMap;

        if ( material.map ) {

            uvScaleMap = material.map;

        } else if ( material.specularMap ) {

            uvScaleMap = material.specularMap;

        } else if ( material.normalMap ) {

            uvScaleMap = material.normalMap;

        } else if ( material.bumpMap ) {

            uvScaleMap = material.bumpMap;

        } else if ( material.alphaMap ) {

            uvScaleMap = material.alphaMap;

        }

        if ( uvScaleMap !== undefined ) {

            var offset = uvScaleMap.offset;
            var repeat = uvScaleMap.repeat;

            uniforms.offsetRepeat.value.set( offset.x, offset.y, repeat.x, repeat.y );

        }

also ja...

Wenn Sie eine grundlegende Änderung der Bibliothek vorschlagen, wie Sie sie hier vorgeschlagen haben, müssen Sie diese Änderung klar und überzeugend begründen

Ich habe versucht, auf diffusen und normalen Maps unterschiedliche Wiederholungen einzustellen und mir die Haare auszureißen, weil es nicht funktionierte. da API diese Einstellung in Textur platziert, dachte ich, ich könnte das tun. Also ja, wie wäre es, wenn ich meine Haare für überzeugende Argumente aufbewahre? dieses Ticket ist noch offen, 3js hat immer noch diese Einstellung für Texturen, und sie wird nur für eine der Texturen respektiert = dies ist tatsächlich bereits eine Einstellung pro Material.

Wenn Sie dies nicht dorthin verschieben, wo es hingehört, sagen Sie zumindest, dass es keine Auswirkungen auf die Dokumente hat?

@sunag Für PR:
https://github.com/mrdoob/three.js/pull/11531

Ein Problem, auf das ich gestoßen bin:
https://jsfiddle.net/f0j2v3s8/

Es scheint, als ob SpriteNodeMaterial Transparenz verloren geht, es gibt keine Kombination von Blending, die ich verwenden kann, um dieses Beispiel zum Laufen zu bringen.

Irgendwelche Ideen?

@karimbeyrouti schrieb:

Wenn Sie die Karte einstellen, weist dies automatisch die Versatz- / Wiederholungsuniformen (die sich in verstecktem Material befinden) zu. Sie können sie ganz einfach separat einstellen - so müssen Sie vorerst keine Texturen klonen. (Arbeiten mit r73)

Ich glaube, dies ist veraltet, da uniforms.offsetRepeat in uniforms.uvTransform (r88) geändert wurde.

In Bezug auf den Anwendungsfall 'Wiederverwendung eines Texturatlas mit mehreren Object3D-Instanzen' schlage ich einen einfachen Rundgang vor:

  1. speichere die UVs-Daten (Offset, Repeat) in einem Atlas-Json-Objekt;
  2. Hook das onBeforeRender\onAfterRender Funktionspaar von Object3D;
  3. Laden Sie im Vor-Render-Callback die UVs-Daten aus dem Atlas-Json-Objekt und legen Sie sie auf material.map fest;
  4. Setzen Sie es im After-Render-Callback zurück;

Es ergibt sich:

  1. nur eine Textur und ein Material, die von mehreren Objekten geteilt werden, es wird kein Klon benötigt und der info.memory.textures-Zähler wird nicht erhöht;
  2. aber trotzdem müssen alle anderen Karten (normal, ao, Verschiebung...) der gleichen UV-Übersetzung entsprechen;
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen