Three.js: Knotenmaterial

Erstellt am 3. Nov. 2015  ·  161Kommentare  ·  Quelle: mrdoob/three.js

Hi.

Ich begann mit der Entwicklung eines THREE.NodeMaterials, um die Materialunterschiede zwischen 3D-Autorensoftware in Einklang zu bringen. In SEA3D Studio gibt es Optionen zum Erstellen von Ebenen in Albedo mit Maske und verschiedenen Mischmodi, Rim-Shader und anderen, ohne benutzerdefinierten Shader-Code zu benötigen. Ich würde dies gerne mit Node-Shader zu Three.JS bringen.

Ich denke, dass MeshPhongMaterial, MeshPhysicalMaterial und andere problemlos auf NodeMaterial über eine Schnittstelle für Abwärtskompatibilität oder nur Proxy basieren können.

AKTUALISIERT
http://sunag.github.io/sea3d/Labs/Three.JS-NodeMaterial/webgl_materials_nodes.html
http://sunag.github.io/sea3d/Labs/Three.JS-NodeMaterial/webgl_postprocessing_nodes.html

Syntaxbeispiel für die Verwendung von UV1 oder UV2 für Textur:

var usesUv2 = true;
var isLightmap = false;

var t = new THREE.NodeTexture( texture, new THREE.NodeUV( usesUv2 ) );

var nodemat = new THREE.NodePhongMaterial();
if (isLightmap) nodemat.light = t;
else nodemat.color = t;
nodemat.build(); // build shader

Ich mache auch einen Editor, derzeit wäre dies die Schnittstelle. Farbe ist Albedo und transform ist die Scheitelpunktposition.
editor

Ich achte auch darauf, dass es in einer verzögerten Schattierung verwendet werden kann. Jetzt werde ich Reflexions- und Brechungseingaben erstellen.

Wird die Neuigkeiten an die PR weitergeben, Vorschläge, Tests und Verbesserungen sind willkommen :+1:

Enhancement

Hilfreichster Kommentar

Okay, der TS-Support ist mit der nächsten Version bereit R017 🙌

Alle 161 Kommentare

Interessant!

@sunag Wir sind sehr an so etwas interessiert. Wie kann ich helfen? Ich kann zumindest die Unterstützung für Standard hinzufügen.

Ich bin daran interessiert, ziemlich willkürliche Graphen zu erstellen, damit die Zwischenknoten auch Eingaben annehmen. Sie können also ein Diagramm haben, das wie folgt aussieht:

Eine Textur (tex1, uv1)
B-Textur (tex2, uv2)
C-Mischung (A, B, Modus)
D Rauschen (param1, param2)
E Mischung (C, D, Modus)

Verwenden Sie dann diesen letzten Knoten E als Eingabe für ein Material.

Es ist also sehr willkürlich und nicht nur auf Texturen beschränkt.

Mein Ziel wäre es, in den nächsten Wochen dabei zu helfen, dies zu schaffen, und wenn möglich, hoffentlich in der nächsten Woche oder so mit Ihnen zusammenzuarbeiten. Ich habe mir dies über die Shadergraph-Bibliothek hier angesehen: https://github.com/mrdoob/three.js/issues/7339 Aber ich finde, es direkt in ThreeJS zu erstellen. Wirklich jede Lösung ist gut, solange sie flexibel ist und funktioniert.

Ich lese gerade deinen Code durch, er ist recht schön gestaltet. Ich habe erste Rückmeldungen. Könnte ich eine PR mit Ihrem Code als Grundlage für die Zusammenarbeit starten?

(1) Ich würde das Material die Referenzen auflösen lassen. Im Grunde hätten Referenzen Namen, die sie in ihrem Material auflösen würden, und das Material würde einen Codeschnipsel zurückgeben, wie auf diese Daten zugegriffen werden kann. Dies würde es dem Material auch ermöglichen, zu wissen, welche Variablen (einheitlich/variierend) die Knoten verwenden, damit es entsprechend optimiert werden kann. Dies ermöglicht auch, dass verschiedene Materialien Referenzen unterschiedlich auflösen, wodurch die Knoten portierbarer werden, anstatt wissen zu müssen, wie die Materialien Dinge implementieren, insbesondere wenn es Unterschiede zwischen Fragment- und Vertex-Implementierungen gibt.

(2) Ich versuche, das GeometryContext-Objekt zu verwenden, das ich im Licht-Refactor erstellt habe. Es bietet konsistenten Zugriff auf viele der erforderlichen lokalen Variablen. Aber das kann natürlich durch das Material selbst gelöst werden.

(3) Ich habe UV nur eine weitere Referenz, die durch das Material aufgelöst wird. Und ich hätte, dass NodeTexture eigentlich einen Node-Input nehmen sollte, um so prozedural generierte UVs zu ermöglichen.

(4) Ich würde NodeCube, NodeTextureCube nennen, um mit dem Rest von Three.JS konsistent zu sein. Und ich würde die Logik entfernen, wie man die Strahlen tatsächlich ausführt. Aber ich mag die Idee von Standard-Cube-Maps, also würde ich die Umgebungsabfrage für specular oder diffus eigentlich nicht in den Knoten platzieren, sondern das im Basis-Phong-Material haben, und Sie können nur die für die Abfrage verwendete Normale steuern, oder die Das cubemap-Ergebnis selbst (dadurch kann es eine prozedural bestimmte Farbe sein.) Ist das sinnvoll? Ich hätte also das normale Pluggable im Material und die Würfeltextur Pluggable (abfragbar durch eine Richtung und Bias/Lod, und gibt eine Farbe zurück). Somit kann man der Strahlungskarte eine Würfeltextur und der Spiegelungskarte eine andere bereitstellen. Wir können true sampleCube mit der cubeToUV2 -Funktion von @tschw nur als Knotentausch austauschen.

(5) Ich würde versuchen, eine NodeFunction hinzuzufügen, die es ermöglicht, beliebige Funktionen mit Parametern als Ergänzung zu Ihrer NodeOp aufzurufen (oder vielleicht könnten sie auf irgendeine Weise zusammengeführt werden).

(6) Ich würde alle ausführlichen einzelnen Klassen NodeNormal, NodeTransform, NormalMap usw. loswerden und nur einige einfache Konstruktoren haben, die eine NodeReference mit einem Namen erstellen, der vom Material entsprechend aufgelöst wird. NodeReference konnte Uniformen, Variationen sowie berechnete Werte im Shader auflösen.

(7) Ich verstehe den Unterschied zwischen NodeEnvironment und NodeCube nicht. Ich denke, NodeEnvironment ist möglicherweise unvollständig?

(8) Es ist verwirrend, dass NodePhong nicht von NodeMaterial abgeleitet ist. Obwohl ich sehe, dass NodeMaterial von ShaderMaterial abgeleitet ist. Ich frage mich, ob Sie die direkte Ableitung von ShaderMaterial, GraphMaterial (oder NodeGraphMaterial) nennen würden, die sinnvoller wäre – da alle Knoten zusammen einen Graphen bilden und der Graph zum Material wird, nicht ein einzelner Knoten.

(9) Ich würde vielleicht eine etwas vielfältigere Terminologie vorschlagen. Ich würde den Wurzelknoten MaterialNode nennen, und man könnte daraus PhongMaterialNode ableiten. Ich habe Vector3Node, FloatNode usw., die von ValueNode abgeleitet sind - nicht unbedingt konstant, sondern nur ein Wert. So könnte man drei FloatNodes an einen Vector3Node weiterleiten. Ich denke, Sie können einen Helfer haben, der es ermöglicht, jede dieser eine Zeile oder so zu deklarieren, anstatt die 10 oder so derzeit.

(10) Ich würde den Namen "Node" vom Anfang der Klassennamen nach hinten verschieben, weil es im Rest des ThreeJS-Projekts so ist.

(11) Ich würde die neue MaterialNode-Klasse erstellen und sie würde mit einer Liste von Uniformen und Variationen initialisiert. Es wäre standardmäßig in der Lage, dies zu beheben und auch zu verfolgen, was es gelöst hat, damit man verfolgen kann, welche Funktionen benötigt werden. Man könnte daher im abgeleiteten PhongMaterialNode eine begrenzte Auflösung haben, die die Sonderfälle auflöst und sich auf die zugrunde liegende Klasse verlassen würde, um die einfachen (Variationen, Uniformen) zu erledigen.

(12) Ich bin irgendwie verwirrt zwischen dem Unterschied zwischen NodePhong und NodePhongMaterial. Mir war bisher nicht bewusst, dass es beides gibt.

(13) Es gibt Code wie diesen:

THREE.NodeGLPosition.prototype = Object.create( THREE.Node.prototype );
THREE.NodeGLPosition.prototype.constructor = THREE.NodeGLPosition;

THREE.NodeGL.prototype.generate = function( material, shader ) {

Aber über diesem Snippet haben Sie bereits generate für NodeGL und Sie haben keines für NodeGLPosition - daher denke ich, dass es sich um einen Copy-Paste-Edit-Fehler handelt.

(14) Ich würde NodeReflectUVW und NodeRefractVector loswerden und stattdessen einfach etwas machen, das man über eine Referenzauflösung aus dem Material anfordern kann. Die Berechnung eines Reflexionsvektors ist einfach. Ich habe es zu GeometryContext in meinen nicht zusammengeführten experimentellen ThreeJS-Zweigen hinzugefügt.

(15) Die Art und Weise, wie ich Reflexion und Brechung implementieren würde, wäre, sie als Farbeingaben auf dem Material zu haben. Man würde Refect, ReflectLOD und Refract, RefractLOD auf die einfache Weise auflösen, in der Sie jede Variable auflösen und sie dann in das eigene Texturwürfel-Äquivalent (prozedural oder SamplerCube-basiert) und dann die resultierende Farbe an Material übergeben. Hast du das so gemacht?

(16) Ich bin verwirrt über den Lichteingang - normalerweise hat man keine Lampen, die steckbar sind, sondern die Lichtparameter sind in der Lichtklasse vollständig definiert. Ich denke, Sie brauchen diese zusätzliche Flexibilität? Wie stellen Sie sich das vor.

@bhouston woow, vielen Dank für Ihr Feedback.
Ich brauche mehrere Beiträge, um zu antworten :)

Ich bin daran interessiert, ziemlich willkürliche Graphen zu erstellen, damit die Zwischenknoten auch Eingaben annehmen. Sie können also ein Diagramm haben, das wie folgt aussieht:
Eine Textur (tex1, uv1)
B-Textur (tex2, uv2)
C-Mischung (A, B, Modus)
D Rauschen (param1, param2)
E Mischung (C, D, Modus)

Derzeit ist die Syntax wie folgt. Uv1-Offset-Animationsbeispiel:
Ich denke, dass NodeMaterial zu MaterialNode und THREE.PhongMaterialNode Es wäre auch besser.

var uv2 = false;
var uv_offset = new THREE.NodeFloat(0);     
var uv = new THREE.NodeOperator( '+', new THREE.NodeUV( uv2 ), uv_offset);
var texture = new THREE.NodeTexture( imgTexture, uv );

nodematerial.color = t;

// onUpdate
uv_offset.number += .01;

Ich denke, die Reihenfolge mit Ihrem Vorschlag wird umgekehrt (Modus, A, B) zu (A, B, Modus). Ich bin gerade dabei, die Reflex Maps, Cubemap und andere zu erstellen...

Die Umgebung und Cubemap sind unvollständig.

Derzeit können die Bugs mehr passieren, weil der Formatkonverter noch nicht fertig ist. Dies ist durch Vektorkonvertierung verantwortlich. vec3 bis vec4 oder vec4 zum Beispiel.

https://github.com/sunag/sea3d/blob/gh-pages/Labs/Three.JS-NodeMaterial/index.html#L365

Eine Blend "Textur" zum Beispiel: (Ich habe diesen Code nicht getestet)
Es kann in einem THREE.NodeOperator implementiert werden

https://github.com/sunag/sea3d/blob/gh-pages/Labs/Three.JS-NodeMaterial/index.html#L1105

THREE.NodeBlend = function( a, b, mode ) {

    THREE.NodeInput.call( this, 'blend' );

    this.mode = mode;
    this.a = a;
    this.b = b;

};

THREE.NodeBlend.prototype = Object.create( THREE.NodeInput.prototype );
THREE.NodeBlend.prototype.constructor = THREE.NodeBlend;

THREE.NodeBlend.prototype.generate = function( material, shader, output ) {

    var a = this.a.build( material, shader, output );
    var b = this.b.build( material, shader, output );

    switch(this.mode)
    {
        case 'multiply':

            return this.format( '(' + a + '*' + b + ')', this.a.type, output);

            break;
    }

    return a;

};

.generate() ist für den Codegenerator verantwortlich. Die Calcs-Codes werden in einem Cache gespeichert, wenn Sie in mehr als einer Eingabe verwenden möchten, ohne die Leistung zu beeinträchtigen.

Trotzdem richte ich keine Zeiger oder Konstanten zur Optimierung ein...

Die Kompilierung erfolgt durch Propagation in build() für Vertex- und Fragmentcode.

Ich kann Sie als Mitarbeiter einsetzen? Wenn Sie den Code in irgendeiner Weise bearbeiten möchten, werde ich auch daran arbeiten.

Ich kann Sie als Mitarbeiter einsetzen? Wenn Sie den Code in irgendeiner Weise bearbeiten möchten, werde ich auch daran arbeiten.

Vielen Dank! Ich werde PRs für Sie erstellen, damit Sie die Änderungen genehmigen können.

Ich habe Sie (sowie @mrdoob , @WestLangley und @tschw) zu einem Nebenprojekt von mir hinzugefügt , das versucht, eine Reihe wiederverwendbarer Knoten und Materialdefinitionen zu definieren, die zwischen verschiedenen Renderings übertragbar sind. Es kann auf dieses von Ihnen erstellte Shader-Graphensystem abgebildet werden.

