Skip to content

Commit

Permalink
NodeMaterial: serialize/deserialize and Material.fromType() (#23314)
Browse files Browse the repository at this point in the history
* Node serializer (draft)

* add Material.fromType()

* NodeObjectLoader: serialize/deserialize

* update default values

* fix analytic light

* force refresh material uniforms using .uniformsNeedUpdate

* Revert "force refresh material uniforms using .uniformsNeedUpdate"

This reverts commit b083fb4.

* mrdoob code style

* cleanup

* cleanup (2)

* Update NodeMaterial.js

Co-authored-by: mrdoob <info@mrdoob.com>
  • Loading branch information
sunag and mrdoob committed Feb 6, 2022
1 parent f6ce66a commit 9898592
Show file tree
Hide file tree
Showing 34 changed files with 1,033 additions and 39 deletions.
104 changes: 102 additions & 2 deletions examples/jsm/renderers/nodes/Nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ import SpriteSheetUVNode from './utils/SpriteSheetUVNode.js';
import OscNode from './utils/OscNode.js';
import TimerNode from './utils/TimerNode.js';

// loaders
import NodeLoader from './loaders/NodeLoader.js';
import NodeObjectLoader from './loaders/NodeObjectLoader.js';
import NodeMaterialLoader from './loaders/NodeMaterialLoader.js';

// procedural
import CheckerNode from './procedural/CheckerNode.js';

Expand All @@ -86,7 +91,7 @@ export * from './materials/Materials.js';
// shader node
export * from './ShaderNode.js';

export {
const nodeLib = {
// core
ArrayInputNode,
AttributeNode,
Expand Down Expand Up @@ -161,6 +166,101 @@ export {
TimerNode,

// procedural
CheckerNode
CheckerNode,

// loaders
NodeLoader,
NodeObjectLoader,
NodeMaterialLoader

};

export const fromType = ( type ) => {

return new nodeLib[ type ]();

};

export {
// core
ArrayInputNode,
AttributeNode,
BypassNode,
CodeNode,
ContextNode,
ExpressionNode,
FunctionCallNode,
FunctionNode,
InputNode,
Node,
NodeAttribute,
NodeBuilder,
NodeCode,
NodeFrame,
NodeFunctionInput,
NodeKeywords,
NodeUniform,
NodeVar,
NodeVary,
PropertyNode,
TempNode,
VarNode,
VaryNode,

// accessors
CameraNode,
MaterialNode,
MaterialReferenceNode,
ModelNode,
ModelViewProjectionNode,
NormalNode,
Object3DNode,
PointUVNode,
PositionNode,
ReferenceNode,
SkinningNode,
UVNode,

// inputs
ColorNode,
FloatNode,
IntNode,
Matrix3Node,
Matrix4Node,
TextureNode,
Vector2Node,
Vector3Node,
Vector4Node,

// display
ColorSpaceNode,
NormalMapNode,

// math
MathNode,
OperatorNode,
CondNode,

// lights
LightContextNode,
LightNode,
LightsNode,

// utils
ArrayElementNode,
ConvertNode,
JoinNode,
SplitNode,
SpriteSheetUVNode,
OscNode,
TimerNode,

// procedural
CheckerNode,

// loaders
NodeLoader,
NodeObjectLoader,
NodeMaterialLoader

};
16 changes: 16 additions & 0 deletions examples/jsm/renderers/nodes/accessors/NormalNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,22 @@ class NormalNode extends Node {

}

serialize( data ) {

super.serialize( data );

data.scope = this.scope;

}

deserialize( data ) {

super.deserialize( data );

this.scope = data.scope;

}

}

export default NormalNode;
16 changes: 16 additions & 0 deletions examples/jsm/renderers/nodes/accessors/Object3DNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ class Object3DNode extends Node {

}

serialize( data ) {

super.serialize( data );

data.scope = this.scope;

}

deserialize( data ) {

super.deserialize( data );

this.scope = data.scope;

}

}

export default Object3DNode;
16 changes: 16 additions & 0 deletions examples/jsm/renderers/nodes/accessors/PositionNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,22 @@ class PositionNode extends Node {

}

serialize( data ) {

super.serialize( data );

data.scope = this.scope;

}

deserialize( data ) {

super.deserialize( data );

this.scope = data.scope;

}

}

export default PositionNode;
16 changes: 16 additions & 0 deletions examples/jsm/renderers/nodes/accessors/UVNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,22 @@ class UVNode extends AttributeNode {

}

serialize( data ) {

super.serialize( data );

data.index = this.index;

}

deserialize( data ) {

super.deserialize( data );

this.index = data.index;

}

}

UVNode.prototype.isUVNode = true;
Expand Down
114 changes: 113 additions & 1 deletion examples/jsm/renderers/nodes/core/Node.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NodeUpdateType } from './constants.js';

import { getNodesKeys } from './NodeUtils.js';
import { MathUtils } from 'three';

class Node {
Expand Down Expand Up @@ -97,6 +97,118 @@ class Node {

}

serialize( json ) {

const nodeKeys = getNodesKeys( this );

if ( nodeKeys.length > 0 ) {

const inputNodes = {};

for ( const property of nodeKeys ) {

inputNodes[ property ] = this[ property ].toJSON( json.meta ).uuid;

}

json.inputNodes = inputNodes;

}

}

deserialize( json ) {

if ( json.inputNodes !== undefined ) {

const nodes = json.meta.nodes;

for ( const property in json.inputNodes ) {

const uuid = json.inputNodes[ property ];

this[ property ] = nodes[ uuid ];

}

}

}

toJSON( meta ) {

const { uuid, type } = this;
const isRoot = ( meta === undefined || typeof meta === 'string' );

if ( isRoot ) {

meta = {
textures: {},
images: {},
nodes: {}
};

}

// serialize

let data = meta.nodes[ uuid ];

if ( data === undefined ) {

data = {
uuid,
type,
meta,
metadata: {
version: 4.5,
type: 'Node',
generator: 'Node.toJSON'
}
};

meta.nodes[ data.uuid ] = data;

this.serialize( data );

delete data.meta;

}

// TODO: Copied from Object3D.toJSON

function extractFromCache( cache ) {

const values = [];

for ( const key in cache ) {

const data = cache[ key ];
delete data.metadata;
values.push( data );

}

return values;

}

if ( isRoot ) {

const textures = extractFromCache( meta.textures );
const images = extractFromCache( meta.images );
const nodes = extractFromCache( meta.nodes );

if ( textures.length > 0 ) data.textures = textures;
if ( images.length > 0 ) data.images = images;
if ( nodes.length > 0 ) data.nodes = nodes;

}

return data;

}

}

Node.prototype.isNode = true;
Expand Down
19 changes: 19 additions & 0 deletions examples/jsm/renderers/nodes/core/NodeUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const getNodesKeys = ( object ) => {

const props = [];

for ( const name in object ) {

const value = object[ name ];

if ( value && value.isNode === true ) {

props.push( name );

}

}

return props;

};
25 changes: 25 additions & 0 deletions examples/jsm/renderers/nodes/inputs/ColorNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,31 @@ class ColorNode extends InputNode {

}

serialize( data ) {

super.serialize( data );

const { r, g, b } = this.value;

data.r = r;
data.g = g;
data.b = b;

}

deserialize( data ) {

super.serialize( data );

const { r, g, b } = data;
const value = this.value;

value.r = r;
value.g = g;
value.b = b;

}

}

ColorNode.prototype.isColorNode = true;
Expand Down
Loading

0 comments on commit 9898592

Please sign in to comment.