Skip to content

Commit

Permalink
NodeMaterial: updates (#23600)
Browse files Browse the repository at this point in the history
* cleanup vec3 conversion

* fix PreviewEditor using WebGL in WebGPU

* uses .lightNode only in MeshStandardNodeMaterial

* cleanup

* use class declaration based

* cleanup

* share texture uniform when sampling texture multiple times
  • Loading branch information
sunag authored Feb 26, 2022
1 parent 30f34a3 commit 62c6fab
Show file tree
Hide file tree
Showing 11 changed files with 152 additions and 112 deletions.
200 changes: 100 additions & 100 deletions examples/jsm/nodes/ShaderNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const NodeHandler = {

const inputs = params.shift();

return NodeClosure( ShaderNodeObjects( inputs ), ...params );
return NodeClosure( new ShaderNodeObjects( inputs ), ...params );

},

Expand All @@ -52,13 +52,13 @@ const NodeHandler = {
.replace( /b|p/g, 'z' )
.replace( /a|q/g, 'w' );

return ShaderNodeObject( new SplitNode( node, prop ) );
return new ShaderNodeObject( new SplitNode( node, prop ) );

} else if ( /^\d+$/.test( prop ) === true ) {

// accessing array

return ShaderNodeObject( new ArrayElementNode( node, new FloatNode( Number( prop ) ).setConst( true ) ) );
return new ShaderNodeObject( new ArrayElementNode( node, new FloatNode( Number( prop ) ).setConst( true ) ) );

}

Expand All @@ -72,13 +72,13 @@ const NodeHandler = {

const nodeObjects = new WeakMap();

const ShaderNodeObject = ( obj ) => {
const ShaderNodeObject = function( obj ) {

const type = typeof obj;

if ( type === 'number' ) {

return ShaderNodeObject( new FloatNode( obj ).setConst( true ) );
return new ShaderNodeObject( new FloatNode( obj ).setConst( true ) );

} else if ( type === 'object' ) {

Expand All @@ -103,57 +103,57 @@ const ShaderNodeObject = ( obj ) => {

};

const ShaderNodeObjects = ( objects ) => {
const ShaderNodeObjects = function( objects ) {

for ( const name in objects ) {

objects[ name ] = ShaderNodeObject( objects[ name ] );
objects[ name ] = new ShaderNodeObject( objects[ name ] );

}

return objects;

};

const ShaderNodeArray = ( array ) => {
const ShaderNodeArray = function( array ) {

const len = array.length;

for ( let i = 0; i < len; i ++ ) {

array[ i ] = ShaderNodeObject( array[ i ] );
array[ i ] = new ShaderNodeObject( array[ i ] );

}

return array;

};

const ShaderNodeProxy = ( NodeClass, scope = null, factor = null ) => {
const ShaderNodeProxy = function( NodeClass, scope = null, factor = null ) {

if ( scope === null ) {

return ( ...params ) => {

return ShaderNodeObject( new NodeClass( ...ShaderNodeArray( params ) ) );
return new ShaderNodeObject( new NodeClass( ...ShaderNodeArray( params ) ) );

};

} else if ( factor === null ) {

return ( ...params ) => {

return ShaderNodeObject( new NodeClass( scope, ...ShaderNodeArray( params ) ) );
return new ShaderNodeObject( new NodeClass( scope, ...ShaderNodeArray( params ) ) );

};

} else {

factor = ShaderNodeObject( factor );
factor = new ShaderNodeObject( factor );

return ( ...params ) => {

return ShaderNodeObject( new NodeClass( scope, ...ShaderNodeArray( params ), factor ) );
return new ShaderNodeObject( new NodeClass( scope, ...ShaderNodeArray( params ), factor ) );

};

Expand All @@ -165,9 +165,9 @@ const ShaderNodeScript = function ( jsFunc ) {

return ( inputs, builder ) => {

ShaderNodeObjects( inputs );
new ShaderNodeObjects( inputs );

return ShaderNodeObject( jsFunc( inputs, builder ) );
return new ShaderNodeObject( jsFunc( inputs, builder ) );

};

Expand All @@ -189,7 +189,7 @@ export const uniform = new ShaderNode( ( inputNode ) => {

export const nodeObject = ( val ) => {

return ShaderNodeObject( val );
return new ShaderNodeObject( val );

};

Expand Down Expand Up @@ -315,38 +315,38 @@ export const addTo = ( varNode, ...params ) => {

};

export const add = ShaderNodeProxy( OperatorNode, '+' );
export const sub = ShaderNodeProxy( OperatorNode, '-' );
export const mul = ShaderNodeProxy( OperatorNode, '*' );
export const div = ShaderNodeProxy( OperatorNode, '/' );
export const remainder = ShaderNodeProxy( OperatorNode, '%' );
export const equal = ShaderNodeProxy( OperatorNode, '==' );
export const assign = ShaderNodeProxy( OperatorNode, '=' );
export const lessThan = ShaderNodeProxy( OperatorNode, '<' );
export const greaterThan = ShaderNodeProxy( OperatorNode, '>' );
export const lessThanEqual = ShaderNodeProxy( OperatorNode, '<=' );
export const greaterThanEqual = ShaderNodeProxy( OperatorNode, '>=' );
export const and = ShaderNodeProxy( OperatorNode, '&&' );
export const or = ShaderNodeProxy( OperatorNode, '||' );
export const xor = ShaderNodeProxy( OperatorNode, '^^' );
export const bitAnd = ShaderNodeProxy( OperatorNode, '&' );
export const bitOr = ShaderNodeProxy( OperatorNode, '|' );
export const bitXor = ShaderNodeProxy( OperatorNode, '^' );
export const shiftLeft = ShaderNodeProxy( OperatorNode, '<<' );
export const shiftRight = ShaderNodeProxy( OperatorNode, '>>' );

export const element = ShaderNodeProxy( ArrayElementNode );

export const normalGeometry = ShaderNodeObject( new NormalNode( NormalNode.GEOMETRY ) );
export const normalLocal = ShaderNodeObject( new NormalNode( NormalNode.LOCAL ) );
export const normalWorld = ShaderNodeObject( new NormalNode( NormalNode.WORLD ) );
export const normalView = ShaderNodeObject( new NormalNode( NormalNode.VIEW ) );
export const transformedNormalView = ShaderNodeObject( new VarNode( new NormalNode( NormalNode.VIEW ), 'TransformedNormalView', 'vec3' ) );

export const positionLocal = ShaderNodeObject( new PositionNode( PositionNode.LOCAL ) );
export const positionWorld = ShaderNodeObject( new PositionNode( PositionNode.WORLD ) );
export const positionView = ShaderNodeObject( new PositionNode( PositionNode.VIEW ) );
export const positionViewDirection = ShaderNodeObject( new PositionNode( PositionNode.VIEW_DIRECTION ) );
export const add = new ShaderNodeProxy( OperatorNode, '+' );
export const sub = new ShaderNodeProxy( OperatorNode, '-' );
export const mul = new ShaderNodeProxy( OperatorNode, '*' );
export const div = new ShaderNodeProxy( OperatorNode, '/' );
export const remainder = new ShaderNodeProxy( OperatorNode, '%' );
export const equal = new ShaderNodeProxy( OperatorNode, '==' );
export const assign = new ShaderNodeProxy( OperatorNode, '=' );
export const lessThan = new ShaderNodeProxy( OperatorNode, '<' );
export const greaterThan = new ShaderNodeProxy( OperatorNode, '>' );
export const lessThanEqual = new ShaderNodeProxy( OperatorNode, '<=' );
export const greaterThanEqual = new ShaderNodeProxy( OperatorNode, '>=' );
export const and = new ShaderNodeProxy( OperatorNode, '&&' );
export const or = new ShaderNodeProxy( OperatorNode, '||' );
export const xor = new ShaderNodeProxy( OperatorNode, '^^' );
export const bitAnd = new ShaderNodeProxy( OperatorNode, '&' );
export const bitOr = new ShaderNodeProxy( OperatorNode, '|' );
export const bitXor = new ShaderNodeProxy( OperatorNode, '^' );
export const shiftLeft = new ShaderNodeProxy( OperatorNode, '<<' );
export const shiftRight = new ShaderNodeProxy( OperatorNode, '>>' );

export const element = new ShaderNodeProxy( ArrayElementNode );

export const normalGeometry = new ShaderNodeObject( new NormalNode( NormalNode.GEOMETRY ) );
export const normalLocal = new ShaderNodeObject( new NormalNode( NormalNode.LOCAL ) );
export const normalWorld = new ShaderNodeObject( new NormalNode( NormalNode.WORLD ) );
export const normalView = new ShaderNodeObject( new NormalNode( NormalNode.VIEW ) );
export const transformedNormalView = new ShaderNodeObject( new VarNode( new NormalNode( NormalNode.VIEW ), 'TransformedNormalView', 'vec3' ) );

export const positionLocal = new ShaderNodeObject( new PositionNode( PositionNode.LOCAL ) );
export const positionWorld = new ShaderNodeObject( new PositionNode( PositionNode.WORLD ) );
export const positionView = new ShaderNodeObject( new PositionNode( PositionNode.VIEW ) );
export const positionViewDirection = new ShaderNodeObject( new PositionNode( PositionNode.VIEW_DIRECTION ) );

export const PI = float( 3.141592653589793 );
export const PI2 = float( 6.283185307179586 );
Expand All @@ -355,54 +355,54 @@ export const RECIPROCAL_PI = float( 0.3183098861837907 );
export const RECIPROCAL_PI2 = float( 0.15915494309189535 );
export const EPSILON = float( 1e-6 );

export const diffuseColor = ShaderNodeObject( new PropertyNode( 'DiffuseColor', 'vec4' ) );
export const roughness = ShaderNodeObject( new PropertyNode( 'Roughness', 'float' ) );
export const metalness = ShaderNodeObject( new PropertyNode( 'Metalness', 'float' ) );
export const alphaTest = ShaderNodeObject( new PropertyNode( 'AlphaTest', 'float' ) );
export const specularColor = ShaderNodeObject( new PropertyNode( 'SpecularColor', 'color' ) );

export const abs = ShaderNodeProxy( MathNode, 'abs' );
export const acos = ShaderNodeProxy( MathNode, 'acos' );
export const asin = ShaderNodeProxy( MathNode, 'asin' );
export const atan = ShaderNodeProxy( MathNode, 'atan' );
export const ceil = ShaderNodeProxy( MathNode, 'ceil' );
export const clamp = ShaderNodeProxy( MathNode, 'clamp' );
export const cos = ShaderNodeProxy( MathNode, 'cos' );
export const cross = ShaderNodeProxy( MathNode, 'cross' );
export const degrees = ShaderNodeProxy( MathNode, 'degrees' );
export const dFdx = ShaderNodeProxy( MathNode, 'dFdx' );
export const dFdy = ShaderNodeProxy( MathNode, 'dFdy' );
export const distance = ShaderNodeProxy( MathNode, 'distance' );
export const dot = ShaderNodeProxy( MathNode, 'dot' );
export const exp = ShaderNodeProxy( MathNode, 'exp' );
export const exp2 = ShaderNodeProxy( MathNode, 'exp2' );
export const faceforward = ShaderNodeProxy( MathNode, 'faceforward' );
export const floor = ShaderNodeProxy( MathNode, 'floor' );
export const fract = ShaderNodeProxy( MathNode, 'fract' );
export const invert = ShaderNodeProxy( MathNode, 'invert' );
export const inversesqrt = ShaderNodeProxy( MathNode, 'inversesqrt' );
export const length = ShaderNodeProxy( MathNode, 'length' );
export const log = ShaderNodeProxy( MathNode, 'log' );
export const log2 = ShaderNodeProxy( MathNode, 'log2' );
export const max = ShaderNodeProxy( MathNode, 'max' );
export const min = ShaderNodeProxy( MathNode, 'min' );
export const mix = ShaderNodeProxy( MathNode, 'mix' );
export const mod = ShaderNodeProxy( MathNode, 'mod' );
export const negate = ShaderNodeProxy( MathNode, 'negate' );
export const normalize = ShaderNodeProxy( MathNode, 'normalize' );
export const pow = ShaderNodeProxy( MathNode, 'pow' );
export const pow2 = ShaderNodeProxy( MathNode, 'pow', 2 );
export const pow3 = ShaderNodeProxy( MathNode, 'pow', 3 );
export const pow4 = ShaderNodeProxy( MathNode, 'pow', 4 );
export const radians = ShaderNodeProxy( MathNode, 'radians' );
export const reflect = ShaderNodeProxy( MathNode, 'reflect' );
export const refract = ShaderNodeProxy( MathNode, 'refract' );
export const round = ShaderNodeProxy( MathNode, 'round' );
export const saturate = ShaderNodeProxy( MathNode, 'saturate' );
export const sign = ShaderNodeProxy( MathNode, 'sign' );
export const sin = ShaderNodeProxy( MathNode, 'sin' );
export const smoothstep = ShaderNodeProxy( MathNode, 'smoothstep' );
export const sqrt = ShaderNodeProxy( MathNode, 'sqrt' );
export const step = ShaderNodeProxy( MathNode, 'step' );
export const tan = ShaderNodeProxy( MathNode, 'tan' );
export const transformDirection = ShaderNodeProxy( MathNode, 'transformDirection' );
export const diffuseColor = new ShaderNodeObject( new PropertyNode( 'DiffuseColor', 'vec4' ) );
export const roughness = new ShaderNodeObject( new PropertyNode( 'Roughness', 'float' ) );
export const metalness = new ShaderNodeObject( new PropertyNode( 'Metalness', 'float' ) );
export const alphaTest = new ShaderNodeObject( new PropertyNode( 'AlphaTest', 'float' ) );
export const specularColor = new ShaderNodeObject( new PropertyNode( 'SpecularColor', 'color' ) );

export const abs = new ShaderNodeProxy( MathNode, 'abs' );
export const acos = new ShaderNodeProxy( MathNode, 'acos' );
export const asin = new ShaderNodeProxy( MathNode, 'asin' );
export const atan = new ShaderNodeProxy( MathNode, 'atan' );
export const ceil = new ShaderNodeProxy( MathNode, 'ceil' );
export const clamp = new ShaderNodeProxy( MathNode, 'clamp' );
export const cos = new ShaderNodeProxy( MathNode, 'cos' );
export const cross = new ShaderNodeProxy( MathNode, 'cross' );
export const degrees = new ShaderNodeProxy( MathNode, 'degrees' );
export const dFdx = new ShaderNodeProxy( MathNode, 'dFdx' );
export const dFdy = new ShaderNodeProxy( MathNode, 'dFdy' );
export const distance = new ShaderNodeProxy( MathNode, 'distance' );
export const dot = new ShaderNodeProxy( MathNode, 'dot' );
export const exp = new ShaderNodeProxy( MathNode, 'exp' );
export const exp2 = new ShaderNodeProxy( MathNode, 'exp2' );
export const faceforward = new ShaderNodeProxy( MathNode, 'faceforward' );
export const floor = new ShaderNodeProxy( MathNode, 'floor' );
export const fract = new ShaderNodeProxy( MathNode, 'fract' );
export const invert = new ShaderNodeProxy( MathNode, 'invert' );
export const inversesqrt = new ShaderNodeProxy( MathNode, 'inversesqrt' );
export const length = new ShaderNodeProxy( MathNode, 'length' );
export const log = new ShaderNodeProxy( MathNode, 'log' );
export const log2 = new ShaderNodeProxy( MathNode, 'log2' );
export const max = new ShaderNodeProxy( MathNode, 'max' );
export const min = new ShaderNodeProxy( MathNode, 'min' );
export const mix = new ShaderNodeProxy( MathNode, 'mix' );
export const mod = new ShaderNodeProxy( MathNode, 'mod' );
export const negate = new ShaderNodeProxy( MathNode, 'negate' );
export const normalize = new ShaderNodeProxy( MathNode, 'normalize' );
export const pow = new ShaderNodeProxy( MathNode, 'pow' );
export const pow2 = new ShaderNodeProxy( MathNode, 'pow', 2 );
export const pow3 = new ShaderNodeProxy( MathNode, 'pow', 3 );
export const pow4 = new ShaderNodeProxy( MathNode, 'pow', 4 );
export const radians = new ShaderNodeProxy( MathNode, 'radians' );
export const reflect = new ShaderNodeProxy( MathNode, 'reflect' );
export const refract = new ShaderNodeProxy( MathNode, 'refract' );
export const round = new ShaderNodeProxy( MathNode, 'round' );
export const saturate = new ShaderNodeProxy( MathNode, 'saturate' );
export const sign = new ShaderNodeProxy( MathNode, 'sign' );
export const sin = new ShaderNodeProxy( MathNode, 'sin' );
export const smoothstep = new ShaderNodeProxy( MathNode, 'smoothstep' );
export const sqrt = new ShaderNodeProxy( MathNode, 'sqrt' );
export const step = new ShaderNodeProxy( MathNode, 'step' );
export const tan = new ShaderNodeProxy( MathNode, 'tan' );
export const transformDirection = new ShaderNodeProxy( MathNode, 'transformDirection' );
22 changes: 20 additions & 2 deletions examples/jsm/nodes/core/InputNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ class InputNode extends Node {

}

getInputHash( builder ) {

return this.getHash( builder );

}

generateConst( builder ) {

return builder.getConst( this.getNodeType( builder ), this.value );
Expand All @@ -48,9 +54,21 @@ class InputNode extends Node {

} else {

const inputType = this.getInputType( builder );
const inputHash = this.getInputHash( builder );

let sharedNode = builder.getNodeFromHash( inputHash );

if ( sharedNode === undefined ) {

builder.setHashNode( this, inputHash );

sharedNode = this;

}

const inputType = sharedNode.getInputType( builder );

const nodeUniform = builder.getUniformFromNode( this, builder.shaderStage, inputType );
const nodeUniform = builder.getUniformFromNode( sharedNode, builder.shaderStage, inputType );
const propertyName = builder.getPropertyName( nodeUniform );

return builder.format( propertyName, type, output );
Expand Down
8 changes: 7 additions & 1 deletion examples/jsm/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ class NodeBuilder {

}

setHashNode( node, hash ) {

this.hashNodes[ hash ] = node;

}

addNode( node ) {

if ( this.nodes.indexOf( node ) === - 1 ) {
Expand All @@ -90,7 +96,7 @@ class NodeBuilder {

this.nodes.push( node );

this.hashNodes[ node.getHash( this ) ] = node;
this.setHashNode( node, node.getHash( this ) );

}

Expand Down
6 changes: 6 additions & 0 deletions examples/jsm/nodes/inputs/TextureNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ class TextureNode extends InputNode {

}

getInputHash( /*builder*/ ) {

return this.value.uuid;

}

generate( builder, output ) {

const texture = this.value;
Expand Down
2 changes: 1 addition & 1 deletion examples/jsm/nodes/materials/LineBasicNodeMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ class LineBasicNodeMaterial extends NodeMaterial {

}

LineBasicNodeMaterial.prototype.isNodeMaterial = true;
LineBasicNodeMaterial.prototype.isLineBasicNodeMaterial = true;

export default LineBasicNodeMaterial;
Loading

0 comments on commit 62c6fab

Please sign in to comment.