Ich glaube nicht, dass Sie auf das Repo achten müssen, auf das ich Ihnen gerade Zugriff gegeben habe, wenn Sie dies nicht möchten. Es ist das, was mich interessiert, darüber hinaus zu implementieren.

(2) Ich versuche, das GeometryContext-Objekt zu verwenden, das ich im Licht-Refactor erstellt habe. Es bietet konsistenten Zugriff auf viele der erforderlichen lokalen Variablen. Aber das kann natürlich durch das Material selbst gelöst werden.

Ich wünschte, die Lichter wären ein LightNode. Mein Anliegen ist es, den bereits für Three.JS entwickelten Code nutzbar zu machen.

(3) Ich habe UV nur eine weitere Referenz, die durch das Material aufgelöst wird. Und ich hätte, dass NodeTexture eigentlich einen Node-Input nehmen sollte, um so prozedural generierte UVs zu ermöglichen.

Sie können UV durch ein vec2 ersetzen, wäre es das?

(5) Ich würde versuchen, eine NodeFunction hinzuzufügen, die es ermöglicht, beliebige Funktionen mit Parametern als Ergänzung zu Ihrer NodeOp aufzurufen (oder vielleicht könnten sie auf irgendeine Weise zusammengeführt werden).

das wäre toll. hauptsächlich für einen BlendNode.

(6) Ich würde alle ausführlichen einzelnen Klassen NodeNormal, NodeTransform, NormalMap usw. loswerden und nur einige einfache Konstruktoren haben, die eine NodeReference mit einem Namen erstellen, der vom Material entsprechend aufgelöst wird. NodeReference konnte Uniformen, Variationen sowie berechnete Werte im Shader auflösen.

In diesem Gedankengang denke ich, dass der MaterialNode eine Basis von materiellem Phong und physischem Material sein könnte.

(7) Ich verstehe den Unterschied zwischen NodeEnvironment und NodeCube nicht. Ich denke, NodeEnvironment ist möglicherweise unvollständig?

Ich kann diese Nodes immer noch nicht fertigstellen.

(8) Es ist verwirrend, dass NodePhong nicht von NodeMaterial abgeleitet ist. Obwohl ich sehe, dass NodeMaterial von ShaderMaterial abgeleitet ist. Ich frage mich, ob Sie die direkte Ableitung von ShaderMaterial, GraphMaterial (oder NodeGraphMaterial) nennen würden, die sinnvoller wäre – da alle Knoten zusammen einen Graphen bilden und der Graph zum Material wird, nicht ein einzelner Knoten.

NodeMaterial wäre das Wurzelknotenmaterial, es ist notwendig, einen Knoten für Vertex und Fragment zu verwenden. NodePhong ist hibrid und NodePhongMaterial ist nur eine Proxy-Klasse. Diese kann dann zusammengeführt werden.

(9) Ich würde vielleicht eine etwas vielfältigere Terminologie vorschlagen. Ich würde den Wurzelknoten MaterialNode nennen, und man könnte daraus PhongMaterialNode ableiten. Ich habe Vector3Node, FloatNode usw., die von ValueNode abgeleitet sind - nicht unbedingt konstant, sondern nur ein Wert. So könnte man drei FloatNodes an einen Vector3Node weiterleiten. Ich denke, Sie können einen Helfer haben, der es ermöglicht, jede dieser eine Zeile oder so zu deklarieren, anstatt die 10 oder so derzeit.

Hört sich gut an.

(16) Ich bin verwirrt über den Lichteingang - normalerweise hat man keine Lampen, die steckbar sind, sondern die Lichtparameter sind in der Lichtklasse vollständig definiert. Ich denke, Sie brauchen diese zusätzliche Flexibilität? Wie stellen Sie sich das vor.

Dies wäre für die Lightmap oder einen möglichen LightNode.

Dies wäre für die Lightmap oder einen möglichen LightNode.

Ich mag die Idee einer steckbaren Lightmap, weil man die UVs dafür explizit definieren könnte. :)

@bhouston Behebt heute mehrere Korrekturen in dieser Datei:
https://github.com/sunag/sea3d/blob/gh-pages/Labs/Three.JS-NodeMaterial/three.node.js

Dies ist die Spielwiese, die ich erschaffe: Kunst: Texturen und Schaltflächen ist ein Drag-and-Drop, funktioniert nur in Chrom

http://sea3d.poonya.com/flow/

Tolles Zeug! Heiliger Strohsack! Es ist schön.

Wäre es möglich, den Code so zu teilen, dass ich auch dazu beitragen kann? Als öffentliche PR oder so?

Sie arbeiten hier mit dem Sea3D-Projekt, oder?

https://github.com/sunag/sea3d/tree/gh-pages/Labs/Three.JS-NodeMaterial

Also kann ich es einfach forken und anfangen, beizutragen? Würden Sie PRs akzeptieren? Wie können wir effektiv zusammenarbeiten.

Ich habe nicht gefragt, aber @mrdoob würde

Bestimmt!

Also kann ich es einfach forken und anfangen, beizutragen? Würden Sie PRs akzeptieren? Wie können wir effektiv zusammenarbeiten.

Ich denke natürlich, dass Ihre Hilfe großartig wäre. Ich muss auch andere Knotentypen wie Sättigung und Rauschen mitbringen, wie Sie es vorgeschlagen haben.

Sie arbeiten hier mit dem Sea3D-Projekt, oder?

Ich denke, wenn man eine PR für Three.JS mit Beispielen macht, ist dies alles definiert.

@mrdoob Was halten Sie von den Materialnamen THREE.MaterialNode oder THREE.NodeMaterial?

Es ist eine Art von Material, also sollte es THREE.NodeMaterial .

ein Rim-Shader-Beispiel
flow-rimshader-example

Beispiel für Flächenreflexion
flow-areareflection

Das ist so toll @sunag!

@bhouston danke! Denkst du, es wird schwierig, auf R74 umzurüsten?

Das ist eine sehr beeindruckende Arbeit! Erinnert mich an Shaderforge .

Bisher sehr gute Arbeit!

@sunag Es wird ein bisschen Arbeit, aber ich möchte helfen und die meisten großen strukturellen Änderungen im R74-Shader-Code sind meine Schuld. :)

sieht wunderschön aus und macht Spaß damit zu spielen: Darf ich zur Inspiration Blender3D Node Editor anbieten. Ich finde es super effizient, es gibt sogar einige großartige Videos zu PBR über das Knotensystem von Blender und welche Knoten am nützlichsten wären, um PBR von Grund auf neu zu erstellen:

https://www.youtube.com/playlist?list=PLlH00768JwqG4__RRtKACofTztc0Owys8

Es wird ein bisschen Arbeit sein, aber ich möchte helfen und die meisten großen strukturellen Änderungen im R74-Shader-Code sind meine Schuld. :)

@bhouston Wow. Mit den neuen r74-Änderungen war es viel sauberer. Ich habe den ersten Teil fertig gestellt, der noch StandardMaterial fehlt. Jedes Problem poste ich hier :) Danke
https://github.com/sunag/sea3d/commit/d544ad7993272348f8bbea2337cdceb52159a6a8

Eine andere Sache, die uns noch fehlt, ist die Refraktion. Ich verwende sehr gerne den Rendering-Puffer anstelle einer Cubemap RTT als Standard. Es wäre viel effizienter.

@GGAlanSmithee Ich habe einige Referenzen von ShaderFX, die ich ein großer Fan bin. Shader Forge und UE4 sind hauptsächlich auch großartige Referenzen. Danke!

@richardanaya Erstaunliche Videos. Danke!

@mrdoob In welchen Ordner empfehlen Sie diese Dateien
https://github.com/sunag/sea3d/tree/gh-pages/Labs/Three.JS-NodeMaterial/node

Ich würde immer noch empfehlen, dies als "Material Graph" oder im umgekehrten ThreeJS-Stil als "GraphMaterial" zu bezeichnen. Oder wenn Sie darauf bestehen, den Begriff "Node" zu verwenden, würde ich ihn "NodeBasedMaterial" nennen. Beide Namen machen deutlich, dass das Material Knoten enthält , anstatt selbst ein Knoten zu sein.

Ich würde immer noch empfehlen, dies als "Material Graph" oder im umgekehrten ThreeJS-Stil als "GraphMaterial" zu bezeichnen. Oder wenn Sie darauf bestehen, den Begriff "Node" zu verwenden, würde ich ihn "NodeBasedMaterial" nennen. Beide Namen machen deutlich, dass das Material Knoten enthält und nicht selbst ein Knoten ist.

Für mich sieht beides gut aus. Die Entscheidung überlasse ich @mrdoob was meint ihr?

Übrigens @sunag Ich würde nach Möglichkeit bei Cubemaps für Refraktionen bleiben, es ist einfacher und genauer. Ich denke, das machen fast alle anderen so und wir brauchen das RTT-Zeug auch für genaue Reflexionen. Ich denke, es muss nur ein schnelles Rendern mit 128^2 oder 256^2 sein.

Übrigens @sunag Ich würde nach Möglichkeit bei Cubemaps für Refraktionen bleiben, es ist einfacher und genauer. Ich denke, das machen fast alle anderen so und wir brauchen das RTT-Zeug auch für genaue Reflexionen. Ich denke, es muss nur ein schnelles Rendern mit 128^2 oder 256^2 sein.

Ja, wir können beides lassen. wäre eine Diskussion zwischen Leistung x Genauigkeit. Dennoch empfehle ich für die ebene Refraktion (Glas, Wasser) den Buffer anstelle einer CubeMap (für die meisten Fälle).

@mrdoob In welchen Ordner empfehlen Sie diese Dateien

Ich würde es für den Anfang in Beispiele setzen. Sobald es gut definiert ist, können wir es später nach src verschieben 😊

Ich würde immer noch empfehlen, dies als "Material Graph" oder im umgekehrten ThreeJS-Stil als "GraphMaterial" zu bezeichnen. Oder wenn Sie darauf bestehen, den Begriff "Node" zu verwenden, würde ich ihn "NodeBasedMaterial" nennen.

Für mich sieht beides gut aus. Die Entscheidung überlasse ich @mrdoob was meint ihr?

Ich mag NodeMaterial schon irgendwie... Vielleicht NodesMaterial ? NodeGraphMaterial ? @WestLangley irgendwelche Vorschläge?

Ich würde die aktuellen Knoten jedoch umbenennen... NodeColor , NodeFloat , NodeTexture , ... in ColorNode , FloatNode , TextureNode

http://sea3d.poonya.dev/flow/

Ich kann das nicht laden 😐

Ich würde es für den Anfang in Beispiele setzen. Sobald es gut definiert ist, können wir es später nach src verschieben :blush:

@mrdoob es wird toll.

Ich würde die aktuellen Knoten jedoch umbenennen ... NodeColor, NodeFloat, NodeTexture, ... in ColorNode, FloatNode, TextureNode

Ich werde es dann weiterleiten.

Dies ist die lokale URL :blush: , versuch das:
http://sea3d.poonya.com/flow/

@WestLangley irgendwelche Vorschläge?

Ich empfehle THREE.FlowMaterial .

Meine zweite Wahl wäre THREE.CustomMaterial .

Als völlig zufälliger Zuschauer. NodeMaterial klingt für mich sehr intuitiv, denn so heißen sie in Blender3D

Wenn @mrdoob NodeMaterial gefällt, können wir dabei bleiben. :)

NodeMaterial dann heißt es

Dieses Projekt ist großartig! Habe gerade die Demo auf Twitter gesehen und sie ist sehr beeindruckend.

Ich frage mich, ob die Knoten etwas sein sollten, das in Three core eingeht. Sie sind sehr implementierungsspezifisch. Auch ich baue einen Three.js-Shader-Graph-Editor (noch nicht veröffentlicht) für ShaderFrog.com, und die Lösung, die ich habe, besteht darin, einfach den GLSL-Code und alle benötigten Metadaten wie einheitliche Namen in eine kleine JSON-Datei zu exportieren und sie zu laden mit einer externen Laufzeitbibliothek

screen shot 2015-11-20 at 12 05 26 pm

Dieser Diagrammeditor kann mit vollständigen Shadern arbeiten, indem er ihren Quellcode analysiert, was bedeutet, dass keine speziellen Shader-Knotentypen erforderlich sind. Könnte dieser NodeMaterial-Typ auch vollständig außerhalb des Kerns von Three gehandhabt werden? Alles, was Sie wirklich ausgeben müssen, ist ein RawShaderMaterial damit jemand es in seinem eigenen Projekt verwenden kann.

Könnte dieser NodeMaterial-Typ auch vollständig außerhalb des Kerns von Three gehandhabt werden? Alles, was Sie wirklich ausgeben müssen, ist ein RawShaderMaterial, damit jemand es in seinem eigenen Projekt verwenden kann.

@DelvarWorld Hallo. Theoretisch ja, aber es ist noch sehr früh, einen guten Shader aus Raw zu machen. Zur Zeit ist besser mit einer ersten Schnittstelle. Es hilft auch, mit Skin / Morph und anderen nativen Komponenten von Three.JS kompatibel zu bleiben.

Ich dachte, ein kleines Problem zu bemerken:
In "Flow" springen die Konnektoren nicht auf die oberste Ebene, wenn Knoten übereinander gezogen werden.
Vielleicht wartet dieses Problem noch auf Ebenen oder so.

Ich frage mich, ob es eine Möglichkeit gibt, beide Ansätze zu vereinen? Ich interessiere mich für einen mehrschichtigen Shader und dafür benötigen Sie mehrere BSDFs, die zu einem Endergebnis beitragen. Das bedeutet, dass man das Schattierungsmodell mehr heraustrennen muss – im @sunag verbunden . Ich denke, wir sollten in eine Richtung gehen, in der kein Standard- oder Phong-Material angegeben werden muss, es könnte roh sein, wie es @DelvarWorld hat. Ich denke, wir können uns schrittweise dorthin bewegen, also ist @sunag ein guter Anfang.

Dies ist keine konkretisierte Antwort, aber vor einiger Zeit habe ich einen groben Vorschlag für ein portables Shader-Format erstellt, das Metadaten wie einheitliche Namen, ihre Typen, ihren Typ in Three.js usw. enthält. https://github.com /DelvarWorld/ShaderFrog-Runtime/blob/master/THREE_SHADER_FORMAT.md

Alles, was ein Shader wirklich braucht, um in einer realen Umgebung zu laufen, ist der rohe Shader-Quellcode (da die GPU ihn kompiliert) und der Einfachheit halber, welche Uniformen der Benutzer mit welchen Werten festlegen kann. Dieser grobe Vorschlag beinhaltet keine Idee, einen Shader programmgesteuert zu erstellen, es ist nur eine einfache Lieferung für GLSL und Metadaten. Es ist mit Three.js kompatibel, weil Sie es am Ende nur in ein RawShaderMaterial stecken müssen.

Derzeit gibt es keine Möglichkeit, Shader in Three.js portabel zu machen oder aus einer Anwendung zu exportieren, was mich auf die Idee brachte, einen Standard vorzuschlagen, und ich denke, er könnte unsere beiden Probleme lösen, da wir externe Anwendungen erstellen die am Ende ein vorgegebenes Material ausspucken. Dies bedeutet auch, dass die Implementierungsdetails zum Kompilieren bestimmter Kombinationen eines Graphen den Anwendungen überlassen werden, nicht Three.js.

Hat dieser vorgeschlagene Shader-Standard einen Platz in der Drei? Ich habe keine Ahnung. Im Moment ist es wahrscheinlich nützlicher für mich als für den Kern von Three, da Three seine eigenen Shader auf seine eigene Weise baut.

@DelvarWorld Ich habe dieses Projekt gestartet, um einen standardisierten Satz von Shader-Graph-Knoten zu erstellen:

https://github.com/OpenMaterialGraph/OpenMaterialGraph

Knotenspezifikationen hier:

https://github.com/OpenMaterialGraph/OpenMaterialGraph/tree/master/spec/nodes

Minimalistische BSDFs-Spezifikationen hier:

https://github.com/OpenMaterialGraph/OpenMaterialGraph/tree/master/spec/bsdfs

Dies ist jedoch auf physikalisch-basiertes Rendering ausgerichtet.

Mein Gefühl ist, dass man für ThreeJS eine Shader-Shell braucht, die ein höheres Level als ein Raw-Shader, aber ein niedrigeres Level als Phong-Shader hat. Grundsätzlich wäre der Standard-Shader in der Lage, Morph-Ziele, Bones usw. zu erstellen. Und dann würden all diese spezifischen Beleuchtungsschema-Shader (Basic, Lambert, Phong, Standard) diese Vorlage verwenden. Im Moment gibt es einen impliziten Template-Shader (wir fügen die gleichen Dinge in jeden Shader ein) - aber ich denke, wir könnten klarer machen, wo man Dinge einfügt. Sie können Beleuchtungsschemata (Phong, Lambert, Basic oder Multilayered) einfügen und Eigenschaften zu diesen Beleuchtungsschemata hinzufügen, die Ihre allgemeinen Knoten sind.

@bhouston oh nett, es sieht so aus, als hätten wir viele überlappende Anforderungen, auch bekannt als Standardwert, Anzeigename, für Menschen lesbare Beschreibungen usw. Ich weiß nicht, was die Zukunft bringt, aber es wäre eine mäßig einfache Änderung für mich, a zu verwenden Format eher wie das, was Sie vorschlagen.

Ein formales Shader-Format macht sehr viel Sinn. Es sollte jedoch mit der Lib leben, damit es sich leichter damit weiterentwickeln kann. Gibt es für jemanden, der mit Three.js noch ziemlich neu ist, einen bestimmten Grund, warum so etwas noch nicht existiert? Sollte zumindest für den Redakteur interessant sein.

*EDIT Vielleicht würde die Spezifikation in Three.js ihren Zweck verfehlen, wenn sie von anderen Rendering-Pipes verwendet werden soll.

Im Moment ist es wahrscheinlich nützlicher für mich als für den Kern von Three, da Three seine eigenen Shader auf seine eigene Weise baut.

Sie können dasselbe Material in einer anderen Sprache generieren, wenn Sie Änderungen in THREE.NodeGL.prototype.generate vornehmen, sobald ein NodeMaterial(*Flow) eine visuelle Sprache ist. Der NodeBuilder kann die Tür dazu sein. Derzeit ist der Vermittler von Daten zwischen Nodes.

Ich habe ein Beispiel von NodeMaterial "raw" bereinigt: Es kann immer noch mehrere Fehler generieren.
https://github.com/sunag/sea3d/blob/gh-pages/Labs/Three.JS-NodeMaterial/index.html#L179
https://github.com/sunag/sea3d/blob/gh-pages/Labs/Three.JS-NodeMaterial/node/NodeMaterial.js#L9

Ich denke, um dies mit Partikeln voranzutreiben, die Wurzelknoten erstellt haben. NodePass für Multi-Pass und NodeMaterialD nach der PR was soll ich in ein paar Tagen machen.

Ich habe einen THREE.ShaderFrogLoader anstelle eines Runtime-Shaders vorgeschlagen.

In "Flow" springen die Konnektoren nicht auf die oberste Ebene, wenn Knoten übereinander gezogen werden.

@MasterJames Danke! Ich werde es mir anschauen.

:+1:

Ich habe angefangen, die Beispiele zu erstellen. Ich hoffe, dass ich diese Woche fertig bin. :sweat_smile:
http://sunag.github.io/sea3d/Labs/Three.JS-NodeMaterial/webgl_materials_nodes.html

Die Gedanken?

@sunag +1

+1!

Das ist so toll. Ich würde eher die Pflanzen + Wandtextur als die wolkige Verschiebung verwenden. :) Das ist einfach schön.

Ich würde eher die Pflanzen + Wandtextur als die wolkige Verschiebung verwenden.

Sie beziehen sich auf das Beispiel "Schichten"? Aber ich werde noch mehr Beispiele für uns posten

GPU Soft-Body
soft-body

Zum Vergleich mit einem anderen Ansatz ist der Grafikeditor von Shader Frog jetzt live und befindet sich in der Phase "Kick the Tires". Ich möchte betonen, dass keine Änderungen am Three.js-Kern erforderlich sind.

ShaderFrog hat derzeit mehr Leistung als herkömmliche Node-Editoren. Es kann mit unendlich vielen Knotentypen arbeiten, da es jeden Shader analysieren und verstehen einen Glow-Shader nehmen , der ein vollständig eigenständiger Shader mit einem Fragment- und Vertex-Shader ist:

screen shot 2015-12-08 at 1 48 24 pm

...und mit einem Reflexions-Shader multiplizieren ...

screen shot 2015-12-08 at 1 49 39 pm

...mit dem Shader-Diagramm...

screen shot 2015-12-08 at 1 50 40 pm

Und ta-da! Ein Reflexions-Rim-Shader .

Sie können beispielsweise auch zwei beliebige Shader mit einem anderen Shader maskieren , und so weiter:

screen shot 2015-12-08 at 1 56 03 pm

Beachten Sie, dass der einzige von diesem Prozess benötigte "Knotentyp" ein Multiply-Knoten ist (es gibt andere in ShaderFrog), der fast vollständig unabhängig von GLSL ist. ShaderFrog kann mit allen Shadern arbeiten, weshalb es unendliche Knotentypen hat. Dieser fortschrittliche Technologieansatz ermöglicht diese Manipulation unabhängig von den Three.js-Änderungen.

ShaderFrog bietet eine erstklassige Exportunterstützung für Three.js, kostenlos. Alles ohne den Three.js-Quellcode zu ändern. Sea3D ist ein Drittanbieterprodukt wie ShaderFrog. Die Produktmechanik von Drittanbietern in den Kern von Three zu integrieren, scheint ein unfairer Vorteil zu sein und ich verstehe das politisch nicht.

@DelvarWorld Ich sehe eine knotenbasierte Shader-Konstruktionsabstraktion wirklich nicht als herstellerspezifische Technologie. Wenn überhaupt, ermöglicht es mehr Wettbewerbern, sich an der Node-basierten Shader-Technologie zu beteiligen und alle vom weiteren Nutzen der Arbeit des anderen zu profitieren (mehr Nodes, optimierte Konstruktion usw.).

Als Grafikprogrammierer wie ich, der Shader auf hohem Niveau versteht (von Tools wie Blender 3D), aber nicht auf niedrigem Niveau, scheint mir die knotenbasierte Abstraktion eine großartige Möglichkeit zu sein, mit meinen 3D-Modellierungskenntnissen programmgesteuert mit Shadern zu interagieren. Ich verstehe zum Beispiel das Node-Setup für PBR, aber Gott helfe mir, wenn ich das jemals in GLSL schreiben wollte.

@DelvarWorld Erstaunlich. Ich liebe den neuen Editor.

@DelvarWorld +1 Sehr schön! :-)

Vielen Dank! :)

Ich sehe eine knotenbasierte Shader-Konstruktionsabstraktion wirklich nicht als herstellerspezifische Technologie.

Ich verstehe zum Beispiel die Knoteneinrichtung für PBR

Ein Teil meines Gegenbeispiels hier ist, dass Sie diese beiden Dinge unabhängig von Three.js kostenlos erhalten können. Alle ShaderFrog-Shader sind Open Source, sodass alle Nodes, die Teil einer PBR-Implementierung werden, im Laufe der Zeit auch von ihnen gelernt, bearbeitet und verbessert werden können (sowie mit anderen Shadern komponiert werden können, nicht nur mit einer Teilmenge im Three.js-Kern). Für mich bedeutet die Tatsache, dass all dies ohne Three-Änderungen erreicht werden kann, dass dies unnötig ist und die Grenze zwischen Three.js als webgl-Wrapper-API und jetzt implementierungsspezifischen Funktionen verwischt. Das Speichern von Shader-Node-Daten ist sehr App-spezifisch und meines Wissens gibt es derzeit kein gemeinsames Node-Editor-Standardformat für jede Software? Das Erzwingen eines kann für andere Implementierungen schädlich sein.

@DelvarWorld Soweit ich diese Änderung verstehe, wird ShaderFrog weiterhin funktionieren und auf Wunsch auch weiterhin über GraphMaterial hinausgehen können. Ich habe mir den Beispielquellcode für GraphMaterial angesehen und konnte die Einfachheit seiner Funktionsweise verstehen, ohne auch nur an eine Lösung/einen Editor eines Drittanbieters denken zu müssen. Als Grafikentwickler beschäftige ich mich damit, wie man programmgesteuert Materialien erstellt, die schnell beeindrucken. Ich glaube, dass diese ein echtes Anliegen von ThreeJS sind.

Ich denke, dass NodeMaterial und Flow zwei unterschiedliche Schwerpunkte haben. Flow und ShaderFrog sind beides visuelle Editoren von Drittanbietern, derzeit in Closed Source (ich denke hauptsächlich bei Künstlern dafür). Ich stimme @richardanaya in dem Sinne zu, dass ShaderFrog auf Wunsch über NodeMaterial hinausgehen kann. So wie ich denke, dass Flow nicht nur ein Materialeditor sein muss. Ich hoffe sehr, dass ShaderFrog in Zukunft wie gewohnt große Verbesserungen erzielen wird.

wip: ätzend-voronoi
http://sunag.github.io/sea3d/Labs/Three.JS-NodeMaterial/webgl_materials_nodes.html
caustic

@sunag Ich habe heute Abend deinen Quellcode durchgesehen. Ich liebe es wirklich. Ein kurzes Feedback zu meinen Lesungen heute Abend:

  • Ich möchte lieber früher als später eine PR sehen. Ich kann helfen. :)
  • Es kann cool sein, beliebige Attribute zuzulassen, anstatt nur die Standardattribute (uv, uv2, normal, position usw.). Ich weiß, dass viele Shader von den Tangenten vec4s profitieren können, mehr als nur 2 uvs und auch mehrere Farben Attribute. Daher würde ich die NeedsPosition in ein RequestedAttributes-Array oder so verallgemeinern.
  • Ich würde vorschlagen, die Knoten in das Haupt-NodeMaterial, die BRDFs (Phong, Standard usw.), Texturknoten (NodeCubeTexture, NodeTexture), Accessor-(?)-Knoten (NodePosition, NodeNormal), mathematische Knoten (NodeOperator usw.) ), Utility-Knoten (NodeSwitch, ...) und zusätzliche (?) (NodeVelocity, ...) Ich denke, das würde sehr helfen.
  • Es wäre schön, Matrix-Accessoren für Projektions-, Ansichts- und Weltmatrizen zu haben.
  • Ihnen fehlen einige der Operatoren: % ^ & << >> ~ |
  • Ich bin mir nicht sicher, ob ich den Wert in NodePhongMaterial sehe, wenn die Klasse so klein ist mehr Natur für mich, aber ich kann damit leben.)
  • Ich würde NodeTimer -> NodeTime nennen ... aber wieder persönliche Präferenz.
  • Ich frage mich, ob es eine Möglichkeit gibt, viele der variablen Knoten zu einem zu kombinieren, wie Sie es mit NodeMath#, NodeOperator getan haben. Diese scheinen so ähnlich zu sein: NodeViewPosition, NodeWorldPosition, NodeViewNormal, NodeTransformedNormal, NodeTransformedPosition, NodeProjectPosition...
  • Ich möchte, dass der Satz optionaler Argumente für NodeMath#, NodeOperator in einer Form vorliegt, die eine Liste sein kann, damit man damit problemlos eine Dropdown-Box füllen kann. Da es sich im Moment um Mitglieder handelt, die nur die Klassen großgeschrieben haben, ist es etwas schwieriger, sie zu identifizieren. Ich bin mir nicht sicher, ob es eine gute Lösung gibt, die noch bequem zum Codieren ist. Vielleicht einfach nach ihrer Definition als Mitglieder der Klasse in einer Liste zusammenfassen, also einfach diese Listen hinzufügen?
  • NodeTransformedNormal, NodeTransformedPosition sind für mich schwer herauszufinden, was sie sind, ohne den Code zu betrachten. Sind sie im Weltraum, Sichtraum, Objektraum? "Transformiert" ist ein sehr allgemeiner Begriff, der einfach mit einer Matrix multipliziert bedeutet. Ich schaue mir jetzt den Code für sie an....
  • Ich würde NodeUV und NodeColor erlauben, einen Index zu verwenden, anstatt auf 2 bzw. 1 Kanal beschränkt zu sein. Auch hier würde ich gerne sehen, dass diese generisch gemacht werden, wirklich Sie übergeben einen String oder eines von mehreren Presets, anstatt es fest auf einen Satz spezifischer Kanäle zu kodieren. Sie können immer noch einige dedizierte Codepfade für einige Variablen haben, aber es würde auf etwas Generisches für Namen zurückgreifen, die es für die Behandlung von Sonderfällen nicht erkennt.

Weitere Rückmeldungen:

  • Ich möchte einen Graphen mit mehr als einem BRDF haben, im Grunde zwei Standard-BRDF und dann die Energieeinsparung zwischen ihnen durchführen. Sobald Sie die PR erhalten haben, möchte ich diese Funktionalität hinzufügen. Dadurch wird das System generischer und leistungsfähiger.

@bhouston Wow! Dankeschön!

Die Anforderungsattribute, Ordnerorganisation, NodeTime, NodePosition, NodeNormal, NodeView wurden überarbeitet. +3 Beispiele hinzugefügt.

in Operatoren und Matrix müssen wir Kompatibilität mit integer und matrix Konvertierungen hinzufügen. Dies geschieht automatisch wie in float / vectors#. Wir haben genug Arbeit für die nächsten Updates.. :sweat_smile:

Morgen mache ich die PR. Einiges muss ich noch rezensieren.

@sunag :

Ich glaube das ist ein Bug:

addGui( 'metalnessA', roughnessA.number, function( val ) {

                        roughnessA.number = val;

                    }, false, 0, 1 );

Ich glaube das ist ein Bug:

Vielen Dank!

Ich wurde gerade schwindlig, als ich auf die Beispielseite ging und ein PBR-Knotendiagramm <3 . sah

Nizza!

Ich wollte vorschlagen, die Knoten für die Nachbearbeitung zu verwenden, aber ich wartete darauf, dass der erste Teil fertig war. Verdammt, das ist schön!

NodeMaterial Rev. 5 + LightNode

http://sunag.github.io/sea3d/Labs/Three.JS-NodeMaterial/webgl_materials_nodes.html

Haut
nodematerial-rev5-skin

Toon-Schattierung
nodematerial-rev5-toon

++ color-adjustment und plush Beispiele.

Niice!

subsurface scattering :sweat_smile:

Dies ist eine Art Shader, der in zukünftigen Updates funktionieren kann.

http://sunag.github.io/sea3d/Labs/Three.JS-NodeMaterial/webgl_materials_nodes.html

sss-img1
sss-img2

!

Danke für tolles NodeMaterial!

Ich habe mehrere Kommentare/Fehler:

  • nachfolgendes Leerzeichen umbricht den Funktionsknoten
var n1 = new THREE.FunctionNode(" float mul_2_float(float x) { return x*2.0; }"); // problem
var n2 = new THREE.FunctionNode("float mul_2_float(float x) { return x*2.0; }"); // ok
  • Problem mit dem Parameter int im Funktionsknoten

Arbeitsbeispiel mit float-Parameter:

var floatFuncNode= new THREE.FunctionNode("float mul_2_float(float x) { return x*2.0; }");

var funcCallNode = new THREE.FunctionCallNode(floatFuncNode);
funcCallNode.inputs.x = new THREE.FloatNode(0.2);

var colorResNode = new THREE.OperatorNode(new THREE.ColorNode(0x00ff00),
    funcCallNode, THREE.OperatorNode.MUL);

var mat = new THREE.PhongNodeMaterial();
mat.color = colorResNode;

defektes Beispiel mit int-Parameter:

var intFuncNode= new THREE.FunctionNode("float mul_2_int(int x) { return float(x)*2.0; }");

var funcCallNode = new THREE.FunctionCallNode(intFuncNode);
funcCallNode.inputs.x = new THREE.IntNode(1);

var colorResNode = new THREE.OperatorNode(new THREE.ColorNode(0x00ff00),
    funcCallNode, THREE.OperatorNode.MUL);

var mat = new THREE.PhongNodeMaterial();
mat.color = colorResNode;
  • Vorschlag: Funktionsparameter im FunctionCallNode-Konstruktor übergeben
//current:
var funcCallNode = new THREE.FunctionCallNode(floatFuncNode);
funcCallNode.inputs.param1 = new THREE.FloatNode(1);
funcCallNode.inputs.param2 = new THREE.ColorNode(0x0f0f0f);

// proposed:
var funcCallNode = new THREE.FunctionCallNode(floatFuncNode, 
    { param1: new THREE.FloatNode(1), param2: new THREE.ColorNode(0x0f0f0f) } );

// and, i think suitable in some cases: 
var funcCallNode = new THREE.FunctionCallNode(floatFuncNode, 
    [ new THREE.FloatNode(1), new THREE.ColorNode(0x0f0f0f) ] );
  • Ist PhongNodeMaterial mit Bump-Map kompatibel?

noch ein paar Anmerkungen:

  • Problem mit PositionNode.LOCAL im Fragmentshader in "rohem" NodeMaterial:
var material = new THREE.NodeMaterial(
        new THREE.RawNode( new THREE.PositionNode( THREE.PositionNode.PROJECTION ) ),
        new THREE.RawNode( new THREE.PositionNode( THREE.PositionNode.LOCAL ) )
    );

resultierende Shader:

varying vec3 vPosition;
void main(){
gl_Position = (projectionMatrix * modelViewMatrix * vec4( position, 1.0 ));
vPosition = transformed;
}
varying vec3 vPosition;
void main(){
gl_FragColor = vec4(vPosition,0.0);
}

Wahrscheinlich sollte die "transformierte" Funktionalität von Phong/Standart-Knotenmaterialien nach NodeMaterial verschoben werden

  • ConstNode-Nutzung
    var material = new THREE.NodeMaterial(
        new THREE.RawNode( 
            new THREE.OperatorNode(
                new THREE.PositionNode( THREE.PositionNode.PROJECTION ),
                new THREE.ConstNode("float TWO = 2.0;"),
                THREE.OperatorNode.MUL)
            ),
        new THREE.RawNode( new THREE.ColorNode( 0xff0000 ) )
    );

In diesem Fall enthält der Ergebnisshader
gl_Position = ((projectionMatrix * modelViewMatrix * vec4( position, 1.0 ))*TWO);
aber ZWEI Konstante ist nicht deklariert. Ist es mein Fehler oder Bug?
Außerdem ist ConstNode semikolonsensitiv, sodass "float TWO = 2.0" nicht geparst wird.

Danke @dimarudol ! Wenn Sie sich mit den Notizen so schnell wie möglich frei fühlen möchten, wird die neue Überarbeitung vorgenommen.

aber ZWEI Konstante ist nicht deklariert. Ist es mein Fehler oder Bug?

Ich werde diese Art der Verwendung und im Material zum Beispiel berücksichtigen material.include( node )

Versuchen Sie zu diesem Zeitpunkt eine globale Konstante:

var TWO = new THREE.ConstNode("float TWO = 2.0;");
THREE.NodeLib.add( TWO ); // global

 var material = new THREE.NodeMaterial(
        new THREE.RawNode( 
            new THREE.OperatorNode(
                new THREE.PositionNode( THREE.PositionNode.PROJECTION ),
                TWO,
                THREE.OperatorNode.MUL)
            ),
        new THREE.RawNode( new THREE.ColorNode( 0xff0000 ) )
    );

Hallo @sunag , ich habe mit Sea3d Flow gespielt und es sieht ziemlich cool aus. Wollte nur fragen, ob es dafür irgendwo ein offizielles Repo gibt.
Grüße.

Hallo @rraallvv , noch nicht, es soll schon fertig sein. So schnell wie möglich poste ich die Neuigkeiten.

Danke @sunag , das

Hallo @sunag ! Du hast wirklich gute Arbeit geleistet!
Ich habe eine Frage: Für mein Projekt wäre es großartig, Ihre Knotenstruktur zu verwenden, aber ich brauche pro Vertex-Farbe (und benutzerdefinierte pro Vertex-Float-Werte), aber in Ihrem Knotensystem haben Sie nur colorNode und floatNode auf das gesamte Netz angewendet .. Glauben Sie, dass es eine Möglichkeit gibt, so etwas wie einen bufferColorNode (mit THREE.BufferAttribute) einfach zu implementieren?

Ich habe zum Beispiel diese Szene:

screenshot from 2016-08-31 16 27 06

Jeder Scheitelpunkt hat seine eigene Farbe. Dies ist mit THREE.BufferAttribute und einem THREE.ShaderMaterial möglich, aber es gibt kein Äquivalent in Ihrem Code.

Ich bräuchte sowas wie:
`let material = new THREE.StandardNodeMaterial();
let texColorMap = new THREE.TextureNode( new THREE.TextureLoader().load("colorMap.jpg"));
let customData = new THREE.BufferFloatNode(new Float32Array(...), "data"); // Der zweite Parameter ist der Name des Attributs

let colorMap = new THREE.FunctionNode([
"vec3 colorMap(sampler2D texColorMap, Float-Daten){",
" return vec3(texture2D(texColorMap, customFunc(data)));", // customFunc gibt je nach Daten ein vec2 zurück
"}"
].join("n"));

let colorMapCall = new THREE.FunctionCallNode(colorMap);
colorMapCall.inputs.texColorMap = texColorMap;

material.color = colorMapCall;
material.build();`

Übrigens, es scheint, als ob ich keine Sampler2D-Parameter für den FunctionNode verwenden kann ...

Verpasse ich etwas?
Ich denke, ich könnte helfen, wenn es nötig ist :)

@martinRenou Danke! Hmm, vielleicht sowas wie jetzt:

bufferGeometry.addAttribute( 'color', new THREE.BufferAttribute( colors, 4 ) );
...
colorMapCall.inputs.data = new THREE.ColorsNode(); // send color.x to float slot

Ich hatte noch nicht daran gedacht, dem Knoten ein dynamisches Geometrieattribut zuzuweisen. Aber ich denke, das ist eine gute Idee ... vielleicht so etwas wie THREE.BufferAttributeNode ...

@sunag danke für deine Antwort :)
Ich werde das versuchen. Wenn es für Sie in Ordnung ist, werde ich mit der Arbeit an einem THREE.BufferAttributeNode beginnen, im Moment lese ich noch Ihren Code und versuche, die Struktur zu verstehen.

  1. Was THREE.FunctionNode betrifft, muss ich, wie gesagt, wirklich einen Sampler2D in meinen Parametern setzen, da er als ColorMap verwendet wird. Die Pixelfarbe wird mit texture2D() berechnet und der zweite Parameter von texture2D() wird mit meinen benutzerdefinierten Daten berechnet (das ist zum Beispiel eine Temperatur).
    Ich verstehe, dass die Idee der Verwendung von vec3-Parametern der Benutzerfreundlichkeit diente, aber FunctionNode könnte auch Sampler2D-Parameter unterstützen, meinen Sie nicht?
  2. Außerdem schreiben THREE.FunctionNode nur im Fragment-Shader, aber wäre es nicht schön, auch im Vertex-Shader schreiben zu können?

Dies wäre mein Anwendungsfall, es heißt IsoColor, weil die Farbe einem Datenwert entspricht (Temperatur, Druck ...) rot -> hohe Temperatur, blau -> niedrige Temperatur:
screenshot from 2016-09-01 17 29 58

  1. Ich denke darüber nach, einen THREE.IsoColorNode (der den FunctionNode meines Diagramms ersetzen würde) und andere Knoten zu schreiben, die für wissenschaftliche Visualisierungen sehr interessant wären. Bist du daran interessiert ? @mrdoob würde dich das auch interessieren?

Was THREE.FunctionNode betrifft, muss ich, wie gesagt, wirklich einen Sampler2D in meinen Parametern setzen, da er als ColorMap verwendet wird. Die Pixelfarbe wird mit texture2D() berechnet und der zweite Parameter von texture2D() wird mit meinen benutzerdefinierten Daten berechnet (das ist zum Beispiel eine Temperatur). Ich verstehe, dass die Idee der Verwendung von vec3-Parametern der Benutzerfreundlichkeit diente, aber FunctionNode könnte auch Sampler2D-Parameter unterstützen, meinen Sie nicht?

Ich verstehe dein Bedürfnis jetzt! Ich werde für diese und andere Notizen des @dimarudol eine PR

Außerdem schreiben THREE.FunctionNode nur im Fragment-Shader, aber wäre es nicht schön, auch im Vertex-Shader schreiben zu können?

Ich habe das nicht getestet, aber ich nehme an.

Ich habe noch zwei Beispiele hinzugefügt:

  • sampler2D sind in triangle-blur Beispiel
  • benutzerdefinierte BufferAttribute sind in custom-attribute Beispiel

Es funktioniert, aber ich werde immer noch einen polierten Code geben ...

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

Beeindruckend ! Das hast du wirklich gut gemacht, bei mir funktioniert es auch :smile:

Nochmals vielen Dank für Ihre Arbeit!

Hallo @sunag ,

Im Moment können wir keinen FunctionNode mit dem Typ "void" haben, da wir ihn als Parameter (Farbe, Alpha...) an das Material senden müssen. Wenn ich zum Beispiel einen Clip Plane FunctionNode implementieren möchte, möchte ich nur einen Shader-Teil wie diesen schreiben:

void clipPlane(vec4 plane){
 if(dot(position, plane.xyz) > plane.w) discard;
}

Aber das kann man dem Material nicht geben... Eine Lösung wäre, einen Schwimmer zurückzugeben, der Alphakanal ist, aber das ist nicht sauber und optimiert. Denken Sie nicht, dass es cool wäre, einem Material wie diesem einige void-Funktionen hinzuzufügen:

var clipPlane = new FunctionNode([
"void clipPlane(vec 4 plane){",
" if (dot(position, plane.xyz) > plane.w) discard;",
"}"].join("\n"));
var clipPlaneCall = new FunctionCallNode(clipPlane);
clipPlaneCall.inputs.plane = myVec4Node;

var threshold = new FunctionNode([
"void threshold(float upperBound, float lowerBound, float data){",
" if(data < lowerBound) discard;",
" if(data > upperBound) discard;",
"}"].join("\n"));
var thresholdCall = new FunctionCallNode(threshold);
thresholdCall.inputs.upperBound = myFloatNode1;
thresholdCall.inputs.lowerBound = myFloatNode2;
thresholdCall.inputs.data = myAttributeNode;

var myMaterial = new StandardNodeMaterial();
myMaterial.color = ...
myMaterial.alpha = ...

// voidFunctions is not a good name I'm not inspired...
myMaterial.voidFunctions = [clipPlaneCall, thresholdCall];

Für ein mehr "Design" -Beispiel, wenn ich mit dieser Textur Löcher in meine Teekanne machen möchte:
wood-hole-texture
Ich möchte so etwas machen:

var holes = new FunctionNode([
"void holes(vec3 texColor){",
" if (/*texColor too much dark*/) discard;",
"}"].join("\n"));
var holesCall = new FunctionCallNode(holes);
holesCall.inputs.texColor = new TextureNode(LoadTexture("holes-text.jpg"));

var myMaterial = new StandardNodeMaterial();
myMaterial.voidFunctions = [holesCall];
myMaterial.side = THREE.DoubleSide;

Eine andere Sache ist, dass wir keine Kontrolle über die Reihenfolge der Funktionen in Shadern haben. Wenn ich Funktionen habe, die nicht kommutativ sind, habe ich keine Kontrolle über das Ergebnis...

Sehen Sie sich dieses Beispiel an:

var transparencyPlane = new FunctionNode([
"float transparencyPlane(vec 4 plane){",
" if (dot(position, plane.xyz) > plane.w) return 0.5.;",
" return 1.;",
"}"].join("\n"));
var transparencyPlaneCall = new FunctionCallNode(transparencyPlane);
transparencyPlaneCall.inputs.plane = myVec4Node;

var displacement = new FunctionNode([
"vec3 displacement(vec3 vector){",
" return position + vector;",
"}"].join("\n"));
var displacementCall = new FunctionCallNode(displacement);
displacementCall.inputs.vector = myVec3Node;

var myMaterial = new StandardNodeMaterial();
myMaterial.transform = displacementCall;
myMaterial.alpha = transparencyPlaneCall;

Befindet sich ein Punkt hinter der Transparenzebene und kommt durch die Verschiebung darüber hinaus, wird bei "transparencyPlaneCall" vor "displacementCall" alpha = 1 aufgerufen, bei einem Aufruf nach alpha = 0,5.
Also würde ich gerne die Reihenfolge der Funktionsaufrufe festlegen... Wissen Sie, was ich meine?

Hallo @martinRenou

Hmm, ungefähr void funktioniert vielleicht ein ProxyNode , das im Slot verwendet werden muss, weil dies einer Reihenfolge folgen oder am Anfang oder Ende des Codes initialisieren muss, vielleicht functionsStart oder functionsEnd Slots...

Wenn alpha Slot verwendet wird, wenn alpha 0 ist, wird automatisch verworfen.
https://github.com/mrdoob/three.js/blob/dev/examples/js/nodes/materials/PhongNode.js#L180

Ich möchte also die Reihenfolge der Funktionsaufrufe festlegen...

Existieren Sie eine Sequenz siehe hier:
https://github.com/mrdoob/three.js/blob/dev/examples/js/nodes/materials/PhongNode.js#L122

Die Funktionsreihenfolge wird automatisch mit dem einfachen dependencies Algorithmus durchgeführt, sollte FunctionCall in einen vorherigen Slot setzen, color ist zum Beispiel der erste specular ist der zweite.

Dieses Beispiel sind zwei verschiedene Shader-Codes: fragment bis transparencyPlaneCall und vertex bis displacementCall .

Es lässt mich denken, dass es sehr interessant sein wird, Variablen ( varying und Locals) zu verwenden, um nicht Eingaben und nur const zu erweitern. Vielleicht ein VarNode ...

Die Verwendung des Alpha-Slots, wenn Alpha 0 ist, wird automatisch verworfen.

Sorry dafür, habe es nicht gesehen.

Die Funktionsreihenfolge wird automatisch mit einem einfachen Abhängigkeitsalgorithmus durchgeführt, sollte der FunctionCall in einen vorherigen Slot gelegt werden, ist die Farbe zum Beispiel zuerst spiegelnd an zweiter Stelle.

Ich verstehe, eigentlich wollte ich nur sichergehen, dass die Funktion, die Pixel verwerfen zuerst aufgerufen wurde. Klingt gut für mich, Alpha zu verwenden, wenn Sie es gleich nach meinen Funktionen verwerfen :smiley:

Dieses Beispiel sind zwei verschiedene Shader-Codes: fragment totransparencyPlaneCall und Vertex to DisplacementCall.

Rechts ! Das war also kein gutes Beispiel. Mein Fehler.

Fertig r6 - #9636

Cool ! Danke für deine Antworten.

Es lässt mich denken, dass es sehr interessant sein wird, Variablen (variierend und lokal) zu verwenden, um nicht Eingaben und nur const zu erweitern. Vielleicht ein VarNode...

Klingt auch gut, es könnte interessant sein, eine Funktion im Vertex-Shader explizit schreiben zu können, einen varNode zu verwenden und ihn mit einer Funktion im Fragment-Shader zu verwenden. Meinst du nicht?

@sunag
Ich denke, es gibt ein Problem mit der Verwendung von AttributeNode mit FunctionNode im Vertex-Shader.

Wenn ich so einen Code habe:

var customData = new THREE.AttributeNode("data", "float");

var myFunc = new THREE.FunctionNode([
 "vec3 myFunc(float data){",
 " return vec3(data, 0., 0.);"
 "}"].join("\n"));
var myFuncCall = new THREE.FunctionCallNode(myFunc);
myFuncCall.inputs.data = customData;

material.transform = myFuncCall;

Der Shader wird in dieser Reihenfolge geschrieben:

...
varying float nVdata;
attribute float data;
...
float myFunc(float data){
 return return vec3(data, 0., 0.);
}

void main(){
...
transformed = myFunc(nVdata); // We use nVdata but it is not initialized
...
nVdata = data;
...
}

Eine einfache Lösung wäre, nVdata mit Daten zu initialisieren?

Klingt auch gut, es könnte interessant sein, eine Funktion im Vertex-Shader explizit schreiben zu können, einen varNode zu verwenden und ihn mit einer Funktion im Fragment-Shader zu verwenden. Meinst du nicht?

Ja! Die Idee ist eine bessere Kommunikation mit Vertex-/Fragment-Shadern, die varying als VarNode . Das passt jetzt hervorragend mit der keywords Funktion.

Ich erstelle ein minimales varying Beispiel, aber es gibt noch keine Lösung für void function .

Ich denke, es gibt ein Problem mit der Verwendung von AttributeNode mit FunctionNode im Vertex-Shader.

Behoben – https://github.com/mrdoob/three.js/pull/9681

Hallo @sunag , ich habe dein variierendes Beispiel gesehen, und es klingt komisch für mich, das Variierende in mtl.transform wie du es getan hast ... Vielleicht ändern Sie dies, wenn es möglich ist, void-Funktionen zu erstellen?
Klingt jedoch nach einer guten Idee, dass Keywords :smiley:

Tatsächlich denke ich, dass es eine gute Idee wäre, diese Variationen in mtl.varyings (mtl.variings ist ein Array) wie folgt zu platzieren: mtl.varyings.push(myVar) . Mit der gleichen Idee könnten wir Funktionen wie folgt in Vertex- und Fragment-Shader einfügen: mtl.vertexFunctions.push(myVertexFunctionCall) , genauso wie mtl.fragmentFunctions .

Auf diese Weise könnten wir viele Berechnungen an diesen Variationen durchführen und sie dann für Effekte verwenden. Diese Funktionen wären Leerfunktionen.

Wie in den obigen Screenshots, in denen Knoten visuell verbunden sind, wie können wir dies mit dieser API mental neu erstellen? Ich sehe, dass Konstruktoren andere Knoten akzeptieren. Ist das die Art und Weise, wie die Ausgabe von einem Knoten (die an einen Konstruktor übergeben wird) für einen anderen Knoten eingegeben wird (er empfängt die Knoten in seinem Konstruktor)? Hat ein Knoten höchstens einen Ausgang? Wie viele Knoten können über den Konstruktor in einen anderen Knoten eingegeben werden, oder ist dies begrenzt?

@trusktr Ist natürlich begrenzt, wie viel mehr Knoten dies mehr CPU zur Build-Zeit und GPU zur Laufzeit verbraucht. Die Knoten werden entsprechend den Ein- und Ausgabewerten angepasst, die Konvertierung von float in vec2 oder vec3 zum Beispiel erfolgt automatisch, und bei mehrmaliger Verwendung zur Optimierung im Cache gespeichert (siehe TempNode ).

In Screenshots ist jeder Knoten eine Klasse, zB: PositionNode im Display ist:
https://github.com/mrdoob/three.js/blob/789efa65bafe022e178c7e93e0985a7607a54403/examples/js/nodes/accessors/PositionNode.js#L5

@mrdoob @sunag Wären Sie bereit, den aktuellen Status des NodeMaterial-Codes zu kommentieren und wie er zur Three.js-Roadmap passt?

Theoretisch könnten wir Knoten jetzt für mehrere Dinge verwenden, wie zum Beispiel:

  • Implementieren Sie glTF spec/gloss PBR-Materialien als NodeStandardSGMaterial.
  • Unterstützt UV-Sets und Transformationen pro Karte
  • Vereinfachen Sie die Verwendung von eingebauten Materialien mit Instanzierung

Aber es ist schwer zu rechtfertigen, eine Abhängigkeit in GLTFLoader für alle Knotendateien hinzuzufügen. Und wahrscheinlich ist es schwer zu rechtfertigen, Knoten ohne aktivere Nutzung in src/* zu setzen. Hühnerei. 😅

Es wäre hilfreich, den langfristigen Plan für NodeMaterial zu kennen, um zu erraten, welche Funktionen zusammenhängen (oder nicht) ... braucht das mehr Entwicklung? Gibt es Dinge, die andere Mitwirkende tun könnten, um zu helfen?

@sunag ja, ich wäre auch gespannt, ob du zu diesem Zeitpunkt noch weitere Pläne hast.

Theoretisch könnten wir Knoten jetzt für mehrere Dinge verwenden, wie zum Beispiel:

  • Implementieren Sie glTF spec/gloss PBR-Materialien als NodeStandardSGMaterial.
  • Unterstützt UV-Sets und Transformationen pro Karte
  • Vereinfachen Sie die Verwendung von eingebauten Materialien mit Instanzierung

Für diese speziellen Probleme gibt es jetzt Beispiele dafür, wie sie mit den vorhandenen APIs gelöst werden können, ohne dass der Kern geändert werden muss:

Instanzierung:
https://github.com/mrdoob/three.js/pull/10750 (voll ausgeblasen, berührt den Kern, könnte aber mit Affen gepatcht werden)
https://github.com/mrdoob/three.js/pull/14166 (einfache, materielle Erweiterungen über onBeforeCompile)
https://github.com/mrdoob/three.js/pull/14012 (einfache Bibliothekserweiterung per Mokey-Patching)

pro Karte-UV-Sets
https://github.com/mrdoob/three.js/pull/14174

spec-gloss als eigene Klasse
https://github.com/mrdoob/three.js/pull/14099

Vielleicht kann es dazu dienen, das Gefühl der Dringlichkeit zu lindern, NodeMaterial in den Kern zu bekommen :).

Für diejenigen, die dieses Thema verfolgen, gibt es eine laufende Diskussion unter https://github.com/mrdoob/three.js/pull/14149.

Joining Threads von #14149:

tl;dr — NodeMaterial scheint mir ein vielversprechender nächster Schritt für das Materialsystem zu sein. Ich vermute, dass die Akzeptanz von NodeMaterial derzeit durch einige Dinge eingeschränkt ist:

  • Reibung beim Einbinden vieler einzelner Dateien
  • Fehlen eines visuellen Editors
  • relativ wenige Beispiele, Dokumente

Ich würde die Frage, wann / ob NodeMaterial in src/ , @mrdoob und @sunag überlassen , aber ich denke, wir sollten (zumindest) die drei oben genannten Probleme



Die kritische Masse scheint sich von GLTFLoader-Stakeholdern zu bilden, und meine (subjektive) Beobachtung ist, dass der Bedarf aufgrund von unsachgemäß dokumentiertem onBeforeRender (wenige Beispiele) und noch weniger dokumentiertem onBeforeCompile (ein Beispiel) entstand.

@pailhead Ich habe begonnen, GLTFLoader zu warten, um Workflow-Probleme in A-Frame zu beheben, von dem ich auch ein Entwickler bin. Ich stimme zu, dass ein nützlicheres Materialsystem das Ziel ist, kein bestimmtes Format zu laden. Die Entscheidung, wie Knotenmaterialien integriert (oder nicht integriert) werden, sollte auf den Vorzügen für Endbenutzer der Three.js-Bibliothek basieren – Funktionen, Flexibilität, eine verständliche API.

Sie haben Recht, dass onBeforeCompile und onBeforeRender Hooks unendlich flexibel sind; es gibt keine praktische Grenze, wie weit Sie die zugrunde liegenden Shader manipulieren oder ersetzen können. Aber beide sind als Primärmaterial-API ähnlich fehlerhaft:

  1. Erzwingt die WebGL-Syntax in die Material-API selbst für relativ einfache Funktionen
  2. Hängt von der String-Manipulation der Kernmaterial-Shader ab, wodurch Änderungen an den Kernmaterialien mit der Zeit schwieriger und anfälliger werden
  3. Weniger zugänglich für Künstler
  4. Praktisch unserialisierbar

Dekoratoren (zB #14206) verbessern dies sicherlich aus Benutzersicht – aber wenn zukünftige Feature-Entwicklungen von Materialien auf immer komplizierteren Dekoratoren zusätzlich zu den bestehenden Material-Shadern basieren, ist dies meiner Meinung nach ein Risiko für die Wartbarkeit.

Knotenmaterialien sind nicht perfekt, werden aber in anderen Grafikwerkzeugen weit verbreitet und haben entscheidende Vorteile:

  1. Flexibel und kombinierbar
  2. Behält eine Abstraktionsebene der internen WebGL-Shader der Bibliothek bei, ohne den Zugriff auf einfache Shader bei Bedarf zu entfernen
  3. Weit verbreitete Materialdarstellung für Künstler und Spieleentwickler
  4. Zumindest etwas serialisierbar (obwohl die Konvertierung in andere Formate immer noch schwierig ist)

Das hört sich wahrscheinlich so an, als würde ich sagen, dass onBeforeCompile veraltet sein sollte, und das möchte ich nicht – ich würde mich freuen, wenn es so bleibt, und Beispiele sind willkommen. Aber es ist keine API, auf die ich A-Frame- oder Three.js-Benutzer für mehr Fälle als nötig verweisen möchte; Ich glaube nicht, dass es mit den Materialsystemen in anderen 3D-Tools vergleichbar ist.

  • Reibung beim Einbinden vieler einzelner Dateien

Das sollte keine Reibung sein. Ich denke, es wäre nützlich, eine Umfrage oder so etwas durchzuführen, um zu sehen, wie viele Leute Bundler verwenden und Tools bauen. Das manuelle Importieren von js-Dateien in eine HTML-Datei sollte 2018 nicht wirklich ein Ansatz sein. Dies ist die einzige Nummer, die ich finden kann , und ich denke, man könnte davon ausgehen, dass alle diese Benutzer sie mit etwas verwenden, das mit node läuft.

Ich würde mir mehr Mühe geben, den Baum zu schütteln und dies import/export richtig zu machen, als mir Gedanken darüber zu machen, wie dies funktionieren würde, wenn man Skriptdateien manuell einfügt.

  • Fehlen eines visuellen Editors
  • relativ wenige Beispiele, Dokumente

Ich denke, dies sollte passieren, bevor es in den Kern gelangt. Das spiegelnde Glanzmaterial sollte ein Beispiel sein, das nicht mit GLTFLoader gekoppelt ist. Die Tatsache, dass es in /src oder /examples sollte irrelevant sein?

@donmccurdy

Sie haben Recht, dass die Hooks onBeforeCompile und onBeforeRender unendlich flexibel sind; es gibt keine praktische Grenze, wie weit Sie die zugrunde liegenden Shader manipulieren oder ersetzen können.

Ich behaupte das nicht wirklich, ich behaupte, dass ein Hook wie onBeforeRender einen anderen Ansatz zur Strukturierung von Code ermöglicht, aber dass er nicht so verwendet werden sollte, wie er jetzt in GLTFLoader (daher #14099).

onBeforeCompile definitiv Einschränkungen und ist möglicherweise falsch benannt. Ein guter Hinweis in diesem Zusammenhang ist eine aktuelle PR #14214. Sobald ich sah, was weg war ( build() zugunsten von needsUpdate ), wusste ich, dass ich dort onBeforeCompile . Ich habe es als onBeforeParse denn wenn ich keine #include <foo> Anweisungen ersetze, werden sie immer noch nach dieser Funktion und vor der eigentlichen Kompilierung geparst. In dieser PR wird es als onWillRefreshMaterial .

Die Philosophie, die ich zu vermitteln versuche, ist, dass diese Art von Rückrufen wahrscheinlich mehr Granularität aufweisen sollte. Es sollte mehr davon geben, und bei der Benennung sollte man sehr vorsichtig sein.

#14214 ist ein großartiges Beispiel dafür, warum NodeMaterial nicht im Kern sein muss. Zumindest nicht mit etwas in /renderer gekoppelt und nicht damit gebündelt.

  1. Erzwingt die WebGL-Syntax in die Material-API selbst für relativ einfache Funktionen

Ich habe dieses Problem schon einmal gehört, aber es wurde nicht weiter ausgeführt. Warum ist das ein Problem? Was ist überhaupt die "Material-API"? Ich habe es immer als "hier sind einige gängige Oberflächenschattierungsmaterialien" gesehen.

Wenn Sie eine dynamische Karte wünschen, sehe ich keinen Grund, warum material.map oder 'material.color' nicht NodeTexture , GLSLTexture , TextureTexture annehmen könnten.

myMaterial.color = new SomeNodeGraph() //outputs vec4 in the end

myMaterial.color = new GLSLInput() // inputs various documented variables, outputs some vec4

myMaterial.color = new THREE.Color()

myMaterial.color = new CustomColorGradientTopBottom() // dunno if its Node, GLSL, regular color whatever, i just know it's compatible with the slot
  1. Hängt von der String-Manipulation der Kernmaterial-Shader ab, wodurch Änderungen an den Kernmaterialien mit der Zeit schwieriger und anfälliger werden

Mein Punkt ist, dass dies mit onBeforeCompile bereits einigermaßen möglich ist, aber diese Änderungen noch schwieriger und fragiler macht als das, was Sie beschreiben. Ich habe bereits in meinem Berufsleben danach gegriffen und habe einen Code, der darauf basiert. Wie zerbrechlich es ist, verursacht viel Stress :(

Die Dekorateure, auf die Sie #14206 hingewiesen haben, sind wegen dieser PR, die selbst seit 3 ​​Jahren ins Stocken geraten ist, seit mehr als einem Jahr ins Stocken geraten. Mein subjektives Gefühl ist, dass #14206 das Schreiben dieser Dekorateure möglich machen würde, weniger mühsam und weniger zerbrechlich. Es sind 30 Codezeilen, die absolut nichts beeinflussen, es sei denn, diese Phantomeigenschaften sind definiert. Wenn wir bereits ein Seil haben, an dem wir uns in Form von onBeforeCompile aufhängen können, warum nicht etwas humaner machen? :Lächeln:

Am Ende möchte ich selbst entscheiden, was ein akzeptables Maß an Zerbrechlichkeit ist und was nicht.

  1. Weniger zugänglich für Künstler

Aus diesem Grund sollten Künstler ein visuelles Werkzeug und eine Art Format zum Speichern der Grafiken haben. Sie als "gebackene" GLSL oder etwas, das die NodeMaterial zur Laufzeit erstellt, zu konsumieren, sollte dem Benutzer überlassen bleiben.

Ein Künstler könnte einen Shader erstellen, ein Ingenieur könnte darum bitten, dass er "kompiliert" wird, um den Ladeprozess zu optimieren. Ein allein arbeitender Künstler könnte den Graphen einfach laden, vorausgesetzt, dies ist aus irgendeinem Grund einfacher ("kompiliert" erfordert mehr Aufwand).

Und warum und wie werden Künstler hier berücksichtigt? Gibt es Statistiken, wie sieht ein durchschnittlicher "Künstler"-Benutzer aus, warum arbeiten sie mit Three.js und nicht mit Unity, dh. was ist das für eine Pipeline. Sind Ingenieure beteiligt, warum nicht ein eigenständiges Tool, das irgendwie mit Three.js kommuniziert, das irgendein Tech-Verzeichnis übernimmt usw. Ich gehe davon aus, dass die 40.000 npm-Downloads pro Woche keine Künstler sind. Es wird davon ausgegangen, dass diese Art von Installation von einigen Build-Tools verwendet wird und es sehr unwahrscheinlich ist, dass sie manuell importiert wird.

Sowohl zu diesem als auch zu Punkt 2 umfasst mein Anwendungsfall keine Künstler und normalerweise keine anderen Benutzer. Ich baue ein Materialsystem auf, das auf eingebauten Materialien aufgebaut ist. Ich verwende mein eigenes normales Entpacken mit tangentialen Attributen, Tiefenschälen, verschiedenen Clippings usw. Alles, was mich interessiert, ist, diesen Code intern zu strukturieren und den oben genannten Klassen so wenig Interna zur Verfügung zu stellen.

  1. Praktisch unserialisierbar

Ich weiß nicht viel darüber und ich habe dieses Argument schon einmal gehört. Ich würde mich sehr freuen, mir etwas Code anzuschauen, wenn mich jemand auf die problematischen Bereiche hinweisen könnte. Mit meinem sehr begrenzten Verständnis (fast) des Problems verstehe ich nicht, warum es einfach nicht ausreicht, zu schreiben

"materialFoo": {
  "color":"#ff0000",
  "specularMap": "some_path.jpg",
  "glossiness": "0.5"
}

Angenommen, Sie haben ein Spec-Gloss-Material, das mit NodeMaterial , möchten nicht den gesamten Graphen serialisieren, sondern nur die Eingaben? Was auch immer die Serialisierung eines SpecGloss Materials ist, sollte es gleich aussehen? Ich vermisse hier wahrscheinlich einiges, würde mich über ein paar Hinweise freuen.

Re: Serialisierung

Wäre es genug hinzuzufügen:

https://github.com/mrdoob/three.js/blob/dev/src/materials/Material.js#L160

customSerializer( data )

Und dann sowas wie

SpecularGlossMaterial.prototype.toJSON = ()=>{
  Material.prototype.call(this, undefined, data =>{
    if ( this.roughness !== undefined ) data.roughness = this.roughness;
  })
}

specularMap würde tatsächlich serialisiert werden, weil es hartcodiert ist:
https://github.com/mrdoob/three.js/blob/dev/src/materials/Material.js#L213

Aber das fühlt sich irgendwie seltsam an, die Material Klasse ist sich der Interna aller eingebauten Materialien bewusst, wie es scheint?

@donmccurdy Wenn Sie diese Diskussion führen möchten, ist es möglicherweise besser, dies in der Dekorateur-PR, #14206, zu tun. Offline bin ich überall in der Bay Area für eine Arbeitssitzung bei Bier oder Kaffee verfügbar :slightly_smiling_face:

Einverstanden, dass mehrere Dateien _keine_ Reibung sein sollten und dass dies kein Argument für sich ist, NodeMaterial in src/ . Dies ist einfach einer der vielen Gründe, warum NodeMaterial noch nicht häufig verwendet wird, und es gibt andere Möglichkeiten, dies zu lösen. Und ich stimme sicherlich zu, dass mehr Dokumente eine Voraussetzung dafür wären, NodeMaterial in src/ oder sogar die Einführung in examples/js oder eine separate Build-Ausgabe voranzutreiben.

Ich bin optimistisch, was NodeMaterial als allgemeine Richtung angeht, obwohl ich vermute, dass noch ein paar Dinge erforderlich sind, bevor es in src/ Sinn machen könnte. Ich bin sehr besorgt über die Verwendung von onBeforeCompile und String-Manipulation als Weg, um neue Funktionen in das Materialsystem zu integrieren, wie oben beschrieben, und insbesondere, wenn wir uns in Richtung der Unterstützung von WebGL2 und (eventuell) WebGPU bewegen . Das soll nicht heißen, dass diese beiden Möglichkeiten die einzigen Optionen sind, aber (von den beiden) sind dies meine Gedanken.

Bei den anderen Punkten scheint es, als ob wir die Sorgen und Vorlieben des anderen verstehen, uns aber immer noch nicht einig sind. Ich habe alles geschrieben, wofür ich an dieser Stelle Zeit habe, und werde dies eine Weile aussetzen und andere abwägen lassen. Vielen Dank für eine gründliche und höfliche Diskussion darüber. 🙂

Ich möchte eine Ambient-Occlusion-Textur mit Multiply auf eine diffuse Textur legen, also versuche ich Folgendes:

const aoNode = new OperatorNode(
        new Math1Node( aoTexture, Math1Node.INVERT ),
        aoScale,
        OperatorNode.MUL
    );
material.ao = aoNode;

Das ist meine AO-Textur
ao sx

Leider habe ich bei meinem Modell eine Umgebungsokklusion gesehen.

Hast du eine Idee dafür?
Hoffe das ist der richtige Ort um meine Frage zu posten.

Vielen Dank!

Ich möchte in der Lage sein, in Richtung eines Mappings von bestehenden Node-basierten Tools auf Materialien in Threejs zu denken. Daher würde ich NodeMaterial gerne in src/ zusammen mit einer richtigen Dokumentation sehen.

@IARI

Können Sie bitte die vorhandenen knotenbasierten Tools auflisten?

@donmccurdy

Danke für Ihre Antwort :)

Leider glaube ich, dass wir uns immer noch nicht verstehen. Wenn Sie Zeit haben, diesen Beitrag zu lesen, dieses Zeug:

Ich mache mir große Sorgen, onBeforeCompile und die String-Manipulation zu verwenden, um neue Funktionen in das Materialsystem zu integrieren.

onBeforeCompile ist schrecklich, ich stimme zu, der einzige Grund, warum ich in einen dieser Threads involviert bin, ist, dass ich #13198 will, was meiner Meinung nach der String-Manipulation von onBeforeCompile überlegen ist.

Dies sollte kein Muster sein, um Three.js neue Funktionen hinzuzufügen. Es sollte Benutzern ermöglichen, ihren Anwendungen neue Funktionen hinzuzufügen. Ich bin traurig, dass @bhouston keine Erkenntnisse über die Pflege einer Gabel geteilt hat, um einige dieser

Im Fall von uv-Transformationen pro Kanal würde ich das zu einem Beispiel oder einem npm-Modul machen. Wenn 3 Leute es jede Woche herunterladen, ist es wahrscheinlich etwas, das nicht im Kern sein sollte. Wenn 20.000 Leute es herunterladen, hätte Three.js wahrscheinlich so gestaltet werden sollen.

onBeforeCompile scheint für Knotenmaterialien von entscheidender Bedeutung zu sein, https://github.com/mrdoob/three.js/pull/14214 , also wird es nicht nur für die String-Manipulation verwendet .

Ich habe onBeforeCompile und NodeMaterial , um dies zu tun, ich bitte um eine dritte Option. Viel bequemer als onBeforeCompile und viel kleiner als NodeMaterial .

Mit aktuellen Beispielen:
https://github.com/mrdoob/three.js/pull/14206

Alte Diskussion:
https://github.com/mrdoob/three.js/pull/13198

@pailhead Für den Anfang würde ich über ein paar grundlegende Blender Cycles Nodes nachdenken.
Ich würde es auch interessant finden, mit Unitys Shadergraph herumzuspielen.

@claudioviola Sie können material.shadow hinzufügen oder mit diffusen material.color = diffuse * oclusion multiplizieren. Okklusionsabhängigkeit von indirektem Licht, AmbientLight , HemisphereLight ...

@IARI

Ich lade 7,5 Gigs von Unity herunter, um den ShaderGraph auszuprobieren :slightly_smiling_face: : Ich bin mir nicht sicher, ob das ein Werkzeug zum Erstellen von Shader-Graphen ist, ich denke, es ist ein Werkzeug zum Erstellen von Shader-Graphen für Unity. Gibt es eigenständige Tools zum Erstellen von Diagrammen? Ich möchte sehen, in welcher Art von Datei das Diagramm auch gespeichert wird und wie es in drei.js und NodeMaterial in /src .

Ich denke, dass @pailhead derzeit isoliert gegen diese Verschiebung von NodeMaterials in den Kern ist. Ich glaube nicht, dass es für jeden sinnvoll ist, tagelang mit

Dies wurde nicht überstürzt und es wurde nicht erzwungen. Sunag hat dies vor Jahren hinzugefügt. Dies ist im Moment notwendig und andere Alternativen haben sich nicht bewährt (zB zusammengeführt), also versuchen wir es mit diesem Weg.

Jedes wichtige Tool, 3DS Max, UE4, Blender, Unity, Maya, Sketchfab verwendet Shader-Diagramme. Zu argumentieren, dass three.js in dieser Hinsicht dauerhaft benachteiligt sein sollte, erscheint Three.js gegenüber unfair.

Ich bin mir nicht sicher, ob dieses grafikbasierte Shader-System derzeit perfekt ist, aber sobald es im Kern ist, können wir alle weiter damit arbeiten.

Ich bestehe darauf, dass wir die API von PhoneMaterial, StandardMaterial usw. weiterhin in irgendeiner Weise unterstützen, damit wir nicht 95% der Three.js-Projekte brechen, dies wäre unverantwortlich. Es ist auch schön, mit solchen vereinfachten, unkomplizierten Schnittstellen zu arbeiten.

Ich habe weder die Fähigkeit noch den Wunsch, dies daran zu hindern, in den Kern vorzudringen. Ich hoffe nur, dass es einige nicht verwandte PRs entsperren könnte, da es als Blocker bezeichnet wurde. @bhouston , wollte auch nie mit dir streiten, ich war nur neugierig auf deine Gabel und deine Erfahrungen damit.

Als ich als hungernder 3D-Künstler über die Runden kam, mag ich alles, was auf Knoten basiert. Nuke war mein Lieblingskomponist und ich würde gerne lernen, wie man solche Werkzeuge herstellt. Ich wünsche mir nur, dass dies insbesondere die Blockierung Nr. 14231 entsperrt. Ich benutze dies als Lernplattform für mich, aber wenn es störend ist, höre ich auf zu posten, danke.

@pailhead Ich habe noch nie damit gearbeitet, aber du hast wahrscheinlich schon von Substanzdesigner gehört? Soweit ich weiß, geht dieses Tool auch über das Erstellen von Graphen/Shadern hinaus - aber es konzentriert sich hauptsächlich auf das prozedurale Design von Materialien - vielleicht ist das ein interessanter Hinweis?

Abgesehen davon kenne ich eigenständige Tools nicht aus dem Kopf, aber eine schnelle Google-Suche ergab diese beiden:

Es gibt jedoch auch dieses Tool für die Threejs-Nodes, das ich in einem Twitter-Post von @mrdoob aus dem Jahr 2015 gefunden habe - obwohl es anscheinend nie aktualisiert wurde, frage ich mich warum ....

Dieses Tool scheint hier referenziert worden zu sein, aber ich sehe keine Möglichkeit, etwas zu exportieren. Der erste Link sieht toll aus, aber die Ausgabe ist ziemlich knorrig, im Vergleich zu GLSL nicht sehr lesbar. Ich frage mich, ob das bereits verwendet werden kann, um das NodeMeterial oder sogar ein ShaderMaterial .

Ich habe mir Unity angesehen, aber das Shader-Graph-Tool konnte ich nicht finden.

Übrigens, wenn ich das irgendwie blockiert habe, lass es auf jeden Fall entblocken. Die PR ist von 2015, ich habe vor 8 Tagen zum ersten Mal geantwortet.

(Entschuldigung, das ist ein bisschen offtopic..)
@pailhead Für Unity-Shadergraph: Sie müssen ein Unity-Projekt mit der Lightweight-Rendering-Pipeline-Vorlage starten. Stellen Sie sicher, dass Sie den Unity Package Manager öffnen und überprüfen Sie, ob Sie die neueste Version des Render-pipelines.light-Pakets verwenden.
Hier ist ein Tutorial, um es einzurichten, beginnend mit einem neuen Projekt, das eingerichtet wird: https://youtu.be/Ar9eIn4z6XE?t=98

Der Materialknoteneditor von Sea3D Flow (http://sea3d.poonya.com/flow/) ist von @sunag , dem gleichen Typ, der NodeMaterial geschrieben hat.

Vielen Dank @sunag
Wie bekomme ich das indirekte Licht? Ist es ein Wert im Renderer oder wie kann ich ihn berechnen?

Ich möchte einen Nachbearbeitungseffekt nur auf eine Auswahl von Objekten anwenden (dh die Sättigung ändern).
Ich kann jedoch nichts finden, was mit der Maskierung (wenn es nicht anders geht) mit Knoten zu tun hat.
Derzeit lese ich den (Nicht-Knoten-)OutlinePass durch, der eine Menge Zeug in eine Reihe von Puffern schreibt, was ich als eine praktikable Methode ansehen kann, um das zu erreichen, was ich will - aber ich habe nicht die geringste Ahnung, wie ich es angehen soll dies mit Knoten.

Der Materialknoten-Editor von Sea3D Flow wird wie der Three.js-Editor eigenständig sein oder ein Teil davon sein? Wird es weiterhin Sea3D heißen oder etwas anderes, das mit Three.js zu tun hat? Danke @sunag für die Veröffentlichung dieses visuellen Editors für die Three.js-Community.

aber ich habe nicht die geringste Ahnung, wie ich das mit Knoten angehen soll.

@IARI

Es scheint, als ob Sie GLSL kennen, da Sie den OutlinePass lesen und verstehen können, was er tut. Sie scheinen es auch genug zu verstehen, um zu sehen, dass Sie es mit Knoten nicht erreichen können. Ich dachte, wenn Sie wissen, wie man es codiert, können Sie es verknoten. Noch mehr, wenn Sie nicht wissen, wie man es codiert, wissen Sie vielleicht, wie man es verknotet. Wo ist die Trennung?

Ich habe diese Beiträge von 2016 überhaupt nicht gesehen. Interessant, Shader Frog zu sehen. Ich frage mich, ob dies als vim vs emacs oder so gesehen werden kann. Ich verwende gerne Sublime Text, Sie verwenden gerne etwas anderes. Einer verwendet gerne Shader Frog, ein anderer verwendet gerne den Sea3D-Editor von Three.js.

Ich mag, wie Shader Frog nur einen Shader ausgibt, aber es ist nicht Open Source wie Sea3D.

Dann gibt es das.

Die Produktmechanik von Drittanbietern in den Kern von Three zu integrieren, scheint ein unfairer Vorteil zu sein und ich verstehe das politisch nicht.

Für mich bedeutet die Tatsache, dass all dies ohne Three-Änderungen erreicht werden kann, dass dies unnötig ist und die Grenze zwischen Three.js als webgl-Wrapper-API und jetzt implementierungsspezifischen Funktionen verwischt. Das Speichern von Shader-Node-Daten ist sehr App-spezifisch und meines Wissens gibt es derzeit kein gemeinsames Node-Editor-Standardformat für jede Software? Das Erzwingen eines kann für andere Implementierungen schädlich sein.

@bhouston
Ich kann es kaum erwarten, dass NodeMaterial landet, da es andere PRs entsperren und das Leben wieder normal werden kann. Es scheint, dass andere Stimmen in der Vergangenheit versucht haben, dies zu blockieren.

Ich denke, dass @pailhead derzeit isoliert gegen diese Verschiebung von NodeMaterials in den Kern ist.
Ich denke, das Projekt sollte nicht einer einzelnen Person verpflichtet sein.

Dankeschön.

Ich sehe keinen Grund, warum dies nicht mit Knoten genau so erreicht werden könnte, wie dies bei outlinepass der Fall ist - aber auf eine Weise, die lesbar, verständlich und modular ist, sodass Teile wiederverwendet werden können.
Warum sollte es zum Beispiel keine Ausgabeknoten geben, die in Puffer schreiben und so.

Und ich kenne mich mit glsl wirklich nicht so gut aus, und auch ich finde es - verzeihen Sie meine Formulierung - eine super Nervensäge, Shader-Code zu lesen und zu schreiben. Und obendrein ist es besonders schmerzhaft, wenn es in ein dummes Array in Strings in Javascript-Code verpackt ist.

Benutzt du Webpack oder so?

dummes Array

Es ist nur dumm, wenn Sie es in eine .html-Datei importieren müssen. Wenn Sie mit Webpack arbeiten und über die moderne JS-Syntax verfügen, können Sie Ihre GLSL in .glsl-, .vs-, .fs-Dateien speichern und Syntax-Highlighting usw. verwenden.

shader.fs:

void main(){
  gl_FragColor = vec4(1.);
} 

Javascript (schau Mama, keine dummen Arrays)

import mShader from './shader.fs'

Meine Sorge ist, dass ich in Ihrem Bedarf nicht viel Wert sehe, da Sie speziell fragen, wie man einen Effekt erzeugt, und nicht, wie man etwas codiert. Wird NodeMaterial Türen zu Tausenden von "Wie schattiere ich diesen Effekt"

Benutze die Knoten, Luke!

Nein, es ist für mich immer eine Qual, Code in zwei verschiedenen Sprachen innerhalb derselben Datei lesen (geschweige denn schreiben) zu müssen. Auch Webpack hilft nichts, wenn Sie versuchen, Threejs Beispiel-Shader-Code zu studieren, der alle in hässliche Stringarrays verpackt ist, die durch Zeilenumbrüche verbunden sind.
Wie auch immer, in dieser Ausgabe geht es um das Node-System, und ich habe eine einfache Frage zu Nodes gestellt - nicht für eine Diskussion über persönliche Codierungspräferenzen -, die nirgendwo hinführt.

@IARI

Entschuldigung, ich habe irgendwie keine Fragezeichen in Ihrem Beitrag gesehen, also habe ich Ihre Frage übersehen.

Dies sollte auf keinen Fall eine Diskussion über persönliche Codierungspräferenzen sein, sondern die Tatsache, dass es unterschiedliche gibt, sollte berücksichtigt werden. Ich bin auch ein bisschen besorgt über die Flut von "Wie erstelle ich diesen Shader"-Fragen.

Früher war diese Messlatte ziemlich hoch, die Leute geben einfach auf, wenn i don't know glsl oder wenn sie "ein dummes Array in Strings" sehen. Aber wenn es niedriger ist, wird jeder versuchen, Shader zu schreiben.

Ich habe deine Frage nicht gefunden, aber ich bin gespannt, was es ist. Ist es:

Wie erstelle ich einen ToonShader mit NodeMaterial?

In diesem Fall bin ich gespannt, was die Antwort ist.

Dies ist nicht möglich, da NodeMaterial keine Abstraktion unterstützt.
Sie können einfach NodeMaterial verwenden, um Knoten zu verbinden

Vielleicht könnte diese Diskussion davon profitieren, dass sie ausgebrochen wird? Es ist eine hohe Anzahl von Beiträgen, die sehr weit zurückreichen (2015). NodeMaterial befindet sich in /examples, sodass Sie wahrscheinlich Ihren Toon-Shader daraus erstellen können. Vielleicht könnten Sie speziell dafür ein anderes Issue öffnen oder auf Stack Overflow posten, und der Rest der Konversation könnte in ein neues Issue übergehen?

Wir können diese Diskussion gerne woanders hinführen, wie in irgendeinen Slack-Channel oder was auch immer - ich habe wirklich das Gefühl, dass sie hier nicht hingehört, aber die Leute meistens ärgern wird.

Das Forum könnte für diesen speziellen Fall besser als locker sein.

@pailhead , diese ganze Diskussion wurde daran

@bhouston

Einverstanden, außer dass ich denke, dass es mehrere Probleme sind.

  • wie man nodematerial implementiert
  • sollten andere verwandte und nicht verwandte PRs blockiert werden
  • wie man Leuten, die nicht wissen, wie man Shader schreibt, erlaubt, bestimmte Shader-Effekte zu implementieren

Wie erstelle ich einen ToonShader mit NodeMaterial?
In diesem Fall bin ich gespannt, was die Antwort ist.
Dies ist nicht möglich, da NodeMaterial keine Abstraktion unterstützt.
Sie können einfach NodeMaterial verwenden, um Knoten zu verbinden

Lol. Ich stimme @bhouston zu ... das kann nur ein Scherz sein. Sie hätten das Beispiel webgl_materials_nodes bevor Sie es gesagt haben?

Und wenn Sie Code verwenden möchten, lesen Sie den Ausdruck mit FunctionNode .

toon

@sunag ich glaube du hast mich falsch verstanden. Ich war neugierig, warum, wenn dies derzeit in /examples und nicht in /src ist, dies zu einem Bürger erster Klasse gemacht wird. Dieses Problem scheint bereits 2015 von @AndrewRayCode angesprochen worden zu

Ich habe gerade gesagt, dass dieses Thema überladen ist, da es weit in das Jahr 2015 zurückreicht und verschiedene Themen diskutiert werden. Wenn jemand fragte, "wie mache ich ein whatever " würde er auf einen Stapelüberlauf verweisen.

Wenn dies eine massive Überarbeitung von Three.js sein wird _(die Tatsache, dass Unity speziell dafür konfiguriert werden muss, macht mir etwas Angst)_ dann sollte es meiner Meinung nach ein fortlaufendes Thema hier auf github für solche Fragen geben - usage of NodeMaterial . So wie es ist, werden Leute, die nach zufälligen Dingen fragen (#14232), auf diesen Thread verwiesen, das macht die Kommunikation chaotisch :)

Ich musste vor kurzem einen Toon-Shader schreiben, aber er basierte auf Linien, und genauer gesagt auf den fetten Linien von NodeMaterial portieren, was wer weiß wie lange dauern könnte. Dies sind alles verschiedene Themen, die hier verworren werden.

Und wenn Sie Code verwenden möchten, lesen Sie Ausdruck mit FunctionNode.

Wenn ich kodiere, verwende ich erhabenen Text, ShaderMaterial ist für mich in Ordnung, keine Notwendigkeit für FunctionNode . Wenn ich visuelle Effekte erstelle, werde ich wahrscheinlich in einen visuellen Editor schauen, aber das ist meine eigene Präferenz. Ich bin nur hier, weil das andere PRs blockiert :) Ich habe vor nicht allzu langer Zeit erkannt, dass es eigentlich im besten Interesse von drei ist, dass dies so schnell wie möglich landet. Dieses Gespräch zu entwirren würde wahrscheinlich dazu beitragen, die Dinge zu beschleunigen. Darin stimme ich @bhouston zu, dies sollte so schnell wie möglich sein!

Dankeschön.

Um es festzuhalten: Ich interessiere mich nicht für einen Toon-Shader oder ähnliches.
Ich implementiere ein System, das es Leuten, die keinen Code schreiben, ermöglicht, einfache vordefinierte Effekte an bestimmten Positionen einzufügen.

Leider habe ich im Moment keine Zeit zu lernen, wie man Nodes schreibt, und ich muss sowieso die grundlegende glsl-Codierung nachholen, also werde ich vorerst Dinge ohne Nodes implementieren: Es wird nicht erweiterbar sein , es werden mehrere Renderdurchgänge verwendet, wobei ein einzelner bei einer guten Node-Implementierung wahrscheinlich ausreichen würde, es wird weniger lesbar sein, ...

Alles in allem bin ich leider nur zu neu im allgemeinen Thema und muss noch viel mehr grundlegendes Verständnis erlangen, aber nach meinem Wissen wären Knoten der beste Weg, dies auf eine wirklich elegante und erweiterbare Weise zu tun.
Ich würde mich sehr über einige Informationen zur Implementierung von Nodes wie einen Blogartikel oder ein Tutorial freuen.

Disclaimer: Ich verlange nichts, hoffe nur, meine vage Bitte von oben zu klären.
Vielen Dank für all die Arbeit, die hier geleistet wird - es ist absolut erstaunlich.

Ich wurde im Thread https://github.com/mrdoob/three.js/issues/14232 gebeten, die Node-basierte Shader-Implementierung zu kommentieren. Ich denke, es ist sehr arm. Ich liebe die Idee, aber die Umsetzung ist aus meiner Sicht völlig unzureichend. Da ich so negativ bin, werde ich einige konkrete Gründe dafür angeben.

Verständlichkeit

Nachdem ich einen Teil des Codes für die Nodes und verschiedene Utility-Klassen gelesen habe, kann ich entschieden sagen, dass es eine große Herausforderung ist, es zu verstehen.

  • Variablennamen sind nicht beschreibend
  • gar keine kommentare
  • Methodennamen sind undeutlich oder geradezu irreführend. (zB was denkst du macht die Methode "build"? - rate mal)

Die Codestruktur ist geradezu seltsam. Betrachten Sie diesen Ausschnitt:
https://github.com/mrdoob/three.js/blob/e2b49c017b2d1f37ab34317033a27df7b5a71d4d/examples/js/nodes/FunctionNode.js#L39 -L50

Dasselbe könntest du erreichen mit:

return this.inputs.find(input => input.name === name);

"Aufstrebende Architektur"

Was ist ein "Knoten"? Ich bitte um eine Definition der Datenstruktur, weil es nur ein nebulöses Konzept zu sein scheint, da es wenig Gemeinsamkeiten zwischen verschiedenen "Nodes" gibt, es sieht aus wie Ducktyping, wenn es wie ein Node quakt - es ist ein Node.

Trennung von Bedenken

Wie kommt man von Node zu einem ShaderMaterial ? Im Moment ist es eine Mischung von Verantwortlichkeiten zwischen verschiedenen Teilen der Logik von jedem Knoten, einigen Buildern, einigen Caches, Parsern usw. Es gibt keine klare Verantwortung für diesen Prozess. Node verwendet NodeBuilder? Was zum ...? Vom Namen her hätte ich gedacht, dass NodeBuilder eine Fabrik ist, die Knoten produziert oder konstruiert, da es sich tatsächlich um eine Hilfsstruktur handelt. Soweit ich das beurteilen kann, gibt es hier ziemlich unterschiedliche Aufgaben zu erledigen:

  • Erstellen Sie ein Diagramm
  • Bestätigen
  • Zwischenrepräsentation erstellen
  • optimieren
  • zu GLSL kompilieren

Das ist überhaupt nicht das, was Sie im aktuellen Code finden.

Abschluss

Ohne gute Dokumentation und Kommentare halte ich diese Implementierung für völlig unzureichend. Wenn diese Dinge vorhanden sind, ist es eine Frage von Spaghetti-Code und mangelndem Design. Abgesehen davon erkenne ich an, dass es sich um ein leistungsstarkes Werkzeug und eine funktionierende Umsetzung eines sehr nützlichen Konzepts handelt.

@Usnul wir werden niemals so in Three.JS codieren "return this.inputs.find(input => input.name === name);"

Der Grund dafür ist, dass das "=>" eine Funktion erstellt, die bei jeder Eingabe aufgerufen werden muss. Funktionsaufrufe sind in JavaScript im Vergleich zu einer for- oder while-Schleife sehr langsam. Daher führen wir immer explizite Schleifen anstelle von rückruforientiertem Code durch. Ich weiß, es ist ausführlicher, aber es ist notwendig. All of Three..JS ist so und mit Absicht.

@Usnul , Ihre Designanliegen sind sehr nützlich, könnten Sie dann bei der

Der Grund dafür ist, dass das "=>" eine Funktion erstellt, die bei jeder Eingabe aufgerufen werden muss. Funktionsaufrufe sind in JavaScript im Vergleich zu einer for- oder while-Schleife sehr langsam. Daher führen wir immer explizite Schleifen anstelle von rückruforientiertem Code durch. Ich weiß, es ist ausführlicher, aber es ist notwendig. All of Three..JS ist so und mit Absicht.

das ist ein gerechter Punkt. Persönlich bin ich der Philosophie, dass Leistung und Lesbarkeit auf einer Skala liegen sollten und nicht das eine oder das andere, aber Konsistenz ist gut. Mein Hauptproblem bei diesem speziellen Beispiel ist, dass es keine übliche Methode zum Durchlaufen eines Arrays ist. Hier ist ein idiomatischer Weg:

for(var i=0, count=array.length; i<count; i++){
    var element = array[i];
    ...
}

Oder nehmen wir an, Sie haben einen Code mit einer Länge von 50 Zeilen des Formulars:

function complex(a){
  if(a){
      //do a ton of stuff
      ...
      return result;
  }
}

das ist nicht so lesbar wie:

function complex(a){
  if(!a){
      //omg! not A?!11 
      return;
  }
  //do a ton of stuff
  ...
  return result;
}

@Usnul könnten Sie helfen, den Code

@usnul Wenn Ihnen das nicht gefällt, können Sie dies umgestalten? Es spielt keine Rolle, ob es so aussieht oder nicht, es ist nur wichtig, dass es darauf aufgebaut wird, ist mein Verständnis.
Ich weiß jedoch nicht, ob Refraktoren passieren sollten, während dies in Beispielen ist (oder möglicherweise in einem anderen Repo) oder sofort in src verschoben werden sollte, wie @bhouston vorschlägt.

@IARI

Ich kenne mich mit glsl wirklich nicht so gut aus und finde es auch - verzeihen Sie meine Formulierung - eine super Nervensäge , Shader-Code zu lesen und zu schreiben .

aber nach dem, was ich weiß , wären Knoten der beste Weg, dies auf wirklich elegante und erweiterbare Weise zu tun.

Ich kann auch nicht behaupten, dass ich GLSL sehr gut kenne, aber ich kenne es genug, um meine Probleme zu lösen. Soweit ich weiß, stimme ich größtenteils dem zu, was @AndrewRayCode zuvor geschrieben hat. Ich finde die Knotensache im Vergleich zu GLSL ausführlich.

Wenn Sie GLSL nicht kennen, wäre es sehr schwer, es mit etwas anderem zu vergleichen. Wie Sie es selbst geschrieben haben, wenn wir judge on what you know , und Sie es selbst gesagt haben, you don't know glsl denke ich, dass Ihr Beitrag mit einem Haftungsausschluss aufgenommen werden sollte :)

Es ist, als ob ich sagte:

Japan ist der schlimmste Ort auf diesem Planeten... aber ich war noch nie in Japan."

Dankeschön.

Methodennamen sind undeutlich oder geradezu irreführend. (zB was denkst du macht die Methode "build"? - rate mal)

Wow, ich wusste gar nicht, dass darunter ein ShaderMaterial . Ich vermute, dass dies alles macht, was THREE.WebGLRenderer mit Shader-Vorlagen macht.

Ich kenne mich mit glsl wirklich nicht so gut aus und finde es auch - verzeihen Sie meine Formulierung - eine super Nervensäge, Shader-Code zu lesen und zu schreiben.
aber nach meinem Wissen wären Knoten der beste Weg, dies auf wirklich elegante und erweiterbare Weise zu tun.

@pailhead Was er meint, ist, dass es Zwischenstufen zwischen den Dingen gibt.

Ich verstehe nicht, warum dieser Alarm. @mrdoob wird niemals etwas anderes als eine großartige Lösung zusammenführen. Alle großartigen PR, Verbesserungen von jedem in NodeMaterial oder nicht, sind für die Community sehr nützlich. Wenn dies immer noch keine Fusion im Kern war, dann deshalb, weil wir uns mit mehr Arbeit verbessern müssen.

@sunag Gibt es etwas, was andere tun können, um Ihnen bei diesem Projekt zu helfen? Ich wäre bereit, eine Dokumentation zu schreiben, wenn Sie bereit für Dokumente sind und sie überprüfen könnten.

@sunag Gibt es etwas, was andere tun können, um Ihnen bei diesem Projekt zu helfen? Ich wäre bereit, eine Dokumentation zu schreiben, wenn Sie bereit für Dokumente sind und sie überprüfen könnten.

Das wird großartig. Kein Zweifel, hilft sehr.

Das knotenbasierte Materialsystem sieht fantastisch aus, es würde die Ausdruckskraft erweitern.

Wie werden wir im Kern vom bestehenden Materialsystem zu einem knotenbasierten Materialsystem wechseln? Werden wir beide zwei Systeme oder das vorhandene durch das Knoten-System ersetzen?

Entschuldigung, vielleicht glaube ich nicht, dass ich diesen Thread aufhole, weil dieser Thread zu groß ist...

Werden wir beide zwei Systeme oder das vorhandene durch das Knoten-System ersetzen?

Ich sehe Ersatz als das ultimative Ziel, ist sowohl für die Leistung als auch für die Wartung besser. Der nächste Schritt besteht darin, ein MeshStandardNodeMaterial und andere Knotenmaterialien im Kern auszuführen, die in visueller, Syntax und Leistung genau wie der Kern ausgeführt werden.

Ich muss shadowMap in meinem Projekt anzeigen.

Ich habe eine Szene mit gerichtetem Licht und 2-Geometrie, die MeshStandardNodeMaterial verwendet.

Ich habe eingeschaltet
castShadow = wahr für Licht
castShadow und receiveShadow für beide Objekte.
shadowEnabled = true für Renderer

Warum funktioniert es nicht?
Muss ich die shadow-Eigenschaft des MeshStandardNodeMaterial verwenden? Ist dies der Zweck?

Kann mir jemand helfen?
Vielen Dank!

@claudioviola
Support-Fragen gehen zum Forum von stackoverflow.

@sunag Glauben Sie, dass NodeMaterial stabil genug ist, damit wir mit der Bereitstellung von TypeScript-Deklarationsdateien beginnen können? Wenn Sie in naher Zukunft keine größeren API-Änderungen planen, würde ich mit dieser Aufgabe beginnen, da NodeMaterial die letzte Gruppe von Modulen ohne TS-Unterstützung ist.

@sunag Glauben Sie, dass NodeMaterial stabil genug ist, damit wir mit der Bereitstellung von TypeScript-Deklarationsdateien beginnen können? Wenn Sie in naher Zukunft keine größeren API-Änderungen planen, würde ich mit dieser Aufgabe beginnen, da NodeMaterial die letzte Gruppe von Modulen ohne TS-Unterstützung ist.

@ Mugen87 Ja, es muss mehr Ergänzungen als Änderungen geben. Hinzufügen von TS-Unterstützung wird großartig sein. 👍

Okay, der TS-Support ist mit der nächsten Version bereit R017 🙌

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen